aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGlenn Morris2016-11-15 23:28:47 -0800
committerGlenn Morris2016-11-15 23:28:47 -0800
commit36b99556dea23f17d5598bbed366e7201eec9fbb (patch)
treeb464455587a53e706288f95da497721c5c42a2c9 /src
parent35007ad9daca9cac39fe758b5815aa6389379d38 (diff)
downloademacs-36b99556dea23f17d5598bbed366e7201eec9fbb.tar.gz
emacs-36b99556dea23f17d5598bbed366e7201eec9fbb.zip
Add --new-daemon, which runs in the foreground and does not fork
This is intended for modern init systems such as systemd, which manage many of the traditional aspects of daemon behavior themselves. (Bug#2677) * src/emacs.c (daemon_type): New integer. (usage, standard_args): Add --old-daemon and --new-daemon. (main): Handle --old-daemon and --new-daemon arguments. Restrict all the forking and complicated daemon stuff to old-daemon. (Fdaemon_initialized): Handle new-style daemon. * src/lisp.h (IS_DAEMON, DAEMON_RUNNING) [!WINDOWNT]: Replace daemon_pipe with daemon_type. * doc/emacs/cmdargs.texi (Initial Options): * doc/emacs/glossary.texi (Glossary): * doc/emacs/misc.texi (Emacs Server): * doc/lispref/display.texi (Window Systems): * doc/lispref/os.texi (Startup Summary): Related doc updates. * etc/NEWS: Mention this. * etc/emacs.service: Use Type=simple and --new-daemon.
Diffstat (limited to 'src')
-rw-r--r--src/emacs.c296
-rw-r--r--src/lisp.h9
2 files changed, 169 insertions, 136 deletions
diff --git a/src/emacs.c b/src/emacs.c
index aeba9631696..92cbb086339 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -162,8 +162,8 @@ char *stack_bottom;
162static uprintmax_t heap_bss_diff; 162static uprintmax_t heap_bss_diff;
163#endif 163#endif
164 164
165/* To run as a daemon under Cocoa or Windows, we must do a fork+exec, 165/* To run as a background daemon under Cocoa or Windows,
166 not a simple fork. 166 we must do a fork+exec, not a simple fork.
167 167
168 On Cocoa, CoreFoundation lib fails in forked process: 168 On Cocoa, CoreFoundation lib fails in forked process:
169 http://developer.apple.com/ReleaseNotes/ 169 http://developer.apple.com/ReleaseNotes/
@@ -190,9 +190,12 @@ bool build_details;
190/* Name for the server started by the daemon.*/ 190/* Name for the server started by the daemon.*/
191static char *daemon_name; 191static char *daemon_name;
192 192
193/* 0 not a daemon, 1 new-style (foreground), 2 old-style (background). */
194int daemon_type;
195
193#ifndef WINDOWSNT 196#ifndef WINDOWSNT
194/* Pipe used to send exit notification to the daemon parent at 197/* Pipe used to send exit notification to the background daemon parent at
195 startup. */ 198 startup. On Windows, we use a kernel event instead. */
196int daemon_pipe[2]; 199int daemon_pipe[2];
197#else 200#else
198HANDLE w32_daemon_event; 201HANDLE w32_daemon_event;
@@ -223,7 +226,8 @@ Initialization options:\n\
223 "\ 226 "\
224--batch do not do interactive display; implies -q\n\ 227--batch do not do interactive display; implies -q\n\
225--chdir DIR change to directory DIR\n\ 228--chdir DIR change to directory DIR\n\
226--daemon[=NAME] start a (named) server in the background\n\ 229--daemon, --old-daemon[=NAME] start a (named) server in the background\n\
230--new-daemon[=NAME] start a (named) server in the foreground\n\
227--debug-init enable Emacs Lisp debugger for init file\n\ 231--debug-init enable Emacs Lisp debugger for init file\n\
228--display, -d DISPLAY use X server DISPLAY\n\ 232--display, -d DISPLAY use X server DISPLAY\n\
229", 233",
@@ -977,6 +981,8 @@ main (int argc, char **argv)
977 exit (0); 981 exit (0);
978 } 982 }
979 983
984 daemon_type = 0;
985
980#ifndef WINDOWSNT 986#ifndef WINDOWSNT
981 /* Make sure IS_DAEMON starts up as false. */ 987 /* Make sure IS_DAEMON starts up as false. */
982 daemon_pipe[1] = 0; 988 daemon_pipe[1] = 0;
@@ -987,38 +993,52 @@ main (int argc, char **argv)
987 993
988 int sockfd = -1; 994 int sockfd = -1;
989 995
990 if (argmatch (argv, argc, "-daemon", "--daemon", 5, NULL, &skip_args) 996 if (argmatch (argv, argc, "-new-daemon", "--new-daemon", 10, NULL, &skip_args)
991 || argmatch (argv, argc, "-daemon", "--daemon", 5, &dname_arg, &skip_args)) 997 || argmatch (argv, argc, "-new-daemon", "--new-daemon", 10, &dname_arg, &skip_args))
998 {
999 daemon_type = 1; /* foreground */
1000 }
1001 else if (argmatch (argv, argc, "-daemon", "--daemon", 5, NULL, &skip_args)
1002 || argmatch (argv, argc, "-daemon", "--daemon", 5, &dname_arg, &skip_args)
1003 || argmatch (argv, argc, "-old-daemon", "--old-daemon", 10, NULL, &skip_args)
1004 || argmatch (argv, argc, "-old-daemon", "--old-daemon", 10, &dname_arg, &skip_args))
1005 {
1006 daemon_type = 2; /* background */
1007 }
1008
1009
1010 if (daemon_type > 0)
992 { 1011 {
993#ifndef DOS_NT 1012#ifndef DOS_NT
994 pid_t f; 1013 if (daemon_type == 2)
995 1014 {
996 /* Start as a daemon: fork a new child process which will run the 1015 /* Start as a background daemon: fork a new child process which
997 rest of the initialization code, then exit. 1016 will run the rest of the initialization code, then exit.
998 1017
999 Detaching a daemon requires the following steps: 1018 Detaching a daemon requires the following steps:
1000 - fork 1019 - fork
1001 - setsid 1020 - setsid
1002 - exit the parent 1021 - exit the parent
1003 - close the tty file-descriptors 1022 - close the tty file-descriptors
1004 1023
1005 We only want to do the last 2 steps once the daemon is ready to 1024 We only want to do the last 2 steps once the daemon is ready to
1006 serve requests, i.e. after loading .emacs (initialization). 1025 serve requests, i.e. after loading .emacs (initialization).
1007 OTOH initialization may start subprocesses (e.g. ispell) and these 1026 OTOH initialization may start subprocesses (e.g. ispell) and these
1008 should be run from the proper process (the one that will end up 1027 should be run from the proper process (the one that will end up
1009 running as daemon) and with the proper "session id" in order for 1028 running as daemon) and with the proper "session id" in order for
1010 them to keep working after detaching, so fork and setsid need to be 1029 them to keep working after detaching, so fork and setsid need to be
1011 performed before initialization. 1030 performed before initialization.
1012 1031
1013 We want to avoid exiting before the server socket is ready, so 1032 We want to avoid exiting before the server socket is ready, so
1014 use a pipe for synchronization. The parent waits for the child 1033 use a pipe for synchronization. The parent waits for the child
1015 to close its end of the pipe (using `daemon-initialized') 1034 to close its end of the pipe (using `daemon-initialized')
1016 before exiting. */ 1035 before exiting. */
1017 if (emacs_pipe (daemon_pipe) != 0) 1036 if (emacs_pipe (daemon_pipe) != 0)
1018 { 1037 {
1019 fprintf (stderr, "Cannot pipe!\n"); 1038 fprintf (stderr, "Cannot pipe!\n");
1020 exit (1); 1039 exit (1);
1021 } 1040 }
1041 } /* daemon_type == 2 */
1022 1042
1023#ifdef HAVE_LIBSYSTEMD 1043#ifdef HAVE_LIBSYSTEMD
1024 /* Read the number of sockets passed through by systemd. */ 1044 /* Read the number of sockets passed through by systemd. */
@@ -1035,99 +1055,105 @@ main (int argc, char **argv)
1035 sockfd = SD_LISTEN_FDS_START; 1055 sockfd = SD_LISTEN_FDS_START;
1036#endif /* HAVE_LIBSYSTEMD */ 1056#endif /* HAVE_LIBSYSTEMD */
1037 1057
1038#ifndef DAEMON_MUST_EXEC
1039#ifdef USE_GTK 1058#ifdef USE_GTK
1040 fprintf (stderr, "\nWarning: due to a long standing Gtk+ bug\nhttp://bugzilla.gnome.org/show_bug.cgi?id=85715\n\ 1059 fprintf (stderr, "\nWarning: due to a long standing Gtk+ bug\nhttp://bugzilla.gnome.org/show_bug.cgi?id=85715\n\
1041Emacs might crash when run in daemon mode and the X11 connection is unexpectedly lost.\n\ 1060Emacs might crash when run in daemon mode and the X11 connection is unexpectedly lost.\n\
1042Using an Emacs configured with --with-x-toolkit=lucid does not have this problem.\n"); 1061Using an Emacs configured with --with-x-toolkit=lucid does not have this problem.\n");
1043#endif /* USE_GTK */ 1062#endif /* USE_GTK */
1044 f = fork ();
1045#else /* DAEMON_MUST_EXEC */
1046 if (!dname_arg || !strchr (dname_arg, '\n'))
1047 f = fork (); /* in orig */
1048 else
1049 f = 0; /* in exec'd */
1050#endif /* !DAEMON_MUST_EXEC */
1051 if (f > 0)
1052 {
1053 int retval;
1054 char buf[1];
1055
1056 /* Close unused writing end of the pipe. */
1057 emacs_close (daemon_pipe[1]);
1058 1063
1059 /* Just wait for the child to close its end of the pipe. */ 1064 if (daemon_type == 2)
1060 do 1065 {
1061 { 1066 pid_t f;
1062 retval = read (daemon_pipe[0], &buf, 1); 1067#ifndef DAEMON_MUST_EXEC
1063 }
1064 while (retval == -1 && errno == EINTR);
1065
1066 if (retval < 0)
1067 {
1068 fprintf (stderr, "Error reading status from child\n");
1069 exit (1);
1070 }
1071 else if (retval == 0)
1072 {
1073 fprintf (stderr, "Error: server did not start correctly\n");
1074 exit (1);
1075 }
1076 1068
1077 emacs_close (daemon_pipe[0]); 1069 f = fork ();
1078 exit (0); 1070#else /* DAEMON_MUST_EXEC */
1079 } 1071 if (!dname_arg || !strchr (dname_arg, '\n'))
1080 if (f < 0) 1072 f = fork (); /* in orig */
1081 { 1073 else
1082 emacs_perror ("fork"); 1074 f = 0; /* in exec'd */
1083 exit (EXIT_CANCELED); 1075#endif /* !DAEMON_MUST_EXEC */
1084 } 1076 if (f > 0)
1077 {
1078 int retval;
1079 char buf[1];
1080
1081 /* Close unused writing end of the pipe. */
1082 emacs_close (daemon_pipe[1]);
1083
1084 /* Just wait for the child to close its end of the pipe. */
1085 do
1086 {
1087 retval = read (daemon_pipe[0], &buf, 1);
1088 }
1089 while (retval == -1 && errno == EINTR);
1090
1091 if (retval < 0)
1092 {
1093 fprintf (stderr, "Error reading status from child\n");
1094 exit (1);
1095 }
1096 else if (retval == 0)
1097 {
1098 fprintf (stderr, "Error: server did not start correctly\n");
1099 exit (1);
1100 }
1101
1102 emacs_close (daemon_pipe[0]);
1103 exit (0);
1104 }
1105 if (f < 0)
1106 {
1107 emacs_perror ("fork");
1108 exit (EXIT_CANCELED);
1109 }
1085 1110
1086#ifdef DAEMON_MUST_EXEC 1111#ifdef DAEMON_MUST_EXEC
1087 { 1112 {
1088 /* In orig process, forked as child, OR in exec'd. */ 1113 /* In orig process, forked as child, OR in exec'd. */
1089 if (!dname_arg || !strchr (dname_arg, '\n')) 1114 if (!dname_arg || !strchr (dname_arg, '\n'))
1090 { /* In orig, child: now exec w/special daemon name. */ 1115 { /* In orig, child: now exec w/special daemon name. */
1091 char fdStr[80]; 1116 char fdStr[80];
1092 int fdStrlen = 1117 int fdStrlen =
1093 snprintf (fdStr, sizeof fdStr, 1118 snprintf (fdStr, sizeof fdStr,
1094 "--daemon=\n%d,%d\n%s", daemon_pipe[0], 1119 "--old-daemon=\n%d,%d\n%s", daemon_pipe[0],
1095 daemon_pipe[1], dname_arg ? dname_arg : ""); 1120 daemon_pipe[1], dname_arg ? dname_arg : "");
1096 1121
1097 if (! (0 <= fdStrlen && fdStrlen < sizeof fdStr)) 1122 if (! (0 <= fdStrlen && fdStrlen < sizeof fdStr))
1098 { 1123 {
1099 fprintf (stderr, "daemon: child name too long\n"); 1124 fprintf (stderr, "daemon: child name too long\n");
1100 exit (EXIT_CANNOT_INVOKE); 1125 exit (EXIT_CANNOT_INVOKE);
1126 }
1127
1128 argv[skip_args] = fdStr;
1129
1130 fcntl (daemon_pipe[0], F_SETFD, 0);
1131 fcntl (daemon_pipe[1], F_SETFD, 0);
1132 execvp (argv[0], argv);
1133 emacs_perror (argv[0]);
1134 exit (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
1101 } 1135 }
1102 1136
1103 argv[skip_args] = fdStr; 1137 /* In exec'd: parse special dname into pipe and name info. */
1104 1138 if (!dname_arg || !strchr (dname_arg, '\n')
1105 fcntl (daemon_pipe[0], F_SETFD, 0); 1139 || strlen (dname_arg) < 1 || strlen (dname_arg) > 70)
1106 fcntl (daemon_pipe[1], F_SETFD, 0);
1107 execvp (argv[0], argv);
1108 emacs_perror (argv[0]);
1109 exit (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
1110 }
1111
1112 /* In exec'd: parse special dname into pipe and name info. */
1113 if (!dname_arg || !strchr (dname_arg, '\n')
1114 || strlen (dname_arg) < 1 || strlen (dname_arg) > 70)
1115 { 1140 {
1116 fprintf (stderr, "emacs daemon: daemon name absent or too long\n"); 1141 fprintf (stderr, "emacs daemon: daemon name absent or too long\n");
1117 exit (EXIT_CANNOT_INVOKE); 1142 exit (EXIT_CANNOT_INVOKE);
1118 } 1143 }
1119 dname_arg2[0] = '\0'; 1144 dname_arg2[0] = '\0';
1120 sscanf (dname_arg, "\n%d,%d\n%s", &(daemon_pipe[0]), &(daemon_pipe[1]), 1145 sscanf (dname_arg, "\n%d,%d\n%s", &(daemon_pipe[0]), &(daemon_pipe[1]),
1121 dname_arg2); 1146 dname_arg2);
1122 dname_arg = *dname_arg2 ? dname_arg2 : NULL; 1147 dname_arg = *dname_arg2 ? dname_arg2 : NULL;
1123 fcntl (daemon_pipe[1], F_SETFD, FD_CLOEXEC); 1148 fcntl (daemon_pipe[1], F_SETFD, FD_CLOEXEC);
1124 } 1149 }
1125#endif /* DAEMON_MUST_EXEC */ 1150#endif /* DAEMON_MUST_EXEC */
1126 1151
1127 /* Close unused reading end of the pipe. */ 1152 /* Close unused reading end of the pipe. */
1128 emacs_close (daemon_pipe[0]); 1153 emacs_close (daemon_pipe[0]);
1129 1154
1130 setsid (); 1155 setsid ();
1156 } /* daemon_type == 2 */
1131#elif defined(WINDOWSNT) 1157#elif defined(WINDOWSNT)
1132 /* Indicate that we want daemon mode. */ 1158 /* Indicate that we want daemon mode. */
1133 w32_daemon_event = CreateEvent (NULL, TRUE, FALSE, W32_DAEMON_EVENT); 1159 w32_daemon_event = CreateEvent (NULL, TRUE, FALSE, W32_DAEMON_EVENT);
@@ -1138,7 +1164,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1138 exit (1); 1164 exit (1);
1139 } 1165 }
1140#else /* MSDOS */ 1166#else /* MSDOS */
1141 fprintf (stderr, "This platform does not support the -daemon flag.\n"); 1167 fprintf (stderr, "This platform does not support daemon mode.\n");
1142 exit (1); 1168 exit (1);
1143#endif /* MSDOS */ 1169#endif /* MSDOS */
1144 if (dname_arg) 1170 if (dname_arg)
@@ -1684,6 +1710,8 @@ static const struct standard_args standard_args[] =
1684 { "-batch", "--batch", 100, 0 }, 1710 { "-batch", "--batch", 100, 0 },
1685 { "-script", "--script", 100, 1 }, 1711 { "-script", "--script", 100, 1 },
1686 { "-daemon", "--daemon", 99, 0 }, 1712 { "-daemon", "--daemon", 99, 0 },
1713 { "-old-daemon", "--old-daemon", 99, 0 },
1714 { "-new-daemon", "--new-daemon", 99, 0 },
1687 { "-help", "--help", 90, 0 }, 1715 { "-help", "--help", 90, 0 },
1688 { "-nl", "--no-loadup", 70, 0 }, 1716 { "-nl", "--no-loadup", 70, 0 },
1689 { "-nsl", "--no-site-lisp", 65, 0 }, 1717 { "-nsl", "--no-site-lisp", 65, 0 },
@@ -2407,27 +2435,33 @@ from the parent process and its tty file descriptors. */)
2407 if (NILP (Vafter_init_time)) 2435 if (NILP (Vafter_init_time))
2408 error ("This function can only be called after loading the init files"); 2436 error ("This function can only be called after loading the init files");
2409#ifndef WINDOWSNT 2437#ifndef WINDOWSNT
2410 int nfd; 2438
2411 2439 if (daemon_type == 2)
2412 /* Get rid of stdin, stdout and stderr. */ 2440 {
2413 nfd = emacs_open ("/dev/null", O_RDWR, 0); 2441 int nfd;
2414 err |= nfd < 0; 2442
2415 err |= dup2 (nfd, STDIN_FILENO) < 0; 2443 /* Get rid of stdin, stdout and stderr. */
2416 err |= dup2 (nfd, STDOUT_FILENO) < 0; 2444 nfd = emacs_open ("/dev/null", O_RDWR, 0);
2417 err |= dup2 (nfd, STDERR_FILENO) < 0; 2445 err |= nfd < 0;
2418 err |= emacs_close (nfd) != 0; 2446 err |= dup2 (nfd, STDIN_FILENO) < 0;
2419 2447 err |= dup2 (nfd, STDOUT_FILENO) < 0;
2420 /* Closing the pipe will notify the parent that it can exit. 2448 err |= dup2 (nfd, STDERR_FILENO) < 0;
2421 FIXME: In case some other process inherited the pipe, closing it here 2449 err |= emacs_close (nfd) != 0;
2422 won't notify the parent because it's still open elsewhere, so we 2450
2423 additionally send a byte, just to make sure the parent really exits. 2451 /* Closing the pipe will notify the parent that it can exit.
2424 Instead, we should probably close the pipe in start-process and 2452 FIXME: In case some other process inherited the pipe, closing it here
2425 call-process to make sure the pipe is never inherited by 2453 won't notify the parent because it's still open elsewhere, so we
2426 subprocesses. */ 2454 additionally send a byte, just to make sure the parent really exits.
2427 err |= write (daemon_pipe[1], "\n", 1) < 0; 2455 Instead, we should probably close the pipe in start-process and
2428 err |= emacs_close (daemon_pipe[1]) != 0; 2456 call-process to make sure the pipe is never inherited by
2457 subprocesses. */
2458 err |= write (daemon_pipe[1], "\n", 1) < 0;
2459 err |= emacs_close (daemon_pipe[1]) != 0;
2460 }
2461
2429 /* Set it to an invalid value so we know we've already run this function. */ 2462 /* Set it to an invalid value so we know we've already run this function. */
2430 daemon_pipe[1] = -1; 2463 daemon_type = -1;
2464
2431#else /* WINDOWSNT */ 2465#else /* WINDOWSNT */
2432 /* Signal the waiting emacsclient process. */ 2466 /* Signal the waiting emacsclient process. */
2433 err |= SetEvent (w32_daemon_event) == 0; 2467 err |= SetEvent (w32_daemon_event) == 0;
diff --git a/src/lisp.h b/src/lisp.h
index aaa44232720..e087828d94f 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4139,12 +4139,11 @@ extern bool no_site_lisp;
4139/* True means put details like time stamps into builds. */ 4139/* True means put details like time stamps into builds. */
4140extern bool build_details; 4140extern bool build_details;
4141 4141
4142/* Pipe used to send exit notification to the daemon parent at
4143 startup. On Windows, we use a kernel event instead. */
4144#ifndef WINDOWSNT 4142#ifndef WINDOWSNT
4145extern int daemon_pipe[2]; 4143/* 0 not a daemon, 1 new-style (foreground), 2 old-style (background). */
4146#define IS_DAEMON (daemon_pipe[1] != 0) 4144extern int daemon_type;
4147#define DAEMON_RUNNING (daemon_pipe[1] >= 0) 4145#define IS_DAEMON (daemon_type != 0)
4146#define DAEMON_RUNNING (daemon_type >= 0)
4148#else /* WINDOWSNT */ 4147#else /* WINDOWSNT */
4149extern void *w32_daemon_event; 4148extern void *w32_daemon_event;
4150#define IS_DAEMON (w32_daemon_event != NULL) 4149#define IS_DAEMON (w32_daemon_event != NULL)