>From 51e1d2919b261be0c734ab3a19b3478fb52f43c1 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 7 Jan 2018 13:47:12 -0800 Subject: [PATCH 2/2] Minor cleanups for server-name fix (Bug#24218) * lisp/server.el (server--external-socket-initialized): Rename from server-external-socket-initialised, since it should be private and Emacs uses American spelling. All uses changed. * src/emacs.c, src/lisp.h: Revert previous changes, as the initialization is now done in src/process.c, which already includes the relevant files. * src/process.c (union u_sockaddr): Move decl to top level. (external_sock_name, Fget_external_sockname): Remove, replacing with Vinternal__external_sockname. All uses changed. (init_process_emacs): Deduce socket name ourselves rather than have main.c do it. Use conv_sockaddr_to_lisp instead of doing it by hand. Conditionalize it on HAVE_GETSOCKNAME. --- lisp/server.el | 24 ++++++++++++------------ src/emacs.c | 16 +++------------- src/lisp.h | 2 +- src/process.c | 58 ++++++++++++++++++++++++++++++---------------------------- 4 files changed, 46 insertions(+), 54 deletions(-) diff --git a/lisp/server.el b/lisp/server.el index e8b53530c9..c867fde832 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -251,15 +251,15 @@ server-existing-buffer are done with it in the server.") (make-variable-buffer-local 'server-existing-buffer) -(defvar server-external-socket-initialised nil +(defvar server--external-socket-initialized 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 +`server-start' in order to initialize the connection. This flag +prevents multiple initializations when an external socket has been consumed.") (defcustom server-name - (if (get-external-sockname) - (file-name-nondirectory (get-external-sockname)) + (if internal--external-sockname + (file-name-nondirectory internal--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 @@ -271,8 +271,8 @@ server-name ;; We do not use `temporary-file-directory' here, because emacsclient ;; does not read the init file. (defvar server-socket-dir - (if (get-external-sockname) - (file-name-directory (get-external-sockname)) + (if internal--external-sockname + (file-name-directory internal--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. @@ -628,15 +628,15 @@ server-start (when server-process ;; kill it dead! (ignore-errors (delete-process server-process))) - ;; Check to see if an uninitialised external socket has been + ;; Check to see if an uninitialized 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) + (if (and internal--external-sockname + (not server--external-socket-initialized)) + (setq server--external-socket-initialized 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 + ;; Remove any leftover socket or authentication file. (ignore-errors (let (delete-by-moving-to-trash) (delete-file server-file))) diff --git a/src/emacs.c b/src/emacs.c index 1af09166b6..20ced26283 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -60,7 +60,6 @@ along with GNU Emacs. If not, see . */ #ifdef HAVE_LIBSYSTEMD # include # include -# include #endif #ifdef HAVE_WINDOW_SYSTEM @@ -1003,7 +1002,6 @@ 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)) @@ -1063,16 +1061,8 @@ 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_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); - } + AF_UNSPEC, SOCK_STREAM, 1))) + sockfd = SD_LISTEN_FDS_START; #endif /* HAVE_LIBSYSTEMD */ #ifdef USE_GTK @@ -1666,7 +1656,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, sockname); + init_process_emacs (sockfd); init_keyboard (); /* This too must precede init_sys_modes. */ if (!noninteractive) diff --git a/src/lisp.h b/src/lisp.h index 2e9002a226..3eb6e0d3c1 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, char *); +extern void init_process_emacs (int); 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 da8e5714b0..2613dd2be0 100644 --- a/src/process.c +++ b/src/process.c @@ -160,6 +160,18 @@ static bool kbd_is_on_hold; when exiting. */ bool inhibit_sentinels; +union u_sockaddr +{ + struct sockaddr sa; + struct sockaddr_in in; +#ifdef AF_INET6 + struct sockaddr_in6 in6; +#endif +#ifdef HAVE_LOCAL_SOCKETS + struct sockaddr_un un; +#endif +}; + #ifdef subprocesses #ifndef SOCK_CLOEXEC @@ -276,10 +288,6 @@ 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 *); @@ -4679,16 +4687,7 @@ server_accept_connection (Lisp_Object server, int channel) struct Lisp_Process *ps = XPROCESS (server); struct Lisp_Process *p; int s; - union u_sockaddr { - struct sockaddr sa; - struct sockaddr_in in; -#ifdef AF_INET6 - struct sockaddr_in6 in6; -#endif -#ifdef HAVE_LOCAL_SOCKETS - struct sockaddr_un un; -#endif - } saddr; + union u_sockaddr saddr; socklen_t len = sizeof saddr; ptrdiff_t count; @@ -7978,21 +7977,10 @@ 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, char *sockname) +init_process_emacs (int sockfd) { #ifdef subprocesses int i; @@ -8027,7 +8015,18 @@ init_process_emacs (int sockfd, char *sockname) #endif external_sock_fd = sockfd; - external_sock_name = sockname; + Lisp_Object sockname = Qnil; +# if HAVE_GETSOCKNAME + if (0 <= sockfd) + { + union u_sockaddr sa; + socklen_t salen = sizeof sa; + if (getsockname (sockfd, &sa.sa, &salen) == 0) + sockname = conv_sockaddr_to_lisp (&sa.sa, salen); + } +# endif + Vinternal__external_sockname = sockname; + max_desc = -1; memset (fd_callback_info, 0, sizeof (fd_callback_info)); @@ -8220,6 +8219,10 @@ These functions are called in the order of the list, until one of them returns non-`nil'. */); Vinterrupt_process_functions = list1 (Qinternal_default_interrupt_process); + DEFVAR_LISP ("internal--external-sockname", Vinternal__external_sockname, + doc: /* Name of external socket passed to Emacs, or nil if none. */); + Vinternal__external_sockname = Qnil; + DEFSYM (Qinternal_default_interrupt_process, "internal-default-interrupt-process"); DEFSYM (Qinterrupt_process_functions, "interrupt-process-functions"); @@ -8322,5 +8325,4 @@ returns non-`nil'. */); defsubr (&Sprocess_inherit_coding_system_flag); defsubr (&Slist_system_processes); defsubr (&Sprocess_attributes); - defsubr (&Sget_external_sockname); } -- 2.14.3