diff options
| author | Matthew Leach | 2018-02-12 12:52:43 -0800 |
|---|---|---|
| committer | Paul Eggert | 2018-02-12 12:57:58 -0800 |
| commit | e1ca0ea87222e70710b3878ac80ed01f2378f050 (patch) | |
| tree | cc79162baa9b968066aafc8d5f2279c5755e5316 | |
| parent | b3f45140ec441bf88fa25f4e615b18e076d51342 (diff) | |
| download | emacs-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.el | 56 | ||||
| -rw-r--r-- | src/emacs.c | 16 | ||||
| -rw-r--r-- | src/lisp.h | 2 | ||||
| -rw-r--r-- | src/process.c | 19 |
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 | |||
| 251 | are done with it in the server.") | 251 | are 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 | ||
| 257 | prevents multiple initialisations when an external socket has | ||
| 258 | been 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. |
| 257 | The command `server-start' makes use of this. It should not be | 265 | The command `server-start' makes use of this. It should not be |
| 258 | changed while a server is running." | 266 | changed 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. |
| 269 | If local sockets are not supported, this is nil.") | 279 | If 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 | ||
| 635 | server or call `\\[server-force-delete]' to forcibly disconnect it.")) | 651 | server 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); | |||
| 4316 | extern void add_gpm_wait_descriptor (int); | 4316 | extern void add_gpm_wait_descriptor (int); |
| 4317 | extern void delete_gpm_wait_descriptor (int); | 4317 | extern void delete_gpm_wait_descriptor (int); |
| 4318 | #endif | 4318 | #endif |
| 4319 | extern void init_process_emacs (int); | 4319 | extern void init_process_emacs (int, char *); |
| 4320 | extern void syms_of_process (void); | 4320 | extern void syms_of_process (void); |
| 4321 | extern void setup_process_coding_systems (Lisp_Object); | 4321 | extern 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. */ |
| 277 | static int external_sock_fd; | 277 | static 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. */ | ||
| 281 | static 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. */ |
| 280 | static Lisp_Object chan_process[FD_SETSIZE]; | 284 | static Lisp_Object chan_process[FD_SETSIZE]; |
| 281 | static void wait_for_socket_fds (Lisp_Object, char const *); | 285 | static void wait_for_socket_fds (Lisp_Object, char const *); |
| @@ -7972,10 +7976,21 @@ restore_nofile_limit (void) | |||
| 7972 | } | 7976 | } |
| 7973 | 7977 | ||
| 7974 | 7978 | ||
| 7979 | DEFUN ("get-external-sockname", Fget_external_sockname, Sget_external_sockname, 0, 0, 0, | ||
| 7980 | doc: /* Return the path of an external socket passed to Emacs. | ||
| 7981 | Otherwise 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. */ |
| 7977 | void | 7992 | void |
| 7978 | init_process_emacs (int sockfd) | 7993 | init_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 | } |