diff options
| author | Dan Nicolaescu | 2008-10-26 19:05:47 +0000 |
|---|---|---|
| committer | Dan Nicolaescu | 2008-10-26 19:05:47 +0000 |
| commit | 5790ef40bae85dc23ae404098198879106057697 (patch) | |
| tree | b479642da69b4f0531ed8efefc739e31cbcaa8e1 /src | |
| parent | 91c491e0518186d86e66413736025f2f585daf60 (diff) | |
| download | emacs-5790ef40bae85dc23ae404098198879106057697.tar.gz emacs-5790ef40bae85dc23ae404098198879106057697.zip | |
* startup.el (command-line): Call daemon-initialized after
starting the server.
* emacs.c (daemon_pipe): New variable
(main): Create a pipe before forking, make the parent exit only after
the child has closed its end of the pipe. Move closing the
descriptors ...
(Fdaemon_initialized): ... here. New function.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 8 | ||||
| -rw-r--r-- | src/emacs.c | 83 |
2 files changed, 83 insertions, 8 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 3dd47c8484b..f86b94ed7d8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2008-10-26 Romain Francoise <romain@orebokech.com> | ||
| 2 | |||
| 3 | * emacs.c (daemon_pipe): New variable | ||
| 4 | (main): Create a pipe before forking, make the parent exit only after | ||
| 5 | the child has closed its end of the pipe. Move closing the | ||
| 6 | descriptors ... | ||
| 7 | (Fdaemon_initialized): ... here. New function. | ||
| 8 | |||
| 1 | 2008-10-26 Stefan Monnier <monnier@iro.umontreal.ca> | 9 | 2008-10-26 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 10 | ||
| 3 | * chartab.c (Foptimize_char_table): Make sure `ascii' doesn't point to | 11 | * chartab.c (Foptimize_char_table): Make sure `ascii' doesn't point to |
diff --git a/src/emacs.c b/src/emacs.c index 4712e9c1d0b..bcc7fb05792 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -238,6 +238,10 @@ int noninteractive1; | |||
| 238 | /* Nonzero means Emacs was started as a daemon. */ | 238 | /* Nonzero means Emacs was started as a daemon. */ |
| 239 | int is_daemon = 0; | 239 | int is_daemon = 0; |
| 240 | 240 | ||
| 241 | /* Pipe used to send exit notification to the daemon parent at | ||
| 242 | startup. */ | ||
| 243 | static int daemon_pipe[2]; | ||
| 244 | |||
| 241 | /* Save argv and argc. */ | 245 | /* Save argv and argc. */ |
| 242 | char **initial_argv; | 246 | char **initial_argv; |
| 243 | int initial_argc; | 247 | int initial_argc; |
| @@ -1073,21 +1077,54 @@ main (int argc, char **argv) | |||
| 1073 | if (argmatch (argv, argc, "-daemon", "--daemon", 5, NULL, &skip_args)) | 1077 | if (argmatch (argv, argc, "-daemon", "--daemon", 5, NULL, &skip_args)) |
| 1074 | { | 1078 | { |
| 1075 | #ifndef DOS_NT | 1079 | #ifndef DOS_NT |
| 1076 | pid_t f = fork (); | 1080 | pid_t f; |
| 1077 | int nfd; | 1081 | |
| 1082 | /* Start as a daemon: fork a new child process which will run the | ||
| 1083 | rest of the initialization code, then exit. | ||
| 1084 | |||
| 1085 | We want to avoid exiting before the server socket is ready, so | ||
| 1086 | use a pipe for synchronization. The parent waits for the child | ||
| 1087 | to close its end of the pipe (using `daemon-initialized') | ||
| 1088 | before exiting. */ | ||
| 1089 | if (pipe (daemon_pipe) == -1) | ||
| 1090 | { | ||
| 1091 | fprintf (stderr, "Cannot pipe!\n"); | ||
| 1092 | exit (1); | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | f = fork (); | ||
| 1078 | if (f > 0) | 1096 | if (f > 0) |
| 1079 | exit (0); | 1097 | { |
| 1098 | int retval; | ||
| 1099 | char buf[1]; | ||
| 1100 | |||
| 1101 | /* Close unused writing end of the pipe. */ | ||
| 1102 | close (daemon_pipe[1]); | ||
| 1103 | |||
| 1104 | /* Just wait for the child to close its end of the pipe. */ | ||
| 1105 | do | ||
| 1106 | { | ||
| 1107 | retval = read (daemon_pipe[0], &buf, 1); | ||
| 1108 | } | ||
| 1109 | while (retval == -1 && errno == EINTR); | ||
| 1110 | |||
| 1111 | if (retval < 0) | ||
| 1112 | { | ||
| 1113 | fprintf (stderr, "Error reading status from child\n"); | ||
| 1114 | exit (1); | ||
| 1115 | } | ||
| 1116 | |||
| 1117 | close (daemon_pipe[0]); | ||
| 1118 | exit (0); | ||
| 1119 | } | ||
| 1080 | if (f < 0) | 1120 | if (f < 0) |
| 1081 | { | 1121 | { |
| 1082 | fprintf (stderr, "Cannot fork!\n"); | 1122 | fprintf (stderr, "Cannot fork!\n"); |
| 1083 | exit (1); | 1123 | exit (1); |
| 1084 | } | 1124 | } |
| 1085 | 1125 | ||
| 1086 | nfd = open ("/dev/null", O_RDWR); | 1126 | /* Close unused reading end of the pipe. */ |
| 1087 | dup2 (nfd, 0); | 1127 | close (daemon_pipe[0]); |
| 1088 | dup2 (nfd, 1); | ||
| 1089 | dup2 (nfd, 2); | ||
| 1090 | close (nfd); | ||
| 1091 | is_daemon = 1; | 1128 | is_daemon = 1; |
| 1092 | #ifdef HAVE_SETSID | 1129 | #ifdef HAVE_SETSID |
| 1093 | setsid(); | 1130 | setsid(); |
| @@ -2388,6 +2425,35 @@ DEFUN ("daemonp", Fdaemonp, Sdaemonp, 0, 0, 0, | |||
| 2388 | return is_daemon ? Qt : Qnil; | 2425 | return is_daemon ? Qt : Qnil; |
| 2389 | } | 2426 | } |
| 2390 | 2427 | ||
| 2428 | DEFUN ("daemon-initialized", Fdaemon_initialized, Sdaemon_initialized, 0, 0, 0, | ||
| 2429 | doc: /* Mark the Emacs daemon as being initialized. */) | ||
| 2430 | () | ||
| 2431 | { | ||
| 2432 | int nfd; | ||
| 2433 | |||
| 2434 | if (!is_daemon) | ||
| 2435 | error ("This function can only be called if emacs is run as a daemon"); | ||
| 2436 | |||
| 2437 | if (daemon_pipe[1] < 0) | ||
| 2438 | error ("The daemon has already been initialized"); | ||
| 2439 | |||
| 2440 | if (NILP (Vafter_init_time)) | ||
| 2441 | error ("This function can only be called after loading the init files"); | ||
| 2442 | |||
| 2443 | /* Get rid of stdin, stdout and stderr. */ | ||
| 2444 | open ("/dev/null", O_RDWR); | ||
| 2445 | dup2 (nfd, 0); | ||
| 2446 | dup2 (nfd, 1); | ||
| 2447 | dup2 (nfd, 2); | ||
| 2448 | close (nfd); | ||
| 2449 | |||
| 2450 | /* Closing the pipe will notify the parent that it can exit. */ | ||
| 2451 | close (daemon_pipe[1]); | ||
| 2452 | /* Set it to an invalid value so we know we've already run this function. */ | ||
| 2453 | daemon_pipe[1] = -1; | ||
| 2454 | return Qt; | ||
| 2455 | } | ||
| 2456 | |||
| 2391 | void | 2457 | void |
| 2392 | syms_of_emacs () | 2458 | syms_of_emacs () |
| 2393 | { | 2459 | { |
| @@ -2407,6 +2473,7 @@ syms_of_emacs () | |||
| 2407 | defsubr (&Sinvocation_name); | 2473 | defsubr (&Sinvocation_name); |
| 2408 | defsubr (&Sinvocation_directory); | 2474 | defsubr (&Sinvocation_directory); |
| 2409 | defsubr (&Sdaemonp); | 2475 | defsubr (&Sdaemonp); |
| 2476 | defsubr (&Sdaemon_initialized); | ||
| 2410 | 2477 | ||
| 2411 | DEFVAR_LISP ("command-line-args", &Vcommand_line_args, | 2478 | DEFVAR_LISP ("command-line-args", &Vcommand_line_args, |
| 2412 | doc: /* Args passed by shell to Emacs, as a list of strings. | 2479 | doc: /* Args passed by shell to Emacs, as a list of strings. |