From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Matthew Leach Newsgroups: gmane.emacs.devel Subject: [PATCH] Fix `server-name' and `server-socket-dir' for bug#24218 Date: Fri, 29 Dec 2017 21:37:05 +0000 Message-ID: <20171229213705.20263-1-matthew@mattleach.net> NNTP-Posting-Host: blaine.gmane.org X-Trace: blaine.gmane.org 1514583376 6476 195.159.176.226 (29 Dec 2017 21:36:16 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 29 Dec 2017 21:36:16 +0000 (UTC) Cc: Matthew Leach To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Dec 29 22:36:12 2017 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eV2K1-0001FS-Hh for ged-emacs-devel@m.gmane.org; Fri, 29 Dec 2017 22:36:09 +0100 Original-Received: from localhost ([::1]:55772 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eV2M0-0000hd-AK for ged-emacs-devel@m.gmane.org; Fri, 29 Dec 2017 16:38:12 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:58508) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eV2LK-0000hC-9D for emacs-devel@gnu.org; Fri, 29 Dec 2017 16:37:31 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eV2LG-00006m-Pi for emacs-devel@gnu.org; Fri, 29 Dec 2017 16:37:30 -0500 Original-Received: from mx0.mattleach.net ([176.58.118.143]:59998) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eV2LG-0008RB-GK for emacs-devel@gnu.org; Fri, 29 Dec 2017 16:37:26 -0500 Original-Received: by mx0.mattleach.net (Postfix, from userid 99) id 9155A6270B; Fri, 29 Dec 2017 21:37:19 +0000 (GMT) Original-Received: from sebastian.b4rn.org.uk (unknown [148.252.22.43]) by mx0.mattleach.net (Postfix) with ESMTPSA id 91C0F626AE; Fri, 29 Dec 2017 21:37:18 +0000 (GMT) X-Mailer: git-send-email 2.14.3 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 176.58.118.143 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:221462 Archived-At: * lisp/server.el: (server-external-socket-initialised): New (server-name): Compute server name from `get-external-sockname'. (server-socket-dir): Compute socket dir from `get-external-sockname'. (server-start): Don't check for existing server when an uninitialised external socket has been passed to Emacs. * src/emacs.c: (main): Obtain socket name via getsockname and pass to `init_process_emacs'. * src/lisp.h: (init_process_emacs): Add second parameter. * src/proess.c: (external_sock_name): New. (get-external-sockname): New. (init_process_emacs): Set `external_sock_name' to `sockname' parameter. --- lisp/server.el | 56 ++++++++++++++++++++++++++++++++++++-------------------- src/emacs.c | 16 +++++++++++++--- src/lisp.h | 2 +- src/process.c | 19 ++++++++++++++++++- 4 files changed, 68 insertions(+), 25 deletions(-) diff --git a/lisp/server.el b/lisp/server.el index 0e225f723e..72417f31b7 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -251,8 +251,16 @@ server-existing-buffer are done with it in the server.") (make-variable-buffer-local 'server-existing-buffer) -;;;###autoload -(defcustom server-name "server" +(defvar server-external-socket-initialised nil + "When an external socket is passed into Emacs, we need to call +`server-start' in order to initialise the connection. This flag +prevents multiple initialisations when an external socket has +been consumed.") + +(defcustom server-name + (if (get-external-sockname) + (file-name-nondirectory (get-external-sockname)) + "server") "The name of the Emacs server, if this Emacs process creates one. The command `server-start' makes use of this. It should not be changed while a server is running." @@ -263,8 +271,10 @@ server-name ;; We do not use `temporary-file-directory' here, because emacsclient ;; does not read the init file. (defvar server-socket-dir - (and (featurep 'make-network-process '(:family local)) - (format "%s/emacs%d" (or (getenv "TMPDIR") "/tmp") (user-uid))) + (if (get-external-sockname) + (file-name-directory (get-external-sockname)) + (and (featurep 'make-network-process '(:family local)) + (format "%s/emacs%d" (or (getenv "TMPDIR") "/tmp") (user-uid)))) "The directory in which to place the server socket. If local sockets are not supported, this is nil.") @@ -618,23 +628,29 @@ server-start (when server-process ;; kill it dead! (ignore-errors (delete-process server-process))) - ;; Delete the socket files made by previous server invocations. - (if (not (eq t (server-running-p server-name))) - ;; Remove any leftover socket or authentication file - (ignore-errors - (let (delete-by-moving-to-trash) - (delete-file server-file))) - (setq server-mode nil) ;; already set by the minor mode code - (display-warning - 'server - (concat "Unable to start the Emacs server.\n" - (format "There is an existing Emacs server, named %S.\n" - server-name) - (substitute-command-keys - "To start the server in this Emacs process, stop the existing + ;; Check to see if an uninitialised external socket has been + ;; passed in, if that is the case, skip checking + ;; `server-running-p' as this will return the wrong result. + (if (and (get-external-sockname) + (not server-external-socket-initialised)) + (setq server-external-socket-initialised t) + ;; Delete the socket files made by previous server invocations. + (if (not (eq t (server-running-p server-name))) + ;; Remove any leftover socket or authentication file + (ignore-errors + (let (delete-by-moving-to-trash) + (delete-file server-file))) + (setq server-mode nil) ;; already set by the minor mode code + (display-warning + 'server + (concat "Unable to start the Emacs server.\n" + (format "There is an existing Emacs server, named %S.\n" + server-name) + (substitute-command-keys + "To start the server in this Emacs process, stop the existing server or call `\\[server-force-delete]' to forcibly disconnect it.")) - :warning) - (setq leave-dead t)) + :warning) + (setq leave-dead t))) ;; If this Emacs already had a server, clear out associated status. (while server-clients (server-delete-client (car server-clients))) diff --git a/src/emacs.c b/src/emacs.c index 9dd060fd3d..20587c9845 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -60,6 +60,7 @@ along with GNU Emacs. If not, see . */ #ifdef HAVE_LIBSYSTEMD # include # include +# include #endif #ifdef HAVE_WINDOW_SYSTEM @@ -1002,6 +1003,7 @@ main (int argc, char **argv) int sockfd = -1; + char *sockname = NULL; if (argmatch (argv, argc, "-fg-daemon", "--fg-daemon", 10, NULL, &skip_args) || argmatch (argv, argc, "-fg-daemon", "--fg-daemon", 10, &dname_arg, &skip_args)) @@ -1061,8 +1063,16 @@ main (int argc, char **argv) "Try 'Accept=false' in the Emacs socket unit file.\n")); else if (systemd_socket == 1 && (0 < sd_is_socket (SD_LISTEN_FDS_START, - AF_UNSPEC, SOCK_STREAM, 1))) - sockfd = SD_LISTEN_FDS_START; + AF_UNIX, SOCK_STREAM, 1))) + { + struct sockaddr_un sockaddr; + socklen_t sockaddr_sz = sizeof(sockaddr); + + sockfd = SD_LISTEN_FDS_START; + + if (!getsockname(sockfd, &sockaddr, &sockaddr_sz)) + sockname = strdup(sockaddr.sun_path); + } #endif /* HAVE_LIBSYSTEMD */ #ifdef USE_GTK @@ -1656,7 +1666,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem /* This can create a thread that may call getenv, so it must follow all calls to putenv and setenv. Also, this sets up add_keyboard_wait_descriptor, which init_display uses. */ - init_process_emacs (sockfd); + init_process_emacs (sockfd, sockname); init_keyboard (); /* This too must precede init_sys_modes. */ if (!noninteractive) diff --git a/src/lisp.h b/src/lisp.h index eb31ba209a..6bcc6125ba 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4313,7 +4313,7 @@ extern void delete_keyboard_wait_descriptor (int); extern void add_gpm_wait_descriptor (int); extern void delete_gpm_wait_descriptor (int); #endif -extern void init_process_emacs (int); +extern void init_process_emacs (int, char *); extern void syms_of_process (void); extern void setup_process_coding_systems (Lisp_Object); diff --git a/src/process.c b/src/process.c index 3a8bcfb3fc..fb86c611fc 100644 --- a/src/process.c +++ b/src/process.c @@ -276,6 +276,10 @@ static int max_desc; the file descriptor of a socket that is already bound. */ static int external_sock_fd; +/* The name (path) of the socket that was passed to Emacs, when + `external_sock_fd' is not -1. */ +static const char *external_sock_name = NULL; + /* Indexed by descriptor, gives the process (if any) for that descriptor. */ static Lisp_Object chan_process[FD_SETSIZE]; static void wait_for_socket_fds (Lisp_Object, char const *); @@ -7974,10 +7978,21 @@ restore_nofile_limit (void) } +DEFUN ("get-external-sockname", Fget_external_sockname, Sget_external_sockname, 0, 0, 0, + doc: /* Return the path of an external socket passed to Emacs. +Otherwise return nil. */) + (void) +{ + if (external_sock_name) + return make_string(external_sock_name, strlen(external_sock_name)); + else + return Qnil; +} + /* This is not called "init_process" because that is the name of a Mach system call, so it would cause problems on Darwin systems. */ void -init_process_emacs (int sockfd) +init_process_emacs (int sockfd, char *sockname) { #ifdef subprocesses int i; @@ -8012,6 +8027,7 @@ init_process_emacs (int sockfd) #endif external_sock_fd = sockfd; + external_sock_name = sockname; max_desc = -1; memset (fd_callback_info, 0, sizeof (fd_callback_info)); @@ -8306,4 +8322,5 @@ returns non-`nil'. */); defsubr (&Sprocess_inherit_coding_system_flag); defsubr (&Slist_system_processes); defsubr (&Sprocess_attributes); + defsubr (&Sget_external_sockname); } -- 2.14.3