views:

56

answers:

2

So I got tired of waiting for Emacs to load every time anew, and consulting Emacs Wiki, I wrote me an invocation script such as:

#!/bin/bash
# @file: /usr/local/bin/emacs
# @version: 1

server=/tmp/emacs${UID}/server
if [ ! -S ${server} ] ; then
    /opt/emacs/bin/emacs --daemon
    until [ -S ${server} ] ; do
        sleep 1s
    done
fi

/opt/emacs/bin/emacsclient -c "$@"

Immediately, however it failed due to a stale socket (for unrelated reasons my emacs --daemon was killed unexpectedly): So I wrote:

#!/bin/bash
# @file: /usr/local/bin/emacs
# @version: 2

server=/tmp/emacs${UID}/server

if ! /sbin/fuser ${server} 2> /dev/null ; then
    /sbin/funser -k ${server}
    rm -f ${server}
fi

if [ ! -S ${server} ] ; then
    /opt/emacs/bin/emacs --daemon
    until [ -S ${server} ] ; do
        sleep 1s
    done
fi

/opt/emacs/bin/emacsclient -c "$@"

This worked, but working with ClearCase views I noticed a wrinkle:

In a Unix the ClearCase command:

cleartool setview myview-myuser

creates a sub shell, that has a modified file system hierarchy: several new mounts under /vobs/ that are using mvfs, and visible only to that shell.

For each such new shell, the command /sbin/fuser ${server} returns 1 (error), the first time my Emacs invocation script runs. Thus:

  • For version 1: There is only one daemon, but the Emacs clients are unable to see the mvfs mounts under /vobs/.
  • For version 2: There are several daemons all using the same ${server} socket.

Thus, my questions are: Is it OK to use version 2? If yes, how can it work if all of the daemons apparently are using the same ${server} socket? If no, what should I do to fix this?


Progress:

So I got an answer (see answers below) to part of the question, and now I am stuck with the how to fix it? part:

I am looking into putting the ${server} under /vobs/ and thus let ClearCase itself solve my problem. I only need to figure out if and how Emacs can let me do that:

According to my /opt/emacs/share/emacs/23.2/lisp/server.el the server-socket-dir is rooted at the value of the environment variable ${TMPDIR}, so I tried:

#!/bin/bash
# @file: /usr/local/bin/emacs
# @version: 3

[ "${CCVIEW}" ] && TMPDIR="/vbos/misc/tmp" || TMPDIR="/tmp"
export TMPDIR

function is_server_up() {
    local server=${TMPDIR}/emacs${UID}/server
    [ -e ${mysock} ] && /sbin/fuser ${server}
}

if ! is_server_up ; then
    /opt/emacs/bin/emacs --daemon
    until is_server_up ; do
        sleep 1s
        echo "DEBUG: sleeping"
    done
fi

/opt/emacs/bin/emacsclient -c "$@"

But when running form a ClearCase view, I see:

Loading ~/.emacs.d/this-module.el (source)...
Loading ~/.emacs.d/this-module.el (source)...done
Loading ~/.emacs.d/that-module.el (source)...
Loading ~/.emacs.d/that-module.el (source)...done
... snip ...
Starting Emacs daemon.
ESC [ A
 ESC
 ESC [
 ESC [ a
M-[ A is undefined

... and it never exits.

I also tried to patch server.el and use a different environment variable, but to no avail.

A: 

OK, part of the mystery is solved:

Version 2 should not be used. It seems to work because:

  1. /sbin/fuser -k ${server} does not actually kill the server process. Perhaps /sbin/fuser -k -SIGKILL ${server} will, but I haven't tried that. It also can be due to ClearCase's view magic (used by manipulation at the kernel level).
  2. rm -f ${server} unlinks the file, but don't release the socket because it is still used by running processes.

Thus the last view to run the invocation script for the first time will be the owner of the ${server} socket file, and subsequent invocations of Emacs will use that socket, and will see the version files of that view.

Just imagine the hours of fun debugging this...


As for the how to fix it? part, I will take the cowardly way out, and just revert to stand alone Emacs in ClearCase views:

#!/bin/bash
# @file: /usr/local/bin/emacs
# @version: 4

if [ "${CCVIEW}" ] ; then
    /opt/emacs/bin/emacs $@
    exit $?
fi

function is_server_up() {
    local server=/tmp/emacs${UID}/server
    [ -e ${mysock} ] && /sbin/fuser ${server}
}

if ! is_server_up ; then
    /opt/emacs/bin/emacs --daemon
    until is_server_up ; do
        sleep 1s
    done
fi

/opt/emacs/bin/emacsclient -c "$@"
Chen Levy
+2  A: 

Just a note, really, but I would avoid using setview.

  • As you have noted, it creates a shell (with all its issues in term of communication with daemons)
  • Its is only for one view at a time. You always need to do a cleartool pwv to make sure in which view you are currently working when using the /vobs path.

I prefer using the full path of a dynamic view:

/view/myView/vobs/...

That way, no spawn shell, no disambiguation, no trouble.

VonC
I second the motion to use the full path, I used this very successfully for years. Even built up some helper scripts to switch between views easily...
Trey Jackson