Subject: bug#11474: Patch for Emacsclient --eval bug

From: Scott Turner <[email-masked]>
Date: Fri, 13 Dec 2013 10:30:17 -0500

In emacsclient, the --eval option tells emacsclient to treat all arguments
as Elisp to be evaluated by the Emacs server.

The --alternate-editor option specifies an program to start if emacsclient
cannot find an Emacs server.

If both options are used and a server is not found, a bug arises.
Emacsclient sends the arguments that are intended to be interpreted as
Elisp to the alternate editor.  If the alternate editor is Emacs, this
results in Emacs creating a buffer named after each argument.  So the
command:

emacsclient --alternate-editor "emacs" --eval "(make-frame-visible)"

results in an Emacs with a buffer named "(make-frame-visible)".

Sending the Elisp arguments to the alternate-editor as plain arguments is
clearly wrong.  If we knew that the alternate-editor was Emacs, we could
send the argument along with "--eval=" prepended to have the newly started
Emacs evaluate the Elisp, but of course the alternate editor could be
something else entirely, and it's probably not the case that you'd want to
execute the same Elisp on startup as on resume.

The patch provided below simply discards the Elisp arguments when
emacsclient falls through to the alternate editor.  There may be better
fixes, but this does the least harm while retaining compatibility.

*** emacsclient.c    Tue Jan  1 15:37:17 2013
--- emacsclient-strip-eval.c    Thu Dec 12 20:01:06 2013
***************
*** 694,700 ****
      {
        int i = optind - 1;

!       execvp (alternate_editor, main_argv + i);
        message (TRUE, "%s: error executing alternate editor \"%s\"\n",
             progname, alternate_editor);
      }
--- 694,713 ----
      {
        int i = optind - 1;

!       /*
!        *  If the --eval option has been used, then the remaining
!        *  arguments are Elisp expressions intended to be evaluated
!        *  by emacsclient.  It doesn't make any sense to pass them
!        *  along to the alternate_editor to be treated as files.
!        *
!        */
!       if (eval) {
!     char *t_argv[] = {alternate_editor, 0 };
!     execvp (alternate_editor, t_argv);
!       } else {
!     execvp (alternate_editor, main_argv + i);
!       };
!
        message (TRUE, "%s: error executing alternate editor \"%s\"\n",
             progname, alternate_editor);
      }