aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthew Leach2016-04-16 12:43:01 +0300
committerEli Zaretskii2016-04-16 12:43:01 +0300
commite390b7b54651d3c5a4c36168e84e96e197631f41 (patch)
treed4ccdf1d6e243e9a5f58b42e78de349a1ffbc6c2 /src
parentbb8c8fdfbb226ea760e8e5761ecda98c8cd9564f (diff)
downloademacs-e390b7b54651d3c5a4c36168e84e96e197631f41.tar.gz
emacs-e390b7b54651d3c5a4c36168e84e96e197631f41.zip
Add external socket launching support
* src/process.c (connect_network_socket): Allow a pre-allocated socket descriptor to be used if passed to Emacs, avoiding the call to 'socket' and 'bind'. (Fmake_network_process): Allow users to pass ':use-external-socket' in the parameter plist to use any sockets that have been passed to Emacs. (wait_reading_process_output): Call 'socket' and 'bind' every time. (syms_of_process): New symbol ':use-external-socket'. (set_external_socket_descriptor): New function. (external_sock_fd): New variable. * src/lisp.h: (set_external_socket_descriptor): New declaration. * src/emacs.c (main): Call 'sd_listen_fds' to read the number of sockets passed and call 'set_external_socket_descriptor' to set the external socket. * src/Makefile.in: Add libsystemd library and C flags to the Emacs compilation options. * configure.ac: Add new default-on option "systemd" and check for libsystemd at configure time. * lisp/server.el (server-start): Set ':use-external-socket' to 't' when calling 'make-network-process'. * etc/NEWS: Document new socket-passing functionality and the configure option to disable systemd interaction. * doc/emacs/misc.texi (Emacs Server): Document systemd socket passing functionality and provide systemd unit examples. * doc/lispref/processes.texi (Network Processes): Document new 'make-network-process' option ':use-external-socket'.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in6
-rw-r--r--src/emacs.c22
-rw-r--r--src/lisp.h1
-rw-r--r--src/process.c52
4 files changed, 73 insertions, 8 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index c290a6082da..fc9360a5bde 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -307,6 +307,9 @@ LIBSELINUX_LIBS = @LIBSELINUX_LIBS@
307LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ 307LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@
308LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ 308LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@
309 309
310LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@
311LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@
312
310INTERVALS_H = dispextern.h intervals.h composite.h 313INTERVALS_H = dispextern.h intervals.h composite.h
311 314
312GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ 315GETLOADAVG_LIBS = @GETLOADAVG_LIBS@
@@ -372,6 +375,7 @@ ALL_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \
372 $(WEBKIT_CFLAGS) \ 375 $(WEBKIT_CFLAGS) \
373 $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \ 376 $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \
374 $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \ 377 $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \
378 $(LIBSYSTEMD_CFLAGS) \
375 $(LIBGNUTLS_CFLAGS) $(NOTIFY_CFLAGS) $(CAIRO_CFLAGS) \ 379 $(LIBGNUTLS_CFLAGS) $(NOTIFY_CFLAGS) $(CAIRO_CFLAGS) \
376 $(WARN_CFLAGS) $(WERROR_CFLAGS) $(CFLAGS) 380 $(WARN_CFLAGS) $(WERROR_CFLAGS) $(CFLAGS)
377ALL_OBJC_CFLAGS=$(ALL_CFLAGS) $(GNU_OBJC_CFLAGS) 381ALL_OBJC_CFLAGS=$(ALL_CFLAGS) $(GNU_OBJC_CFLAGS)
@@ -489,7 +493,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \
489 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ 493 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
490 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ 494 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
491 $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) \ 495 $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) \
492 $(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) 496 $(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS)
493 497
494$(leimdir)/leim-list.el: bootstrap-emacs$(EXEEXT) 498$(leimdir)/leim-list.el: bootstrap-emacs$(EXEEXT)
495 $(MAKE) -C ../leim leim-list.el EMACS="$(bootstrap_exe)" 499 $(MAKE) -C ../leim leim-list.el EMACS="$(bootstrap_exe)"
diff --git a/src/emacs.c b/src/emacs.c
index c21c9e3971c..a51df0903b1 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -56,6 +56,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
56#include <binary-io.h> 56#include <binary-io.h>
57#endif 57#endif
58 58
59#ifdef HAVE_LIBSYSTEMD
60#include <systemd/sd-daemon.h>
61#include <sys/socket.h>
62#endif /* HAVE_LIBSYSTEMD */
63
59#ifdef HAVE_WINDOW_SYSTEM 64#ifdef HAVE_WINDOW_SYSTEM
60#include TERM_HEADER 65#include TERM_HEADER
61#endif /* HAVE_WINDOW_SYSTEM */ 66#endif /* HAVE_WINDOW_SYSTEM */
@@ -676,6 +681,9 @@ main (int argc, char **argv)
676 char dname_arg2[80]; 681 char dname_arg2[80];
677#endif 682#endif
678 char *ch_to_dir = 0; 683 char *ch_to_dir = 0;
684#ifdef HAVE_LIBSYSTEMD
685 int systemd_socket;
686#endif
679 687
680 /* If we use --chdir, this records the original directory. */ 688 /* If we use --chdir, this records the original directory. */
681 char *original_pwd = 0; 689 char *original_pwd = 0;
@@ -999,6 +1007,20 @@ main (int argc, char **argv)
999 exit (1); 1007 exit (1);
1000 } 1008 }
1001 1009
1010#ifdef HAVE_LIBSYSTEMD
1011 /* Read the number of sockets passed through by systemd. */
1012 systemd_socket = sd_listen_fds(1);
1013
1014 if (systemd_socket > 1)
1015 fprintf (stderr, "\nWarning: systemd has passed more than one socket to the Emacs process.\n\
1016Try adding 'Accept=false' in the Emacs socket unit file.\n");
1017
1018 else if (systemd_socket == 1 &&
1019 sd_is_socket (SD_LISTEN_FDS_START,
1020 AF_UNSPEC, SOCK_STREAM, 1) >= 0)
1021 set_external_socket_descriptor (SD_LISTEN_FDS_START);
1022#endif /* HAVE_LIBSYSTEMD */
1023
1002#ifndef DAEMON_MUST_EXEC 1024#ifndef DAEMON_MUST_EXEC
1003#ifdef USE_GTK 1025#ifdef USE_GTK
1004 fprintf (stderr, "\nWarning: due to a long standing Gtk+ bug\nhttp://bugzilla.gnome.org/show_bug.cgi?id=85715\n\ 1026 fprintf (stderr, "\nWarning: due to a long standing Gtk+ bug\nhttp://bugzilla.gnome.org/show_bug.cgi?id=85715\n\
diff --git a/src/lisp.h b/src/lisp.h
index d111a78f3e0..c6f8bb89a3f 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4184,6 +4184,7 @@ extern void delete_gpm_wait_descriptor (int);
4184extern void init_process_emacs (void); 4184extern void init_process_emacs (void);
4185extern void syms_of_process (void); 4185extern void syms_of_process (void);
4186extern void setup_process_coding_systems (Lisp_Object); 4186extern void setup_process_coding_systems (Lisp_Object);
4187extern void set_external_socket_descriptor (int);
4187 4188
4188/* Defined in callproc.c. */ 4189/* Defined in callproc.c. */
4189#ifndef DOS_NT 4190#ifndef DOS_NT
diff --git a/src/process.c b/src/process.c
index a006ca61ac5..2dfad669072 100644
--- a/src/process.c
+++ b/src/process.c
@@ -267,6 +267,9 @@ static int max_process_desc;
267/* The largest descriptor currently in use for input; -1 if none. */ 267/* The largest descriptor currently in use for input; -1 if none. */
268static int max_input_desc; 268static int max_input_desc;
269 269
270/* The descriptor of any sockets passed to Emacs; -1 if none. */
271static int external_sock_fd = -1;
272
270/* Indexed by descriptor, gives the process (if any) for that descriptor. */ 273/* Indexed by descriptor, gives the process (if any) for that descriptor. */
271static Lisp_Object chan_process[FD_SETSIZE]; 274static Lisp_Object chan_process[FD_SETSIZE];
272static void wait_for_socket_fds (Lisp_Object, char const *); 275static void wait_for_socket_fds (Lisp_Object, char const *);
@@ -3075,7 +3078,8 @@ finish_after_tls_connection (Lisp_Object proc)
3075#endif 3078#endif
3076 3079
3077static void 3080static void
3078connect_network_socket (Lisp_Object proc, Lisp_Object ip_addresses) 3081connect_network_socket (Lisp_Object proc, Lisp_Object ip_addresses,
3082 Lisp_Object use_external_socket_p)
3079{ 3083{
3080 ptrdiff_t count = SPECPDL_INDEX (); 3084 ptrdiff_t count = SPECPDL_INDEX ();
3081 ptrdiff_t count1; 3085 ptrdiff_t count1;
@@ -3089,6 +3093,16 @@ connect_network_socket (Lisp_Object proc, Lisp_Object ip_addresses)
3089 struct Lisp_Process *p = XPROCESS (proc); 3093 struct Lisp_Process *p = XPROCESS (proc);
3090 Lisp_Object contact = p->childp; 3094 Lisp_Object contact = p->childp;
3091 int optbits = 0; 3095 int optbits = 0;
3096 int socket_to_use = -1;
3097
3098 if (!NILP (use_external_socket_p))
3099 {
3100 socket_to_use = external_sock_fd;
3101
3102 /* Ensure we don't consume the external socket twice. */
3103 external_sock_fd = -1;
3104 }
3105
3092 3106
3093 /* Do this in case we never enter the while-loop below. */ 3107 /* Do this in case we never enter the while-loop below. */
3094 count1 = SPECPDL_INDEX (); 3108 count1 = SPECPDL_INDEX ();
@@ -3109,7 +3123,11 @@ connect_network_socket (Lisp_Object proc, Lisp_Object ip_addresses)
3109 sa = xmalloc (addrlen); 3123 sa = xmalloc (addrlen);
3110 conv_lisp_to_sockaddr (family, ip_address, sa, addrlen); 3124 conv_lisp_to_sockaddr (family, ip_address, sa, addrlen);
3111 3125
3112 s = socket (family, p->socktype | SOCK_CLOEXEC, p->ai_protocol); 3126 if (socket_to_use != -1)
3127 s = socket_to_use;
3128 else
3129 s = socket (family, p->socktype | SOCK_CLOEXEC, p->ai_protocol);
3130
3113 if (s < 0) 3131 if (s < 0)
3114 { 3132 {
3115 xerrno = errno; 3133 xerrno = errno;
@@ -3168,8 +3186,11 @@ connect_network_socket (Lisp_Object proc, Lisp_Object ip_addresses)
3168 report_file_error ("Cannot set reuse option on server socket", Qnil); 3186 report_file_error ("Cannot set reuse option on server socket", Qnil);
3169 } 3187 }
3170 3188
3171 if (bind (s, sa, addrlen)) 3189 /* If we are passed a socket descriptor, it should be
3172 report_file_error ("Cannot bind server socket", Qnil); 3190 already bound. */
3191 if (socket_to_use == -1)
3192 if (bind (s, sa, addrlen))
3193 report_file_error ("Cannot bind server socket", Qnil);
3173 3194
3174#ifdef HAVE_GETSOCKNAME 3195#ifdef HAVE_GETSOCKNAME
3175 if (p->port == 0) 3196 if (p->port == 0)
@@ -3534,6 +3555,11 @@ The following network options can be specified for this connection:
3534 (this is allowed by default for a server process). 3555 (this is allowed by default for a server process).
3535:bindtodevice NAME -- bind to interface NAME. Using this may require 3556:bindtodevice NAME -- bind to interface NAME. Using this may require
3536 special privileges on some systems. 3557 special privileges on some systems.
3558:use-external-socket BOOL -- Use any pre-allocated sockets that have
3559 been passed to Emacs. If Emacs wasn't
3560 passed a socket, this option is silently
3561 ignored.
3562
3537 3563
3538Consult the relevant system programmer's manual pages for more 3564Consult the relevant system programmer's manual pages for more
3539information on using these options. 3565information on using these options.
@@ -3578,7 +3604,7 @@ usage: (make-network-process &rest ARGS) */)
3578 EMACS_INT port = 0; 3604 EMACS_INT port = 0;
3579 Lisp_Object tem; 3605 Lisp_Object tem;
3580 Lisp_Object name, buffer, host, service, address; 3606 Lisp_Object name, buffer, host, service, address;
3581 Lisp_Object filter, sentinel; 3607 Lisp_Object filter, sentinel, use_external_socket_p;
3582 Lisp_Object ip_addresses = Qnil; 3608 Lisp_Object ip_addresses = Qnil;
3583 int socktype; 3609 int socktype;
3584 int family = -1; 3610 int family = -1;
@@ -3618,6 +3644,7 @@ usage: (make-network-process &rest ARGS) */)
3618 buffer = Fplist_get (contact, QCbuffer); 3644 buffer = Fplist_get (contact, QCbuffer);
3619 filter = Fplist_get (contact, QCfilter); 3645 filter = Fplist_get (contact, QCfilter);
3620 sentinel = Fplist_get (contact, QCsentinel); 3646 sentinel = Fplist_get (contact, QCsentinel);
3647 use_external_socket_p = Fplist_get (contact, QCuse_external_socket);
3621 3648
3622 CHECK_STRING (name); 3649 CHECK_STRING (name);
3623 3650
@@ -3914,7 +3941,7 @@ usage: (make-network-process &rest ARGS) */)
3914 } 3941 }
3915#endif 3942#endif
3916 3943
3917 connect_network_socket (proc, ip_addresses); 3944 connect_network_socket (proc, ip_addresses, use_external_socket_p);
3918 return proc; 3945 return proc;
3919} 3946}
3920 3947
@@ -4848,7 +4875,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4848 { 4875 {
4849 Lisp_Object ip_addresses = check_for_dns (aproc); 4876 Lisp_Object ip_addresses = check_for_dns (aproc);
4850 if (!NILP (ip_addresses) && !EQ (ip_addresses, Qt)) 4877 if (!NILP (ip_addresses) && !EQ (ip_addresses, Qt))
4851 connect_network_socket (aproc, ip_addresses); 4878 connect_network_socket (aproc, ip_addresses, Qnil);
4852 else 4879 else
4853 retry_for_async = true; 4880 retry_for_async = true;
4854 } 4881 }
@@ -7709,6 +7736,16 @@ catch_child_signal (void)
7709} 7736}
7710#endif /* subprocesses */ 7737#endif /* subprocesses */
7711 7738
7739/* Set the external socket descriptor for Emacs to use when
7740 `make-network-process' is called with a non-nil
7741 `:use-external-socket' option. The fd should have been checked to
7742 ensure it is a valid socket and is already bound. */
7743void
7744set_external_socket_descriptor(int fd)
7745{
7746 external_sock_fd = fd;
7747}
7748
7712 7749
7713/* This is not called "init_process" because that is the name of a 7750/* This is not called "init_process" because that is the name of a
7714 Mach system call, so it would cause problems on Darwin systems. */ 7751 Mach system call, so it would cause problems on Darwin systems. */
@@ -7837,6 +7874,7 @@ syms_of_process (void)
7837 DEFSYM (QCserver, ":server"); 7874 DEFSYM (QCserver, ":server");
7838 DEFSYM (QCnowait, ":nowait"); 7875 DEFSYM (QCnowait, ":nowait");
7839 DEFSYM (QCsentinel, ":sentinel"); 7876 DEFSYM (QCsentinel, ":sentinel");
7877 DEFSYM (QCuse_external_socket, ":use-external-socket");
7840 DEFSYM (QCtls_parameters, ":tls-parameters"); 7878 DEFSYM (QCtls_parameters, ":tls-parameters");
7841 DEFSYM (Qnsm_verify_connection, "nsm-verify-connection"); 7879 DEFSYM (Qnsm_verify_connection, "nsm-verify-connection");
7842 DEFSYM (QClog, ":log"); 7880 DEFSYM (QClog, ":log");