aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDan Nicolaescu2008-10-26 19:05:47 +0000
committerDan Nicolaescu2008-10-26 19:05:47 +0000
commit5790ef40bae85dc23ae404098198879106057697 (patch)
treeb479642da69b4f0531ed8efefc739e31cbcaa8e1 /src
parent91c491e0518186d86e66413736025f2f585daf60 (diff)
downloademacs-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/ChangeLog8
-rw-r--r--src/emacs.c83
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 @@
12008-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
12008-10-26 Stefan Monnier <monnier@iro.umontreal.ca> 92008-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. */
239int is_daemon = 0; 239int is_daemon = 0;
240 240
241/* Pipe used to send exit notification to the daemon parent at
242 startup. */
243static int daemon_pipe[2];
244
241/* Save argv and argc. */ 245/* Save argv and argc. */
242char **initial_argv; 246char **initial_argv;
243int initial_argc; 247int 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
2428DEFUN ("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
2391void 2457void
2392syms_of_emacs () 2458syms_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.