aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Leach2018-02-12 12:52:43 -0800
committerPaul Eggert2018-02-12 12:57:58 -0800
commite1ca0ea87222e70710b3878ac80ed01f2378f050 (patch)
treecc79162baa9b968066aafc8d5f2279c5755e5316
parentb3f45140ec441bf88fa25f4e615b18e076d51342 (diff)
downloademacs-e1ca0ea87222e70710b3878ac80ed01f2378f050.tar.gz
emacs-e1ca0ea87222e70710b3878ac80ed01f2378f050.zip
Fix `server-name' and `server-socket-dir' for (Bug#24218)
* 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/process.c: (external_sock_name): New. (get-external-sockname): New. (init_process_emacs): Set `external_sock_name' to `sockname' parameter.
-rw-r--r--lisp/server.el56
-rw-r--r--src/emacs.c16
-rw-r--r--src/lisp.h2
-rw-r--r--src/process.c19
4 files changed, 68 insertions, 25 deletions
diff --git a/lisp/server.el b/lisp/server.el
index d91a51e425a..d2406e21bdf 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -251,8 +251,16 @@ This means that the server should not kill the buffer when you say you
251are done with it in the server.") 251are done with it in the server.")
252(make-variable-buffer-local 'server-existing-buffer) 252(make-variable-buffer-local 'server-existing-buffer)
253 253
254;;;###autoload 254(defvar server-external-socket-initialised nil
255(defcustom server-name "server" 255 "When an external socket is passed into Emacs, we need to call
256`server-start' in order to initialise the connection. This flag
257prevents multiple initialisations when an external socket has
258been consumed.")
259
260(defcustom server-name
261 (if (get-external-sockname)
262 (file-name-nondirectory (get-external-sockname))
263 "server")
256 "The name of the Emacs server, if this Emacs process creates one. 264 "The name of the Emacs server, if this Emacs process creates one.
257The command `server-start' makes use of this. It should not be 265The command `server-start' makes use of this. It should not be
258changed while a server is running." 266changed while a server is running."
@@ -263,8 +271,10 @@ changed while a server is running."
263;; We do not use `temporary-file-directory' here, because emacsclient 271;; We do not use `temporary-file-directory' here, because emacsclient
264;; does not read the init file. 272;; does not read the init file.
265(defvar server-socket-dir 273(defvar server-socket-dir
266 (and (featurep 'make-network-process '(:family local)) 274 (if (get-external-sockname)
267 (format "%s/emacs%d" (or (getenv "TMPDIR") "/tmp") (user-uid))) 275 (file-name-directory (get-external-sockname))
276 (and (featurep 'make-network-process '(:family local))
277 (format "%s/emacs%d" (or (getenv "TMPDIR") "/tmp") (user-uid))))
268 "The directory in which to place the server socket. 278 "The directory in which to place the server socket.
269If local sockets are not supported, this is nil.") 279If local sockets are not supported, this is nil.")
270 280
@@ -618,23 +628,29 @@ To force-start a server, do \\[server-force-delete] and then
618 (when server-process 628 (when server-process
619 ;; kill it dead! 629 ;; kill it dead!
620 (ignore-errors (delete-process server-process))) 630 (ignore-errors (delete-process server-process)))
621 ;; Delete the socket files made by previous server invocations. 631 ;; Check to see if an uninitialised external socket has been
622 (if (not (eq t (server-running-p server-name))) 632 ;; passed in, if that is the case, skip checking
623 ;; Remove any leftover socket or authentication file 633 ;; `server-running-p' as this will return the wrong result.
624 (ignore-errors 634 (if (and (get-external-sockname)
625 (let (delete-by-moving-to-trash) 635 (not server-external-socket-initialised))
626 (delete-file server-file))) 636 (setq server-external-socket-initialised t)
627 (setq server-mode nil) ;; already set by the minor mode code 637 ;; Delete the socket files made by previous server invocations.
628 (display-warning 638 (if (not (eq t (server-running-p server-name)))
629 'server 639 ;; Remove any leftover socket or authentication file
630 (concat "Unable to start the Emacs server.\n" 640 (ignore-errors
631 (format "There is an existing Emacs server, named %S.\n" 641 (let (delete-by-moving-to-trash)
632 server-name) 642 (delete-file server-file)))
633 (substitute-command-keys 643 (setq server-mode nil) ;; already set by the minor mode code
634 "To start the server in this Emacs process, stop the existing 644 (display-warning
645 'server
646 (concat "Unable to start the Emacs server.\n"
647 (format "There is an existing Emacs server, named %S.\n"
648 server-name)
649 (substitute-command-keys
650 "To start the server in this Emacs process, stop the existing
635server or call `\\[server-force-delete]' to forcibly disconnect it.")) 651server or call `\\[server-force-delete]' to forcibly disconnect it."))
636 :warning) 652 :warning)
637 (setq leave-dead t)) 653 (setq leave-dead t)))
638 ;; If this Emacs already had a server, clear out associated status. 654 ;; If this Emacs already had a server, clear out associated status.
639 (while server-clients 655 (while server-clients
640 (server-delete-client (car server-clients))) 656 (server-delete-client (car server-clients)))
diff --git a/src/emacs.c b/src/emacs.c
index 8ea61b71fb7..c423faf6c0d 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -60,6 +60,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
60#ifdef HAVE_LIBSYSTEMD 60#ifdef HAVE_LIBSYSTEMD
61# include <systemd/sd-daemon.h> 61# include <systemd/sd-daemon.h>
62# include <sys/socket.h> 62# include <sys/socket.h>
63# include <sys/un.h>
63#endif 64#endif
64 65
65#ifdef HAVE_WINDOW_SYSTEM 66#ifdef HAVE_WINDOW_SYSTEM
@@ -1002,6 +1003,7 @@ main (int argc, char **argv)
1002 1003
1003 1004
1004 int sockfd = -1; 1005 int sockfd = -1;
1006 char *sockname = NULL;
1005 1007
1006 if (argmatch (argv, argc, "-fg-daemon", "--fg-daemon", 10, NULL, &skip_args) 1008 if (argmatch (argv, argc, "-fg-daemon", "--fg-daemon", 10, NULL, &skip_args)
1007 || argmatch (argv, argc, "-fg-daemon", "--fg-daemon", 10, &dname_arg, &skip_args)) 1009 || argmatch (argv, argc, "-fg-daemon", "--fg-daemon", 10, &dname_arg, &skip_args))
@@ -1061,8 +1063,16 @@ main (int argc, char **argv)
1061 "Try 'Accept=false' in the Emacs socket unit file.\n")); 1063 "Try 'Accept=false' in the Emacs socket unit file.\n"));
1062 else if (systemd_socket == 1 1064 else if (systemd_socket == 1
1063 && (0 < sd_is_socket (SD_LISTEN_FDS_START, 1065 && (0 < sd_is_socket (SD_LISTEN_FDS_START,
1064 AF_UNSPEC, SOCK_STREAM, 1))) 1066 AF_UNIX, SOCK_STREAM, 1)))
1065 sockfd = SD_LISTEN_FDS_START; 1067 {
1068 struct sockaddr_un sockaddr;
1069 socklen_t sockaddr_sz = sizeof(sockaddr);
1070
1071 sockfd = SD_LISTEN_FDS_START;
1072
1073 if (!getsockname(sockfd, &sockaddr, &sockaddr_sz))
1074 sockname = strdup(sockaddr.sun_path);
1075 }
1066#endif /* HAVE_LIBSYSTEMD */ 1076#endif /* HAVE_LIBSYSTEMD */
1067 1077
1068#ifdef USE_GTK 1078#ifdef USE_GTK
@@ -1660,7 +1670,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1660 /* This can create a thread that may call getenv, so it must follow 1670 /* This can create a thread that may call getenv, so it must follow
1661 all calls to putenv and setenv. Also, this sets up 1671 all calls to putenv and setenv. Also, this sets up
1662 add_keyboard_wait_descriptor, which init_display uses. */ 1672 add_keyboard_wait_descriptor, which init_display uses. */
1663 init_process_emacs (sockfd); 1673 init_process_emacs (sockfd, sockname);
1664 1674
1665 init_keyboard (); /* This too must precede init_sys_modes. */ 1675 init_keyboard (); /* This too must precede init_sys_modes. */
1666 if (!noninteractive) 1676 if (!noninteractive)
diff --git a/src/lisp.h b/src/lisp.h
index a7f0a1d78ff..0bd0e5e53cf 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4316,7 +4316,7 @@ extern void delete_keyboard_wait_descriptor (int);
4316extern void add_gpm_wait_descriptor (int); 4316extern void add_gpm_wait_descriptor (int);
4317extern void delete_gpm_wait_descriptor (int); 4317extern void delete_gpm_wait_descriptor (int);
4318#endif 4318#endif
4319extern void init_process_emacs (int); 4319extern void init_process_emacs (int, char *);
4320extern void syms_of_process (void); 4320extern void syms_of_process (void);
4321extern void setup_process_coding_systems (Lisp_Object); 4321extern void setup_process_coding_systems (Lisp_Object);
4322 4322
diff --git a/src/process.c b/src/process.c
index 2cc2c86df39..405c06db46d 100644
--- a/src/process.c
+++ b/src/process.c
@@ -276,6 +276,10 @@ static int max_desc;
276 the file descriptor of a socket that is already bound. */ 276 the file descriptor of a socket that is already bound. */
277static int external_sock_fd; 277static int external_sock_fd;
278 278
279/* The name (path) of the socket that was passed to Emacs, when
280 `external_sock_fd' is not -1. */
281static const char *external_sock_name = NULL;
282
279/* Indexed by descriptor, gives the process (if any) for that descriptor. */ 283/* Indexed by descriptor, gives the process (if any) for that descriptor. */
280static Lisp_Object chan_process[FD_SETSIZE]; 284static Lisp_Object chan_process[FD_SETSIZE];
281static void wait_for_socket_fds (Lisp_Object, char const *); 285static void wait_for_socket_fds (Lisp_Object, char const *);
@@ -7972,10 +7976,21 @@ restore_nofile_limit (void)
7972} 7976}
7973 7977
7974 7978
7979DEFUN ("get-external-sockname", Fget_external_sockname, Sget_external_sockname, 0, 0, 0,
7980 doc: /* Return the path of an external socket passed to Emacs.
7981Otherwise return nil. */)
7982 (void)
7983{
7984 if (external_sock_name)
7985 return make_string(external_sock_name, strlen(external_sock_name));
7986 else
7987 return Qnil;
7988}
7989
7975/* This is not called "init_process" because that is the name of a 7990/* This is not called "init_process" because that is the name of a
7976 Mach system call, so it would cause problems on Darwin systems. */ 7991 Mach system call, so it would cause problems on Darwin systems. */
7977void 7992void
7978init_process_emacs (int sockfd) 7993init_process_emacs (int sockfd, char *sockname)
7979{ 7994{
7980#ifdef subprocesses 7995#ifdef subprocesses
7981 int i; 7996 int i;
@@ -8010,6 +8025,7 @@ init_process_emacs (int sockfd)
8010#endif 8025#endif
8011 8026
8012 external_sock_fd = sockfd; 8027 external_sock_fd = sockfd;
8028 external_sock_name = sockname;
8013 max_desc = -1; 8029 max_desc = -1;
8014 memset (fd_callback_info, 0, sizeof (fd_callback_info)); 8030 memset (fd_callback_info, 0, sizeof (fd_callback_info));
8015 8031
@@ -8304,4 +8320,5 @@ returns non-`nil'. */);
8304 defsubr (&Sprocess_inherit_coding_system_flag); 8320 defsubr (&Sprocess_inherit_coding_system_flag);
8305 defsubr (&Slist_system_processes); 8321 defsubr (&Slist_system_processes);
8306 defsubr (&Sprocess_attributes); 8322 defsubr (&Sprocess_attributes);
8323 defsubr (&Sget_external_sockname);
8307} 8324}