Subject: Problem using `etc/emacs.bash' with EmacsW32

From: Anonymous Sender <[email-masked]>
Date: Thu, 4 Sep 2008 19:55:05 +0000 (UTC)

In GNU Emacs 22.2.1 (i386-mingw-nt5.1.2600)
 of 2008-03-26 on RELEASE
Windowing system distributor `Microsoft Corp.', version 5.1.2600
configured using `configure --with-gcc (3.4)'

I am attempting to use the shell script `emacs.bash' that is provided
in the `etc' directory of the GNU Emacs distribution.  This script
defines the shell function named 'edit' to provide a single,
consistent command for starting Emacs and subsequently, for calling
Emacs via `emacsclient', if `server-start' has been invoked via either
the initialization file or M-x server-start.

After sourcing the script, the command 'edit [filename]' starts Emacs
as expected.  However, subsequent calls to `edit' do not result in
`emacsclient' being invoked.  Instead, new instances of `emacs' are
started.  The reason for this is that the script contains the
following test, which fails for EmacsW32:

  if [ -e "${HOME}/.emacs_server" -o -e "/tmp/emacs${UID}/server" ]; then

Neither of these files is created by EmacsW32.  Instead, the file
${HOME}/.emacs.d/server/server is created, by default, when
`server-start' is invoked from EmacsW32.  I would like to suggest that
`etc/emacs.bash' be changed to include that server file in its test
for starting `emacsclient', that is, change the test, above, to:

  if [ -e "${HOME}/.emacs.d/server/server" -o -e "${HOME}/.emacs_server" -o -e "/tmp/emacs${UID}/server" ]; then

With this change, the shell function `edit' then appropriately calls
`emacsclient' after Emacs has started its server.

A second problem occurs after Emacs has been stopped ("killed").  The
next time `edit' is called, the code in `etc/emacs.bash' calls
`emacsclient' even though Emacs and its server are not running.  The
reason for this appears to be that the function `server-start' in
`lisp/server.el' does not remove ${HOME}/.emacs.d/server/server when
it is called when Emacs is killed via C-x C-c (that is,
`save-buffers-kill-emacs').

Here is the sequence of calls:

- When `(server-start)' is invoked, the following code in
  `lisp/server.el' adds an anonymous function to `kill-emacs-hook':

  (add-hook 'kill-emacs-hook (lambda () (server-mode -1))) ;Cleanup upon exit.

- When emacs is exited via C-x C-c, the function
  `save-buffers-kill-emacs' is called.

- The function `save-buffers-kill-emacs' calls the function
  `kill-emacs', which, in turn, calls the list of functions in
  `kill-emacs-hook'.

- `server-mode' includes the form:

   (server-start (not server-mode))

- When the function `server-start' is called with its optional
  parameter `leave-dead' set to nil, the code in the following the
  condition in the form:

   (unless leave-dead ...)

  is not executed.  This includes the code to remove the server file
  that was created when `server-start' was originally called, namely,

  (let* ((server-dir (if server-use-tcp server-auth-dir server-socket-dir))
         (server-file (expand-file-name server-name server-dir)))
    ;; Make sure there is a safe directory in which to place the socket.
    (server-ensure-safe-dir server-dir)
    ;; Remove any leftover socket or authentication file
    (ignore-errors (delete-file server-file))
    ...)) ; `let' and `unless'

A possible solution to this problem is to move the `(unless
leave-dead)' form inside the `(let* ...)' form after the form:

    (ignore-errors (delete-file server-file))

I have made this change in my copy of `lisp/server.el' and confirmed
that `edit' works correctly for EmacsW32, that is, it starts `emacs'
if there is no instance of `emacs' running, and starts `emacsclient'
if emacs's server is running.

; End of report