This file is part of GNU Emacs.
-GNU Emacs is free software; you can redistribute it and/or modify
+GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <sys/types.h>
#include <sys/file.h>
-#ifdef VMS
-#include <ssdef.h>
-#endif
-
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "w32heap.h" /* for prototype of sbrk */
#endif
+#ifdef NS_IMPL_GNUSTEP
+/* At least under Debian, GSConfig is in a subdirectory. --Stef */
+#include <GNUstepBase/GSConfig.h>
+#endif
+
#include "lisp.h"
#include "commands.h"
#include "intervals.h"
#else
int gdb_use_lsb = 0;
#endif
-#ifdef NO_UNION_TYPE
+#ifndef USE_LISP_UNION_TYPE
int gdb_use_union = 0;
#else
int gdb_use_union = 1;
nil means get them only from PATH_LOADSEARCH. */
Lisp_Object Vinstallation_directory;
+/* The values of `current-time' before and after Emacs initialization. */
+Lisp_Object Vbefore_init_time, Vafter_init_time;
+
/* Hook run by `kill-emacs' before it does really anything. */
Lisp_Object Vkill_emacs_hook;
extern int inherited_pgroup;
#endif
-#ifdef HAVE_X_WINDOWS
+#if defined(HAVE_X_WINDOWS) || defined(HAVE_NS)
/* If non-zero, -d was specified, meaning we're using some window system. */
int display_arg;
#endif
/* The gap between BSS end and heap start as far as we can tell. */
static unsigned long heap_bss_diff;
-/* If the gap between BSS end and heap start is larger than this we try to
- work around it, and if that fails, output a warning in dump-emacs. */
+/* If the gap between BSS end and heap start is larger than this
+ output a warning in dump-emacs. */
#define MAX_HEAP_BSS_DIFF (1024*1024)
extern Lisp_Object Vinhibit_redisplay;
-#ifdef USG_SHARED_LIBRARIES
-/* If nonzero, this is the place to put the end of the writable segment
- at startup. */
-
-unsigned int bss_end = 0;
-#endif
-
/* Nonzero means running Emacs without interactive terminal. */
int noninteractive;
int noninteractive1;
+/* Name for the server started by the daemon.*/
+static char *daemon_name;
+
+/* Pipe used to send exit notification to the daemon parent at
+ startup. */
+int daemon_pipe[2];
+
/* Save argv and argc. */
char **initial_argv;
int initial_argc;
Initialization options:\n\
\n\
--batch do not do interactive display; implies -q\n\
+--daemon start a server in the background\n\
--debug-init enable Emacs Lisp debugger for init file\n\
---disable-font-backend do not use font backend (only if compiled)\n\
--display, -d DISPLAY use X server DISPLAY\n\
--multibyte, --no-unibyte inhibit the effect of EMACS_UNIBYTE\n\
--no-desktop do not load a saved desktop\n\
Action options:\n\
\n\
FILE visit FILE using find-file\n\
-+LINE go to line LINE in next FILE\n\
-+LINE:COLUMN go to line LINE, column COLUMN, in next FILE\n\
++LINE go to line LINE in next FILE\n\
++LINE:COLUMN go to line LINE, column COLUMN, in next FILE\n\
--directory, -L DIR add DIR to variable load-path\n\
--eval EXPR evaluate Emacs Lisp expression EXPR\n\
--execute EXPR evaluate Emacs Lisp expression EXPR\n\
void (*fatal_error_signal_hook) P_ ((void));
-#ifdef HAVE_GTK_AND_PTHREAD
-/* When compiled with GTK and running under Gnome, multiple threads may be
- created. Keep track of our main thread to make sure signals are delivered
- to it (see syssignal.h). */
+#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
+/* When compiled with GTK and running under Gnome,
+ multiple threads may be created. Keep track of our main
+ thread to make sure signals are delivered to it (see syssignal.h). */
pthread_t main_thread;
#endif
shut_down_emacs (sig, 0, Qnil);
}
-#ifdef VMS
- LIB$STOP (SS$_ABORT);
-#else
/* Signal the same code; this time it will really be fatal.
Remember that since we're in a signal handler, the signal we're
going to send is probably blocked, so we have to unblock it if we
fatal_error_signal_hook ();
kill (getpid (), fatal_error_code);
-#endif /* not VMS */
}
#ifdef SIGDANGER
}
\f
-#ifdef VMS
-#ifdef LINK_CRTL_SHARE
-#ifdef SHARABLE_LIB_BUG
-extern noshare char **environ;
-#endif /* SHARABLE_LIB_BUG */
-#endif /* LINK_CRTL_SHARE */
-#endif /* VMS */
-
#ifdef HAVE_TZSET
/* A valid but unlikely value for the TZ environment value.
It is OK (though a bit slower) if the user actually chooses this value. */
return count >= 3 ? REPORT_EMACS_BUG_PRETEST_ADDRESS : REPORT_EMACS_BUG_ADDRESS;
}
-#ifdef USE_FONT_BACKEND
-extern int enable_font_backend;
-#endif /* USE_FONT_BACKEND */
/* ARGSUSED */
int
-main (argc, argv
-#ifdef VMS
-, envp
-#endif
-)
- int argc;
- char **argv;
-#ifdef VMS
- char **envp;
-#endif
+main (int argc, char **argv)
{
#if GC_MARK_STACK
Lisp_Object dummy;
#endif
int no_loadup = 0;
char *junk = 0;
+ char *dname_arg = 0;
#if GC_MARK_STACK
extern Lisp_Object *stack_base;
}
#ifdef LINUX_SBRK_BUG
+ /* This is only used GNU/LINUX running on alpha when using libc5 */
__sbrk (1);
#endif
run_time_remap (argv[0]);
#endif
-#ifdef MAC_OSX
+/* If using unexmacosx.c (set by s/darwin.h), we must do this. */
+#ifdef DARWIN_OS
if (!initialized)
unexec_init_emacs_zone ();
#endif
}
#ifdef HAVE_PERSONALITY_LINUX32
- /* See if there is a gap between the end of BSS and the heap.
- In that case, set personality and exec ourself again. */
if (!initialized
&& (strcmp (argv[argc-1], "dump") == 0
|| strcmp (argv[argc-1], "bootstrap") == 0)
- && heap_bss_diff > MAX_HEAP_BSS_DIFF)
+ && ! getenv ("EMACS_HEAP_EXEC"))
{
- if (! getenv ("EMACS_HEAP_EXEC"))
- {
- /* Set this so we only do this once. */
- putenv("EMACS_HEAP_EXEC=true");
+ /* Set this so we only do this once. */
+ putenv("EMACS_HEAP_EXEC=true");
- /* A flag to turn off address randomization which is introduced
- in linux kernel shipped with fedora core 4 */
+ /* A flag to turn off address randomization which is introduced
+ in linux kernel shipped with fedora core 4 */
#define ADD_NO_RANDOMIZE 0x0040000
- personality (PER_LINUX32 | ADD_NO_RANDOMIZE);
+ personality (PER_LINUX32 | ADD_NO_RANDOMIZE);
#undef ADD_NO_RANDOMIZE
- execvp (argv[0], argv);
+ execvp (argv[0], argv);
- /* If the exec fails, try to dump anyway. */
- perror ("execvp");
- }
+ /* If the exec fails, try to dump anyway. */
+ perror ("execvp");
}
#endif /* HAVE_PERSONALITY_LINUX32 */
}
#endif
-#ifdef NeXT
- {
- extern int malloc_cookie;
- /* This helps out unexnext.c. */
- if (initialized)
- if (malloc_jumpstart (malloc_cookie) != 0)
- printf ("malloc jumpstart failed!\n");
- }
-#endif /* NeXT */
-
-#ifdef MAC_OSX
- /* Skip process serial number passed in the form -psn_x_y as
- command-line argument. The WindowServer adds this option when
- Emacs is invoked from the Finder or by the `open' command. In
- these cases, the working directory becomes `/', so we change it
- to the user's home directory. */
- if (argc > skip_args + 1 && strncmp (argv[skip_args+1], "-psn_", 5) == 0)
- {
- chdir (getenv ("HOME"));
- skip_args++;
- }
-#endif /* MAC_OSX */
-
-#ifdef VMS
- /* If -map specified, map the data file in. */
- {
- char *file;
- if (argmatch (argv, argc, "-map", "--map-data", 3, &file, &skip_args))
- mapin_data (file);
- }
-
-#ifdef LINK_CRTL_SHARE
-#ifdef SHARABLE_LIB_BUG
- /* Bletcherous shared libraries! */
- if (!stdin)
- stdin = fdopen (0, "r");
- if (!stdout)
- stdout = fdopen (1, "w");
- if (!stderr)
- stderr = fdopen (2, "w");
- if (!environ)
- environ = envp;
-#endif /* SHARABLE_LIB_BUG */
-#endif /* LINK_CRTL_SHARE */
-#endif /* VMS */
-
#if defined (HAVE_SETRLIMIT) && defined (RLIMIT_STACK)
/* Extend the stack space available.
Don't do that if dumping, since some systems (e.g. DJGPP)
/* Record (approximately) where the stack begins. */
stack_bottom = &stack_bottom_variable;
-#ifdef USG_SHARED_LIBRARIES
- if (bss_end)
- brk ((void *)bss_end);
-#endif
-
clearerr (stdin);
#ifndef SYSTEM_MALLOC
# endif /* not SYNC_INPUT */
#endif /* not SYSTEM_MALLOC */
-#ifdef HAVE_GTK_AND_PTHREAD
+#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
main_thread = pthread_self ();
-#endif /* HAVE_GTK_AND_PTHREAD */
+#endif /* FORWARD_SIGNAL_TO_MAIN_THREAD */
#if defined (MSDOS) || defined (WINDOWSNT)
/* We do all file input/output as binary files. When we need to translate
if (argmatch (argv, argc, "-script", "--script", 3, &junk, &skip_args))
{
noninteractive = 1; /* Set batch mode. */
- /* Convert --script to --scriptload, un-skip it, and sort again
+ /* Convert --script to -scriptload, un-skip it, and sort again
so that it will be handled in proper sequence. */
+ /* FIXME broken for --script=FILE - is that supposed to work? */
argv[skip_args - 1] = "-scriptload";
skip_args -= 2;
sort_args (argc, argv);
exit (0);
}
+ if (argmatch (argv, argc, "-daemon", "--daemon", 5, NULL, &skip_args)
+ || argmatch (argv, argc, "-daemon", "--daemon", 5, &dname_arg, &skip_args))
+ {
+#ifndef DOS_NT
+ pid_t f;
+
+ /* Start as a daemon: fork a new child process which will run the
+ rest of the initialization code, then exit.
+
+ Detaching a daemon requires the following steps:
+ - fork
+ - setsid
+ - exit the parent
+ - close the tty file-descriptors
+
+ We only want to do the last 2 steps once the daemon is ready to
+ serve requests, i.e. after loading .emacs (initialization).
+ OTOH initialization may start subprocesses (e.g. ispell) and these
+ should be run from the proper process (the one that will end up
+ running as daemon) and with the proper "session id" in order for
+ them to keep working after detaching, so fork and setsid need to be
+ performed before initialization.
+
+ We want to avoid exiting before the server socket is ready, so
+ use a pipe for synchronization. The parent waits for the child
+ to close its end of the pipe (using `daemon-initialized')
+ before exiting. */
+ if (pipe (daemon_pipe) == -1)
+ {
+ fprintf (stderr, "Cannot pipe!\n");
+ exit (1);
+ }
+
+ f = fork ();
+ if (f > 0)
+ {
+ int retval;
+ char buf[1];
+
+ /* Close unused writing end of the pipe. */
+ close (daemon_pipe[1]);
+
+ /* Just wait for the child to close its end of the pipe. */
+ do
+ {
+ retval = read (daemon_pipe[0], &buf, 1);
+ }
+ while (retval == -1 && errno == EINTR);
+
+ if (retval < 0)
+ {
+ fprintf (stderr, "Error reading status from child\n");
+ exit (1);
+ }
+ else if (retval == 0)
+ {
+ fprintf (stderr, "Error: server did not start correctly\n");
+ exit (1);
+ }
+
+ close (daemon_pipe[0]);
+ exit (0);
+ }
+ if (f < 0)
+ {
+ fprintf (stderr, "Cannot fork!\n");
+ exit (1);
+ }
+
+ if (dname_arg)
+ daemon_name = xstrdup (dname_arg);
+ /* Close unused reading end of the pipe. */
+ close (daemon_pipe[0]);
+ /* Make sure that the used end of the pipe is closed on exec, so
+ that it is not accessible to programs started from .emacs. */
+ fcntl (daemon_pipe[1], F_SETFD, FD_CLOEXEC);
+
+#ifdef HAVE_SETSID
+ setsid();
+#endif
+#else /* DOS_NT */
+ fprintf (stderr, "This platform does not support the -daemon flag.\n");
+ exit (1);
+#endif /* DOS_NT */
+ }
+
if (! noninteractive)
{
#ifdef BSD_PGRPS
CANNOT_DUMP is defined. */
syms_of_keyboard ();
-#ifdef MAC_OS8
- /* init_window_once calls make_terminal_frame which on Mac OS
- creates a full-fledge output_mac type frame. This does not
- work correctly before syms_of_textprop, syms_of_macfns,
- syms_of_ccl, syms_of_fontset, syms_of_xterm, syms_of_search,
- syms_of_frame, mac_term_init, and init_keyboard have already
- been called. */
- syms_of_textprop ();
- syms_of_macfns ();
- syms_of_ccl ();
- syms_of_fontset ();
- syms_of_macterm ();
- syms_of_macmenu ();
- syms_of_macselect ();
- syms_of_search ();
- syms_of_frame ();
-
- init_atimer ();
- mac_term_init (build_string ("Mac"), NULL, NULL);
- init_keyboard ();
-#endif
/* Called before syms_of_fileio, because it sets up Qerror_condition. */
syms_of_data ();
syms_of_fileio ();
no_loadup
= argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args);
-#ifdef USE_FONT_BACKEND
- enable_font_backend = 1;
- if (argmatch (argv, argc, "-enable-font-backend", "--enable-font-backend",
- 4, NULL, &skip_args))
- enable_font_backend = 1;
- else if (argmatch (argv, argc,
- "-disable-font-backend", "--disable-font-backend",
- 4, NULL, &skip_args))
- enable_font_backend = 0;
-#endif /* USE_FONT_BACKEND */
+#ifdef HAVE_NS
+ ns_alloc_autorelease_pool();
+ if (!noninteractive)
+ {
+ char *tmp;
+ display_arg = 4;
+#ifdef NS_IMPL_COCOA
+ if (skip_args < argc)
+ {
+ if (!strncmp(argv[skip_args], "-psn", 4))
+ {
+ skip_args += 1;
+ chdir (getenv ("HOME"));
+ }
+ else if (skip_args+1 < argc && !strncmp(argv[skip_args+1], "-psn", 4))
+ {
+ skip_args += 2;
+ chdir (getenv ("HOME"));
+ }
+ }
+#endif
+ /* This used for remote operation.. not fully implemented yet. */
+ if (argmatch (argv, argc, "-_NSMachLaunch", 0, 3, &tmp, &skip_args))
+ display_arg = 4;
+ else if (argmatch (argv, argc, "-MachLaunch", 0, 3, &tmp, &skip_args))
+ display_arg = 4;
+ else if (argmatch (argv, argc, "-macosx", 0, 2, NULL, &skip_args))
+ display_arg = 4;
+ else if (argmatch (argv, argc, "-NSHost", 0, 3, &tmp, &skip_args))
+ display_arg = 4;
+ }
+#endif /* HAVE_NS */
#ifdef HAVE_X_WINDOWS
/* Stupid kludge to catch command-line display spec. We can't
init_ntproc (); /* must precede init_editfns. */
#endif
-#if defined (MAC_OSX) && defined (HAVE_CARBON)
+#ifdef HAVE_NS
+#ifndef CANNOT_DUMP
if (initialized)
- init_mac_osx_environment ();
+#endif
+ ns_init_paths ();
#endif
/* egetenv is a pretty low-level facility, which may get called in
if this is not done. Do it after set_global_environment so that we
don't pollute Vglobal_environment. */
/* Setting LANG here will defeat the startup locale processing... */
-#ifdef AIX3_2
+#ifdef AIX
putenv ("LANG=C");
#endif
/* The basic levels of Lisp must come first. */
/* And data must come first of all
for the sake of symbols like error-message. */
- /* Called before init_window_once for Mac OS Classic. */
syms_of_data ();
syms_of_chartab ();
syms_of_lread ();
#endif
syms_of_textprop ();
syms_of_composite ();
-#ifdef VMS
- syms_of_vmsproc ();
-#endif /* VMS */
#ifdef WINDOWSNT
syms_of_ntproc ();
#endif /* WINDOWSNT */
syms_of_window ();
syms_of_xdisp ();
-#ifdef HAVE_WINDOW_SYSTEM
syms_of_font ();
+#ifdef HAVE_WINDOW_SYSTEM
syms_of_fringe ();
syms_of_image ();
#endif /* HAVE_WINDOW_SYSTEM */
#ifdef HAVE_X_WINDOWS
syms_of_xterm ();
syms_of_xfns ();
+ syms_of_xmenu ();
syms_of_fontset ();
#ifdef HAVE_X_SM
syms_of_xsmfns ();
#endif
#endif /* HAVE_X_WINDOWS */
-#ifndef HAVE_NTGUI
-#ifndef MAC_OS
- /* Called before init_window_once for Mac OS Classic. */
- syms_of_xmenu ();
-#endif
-#endif
+ syms_of_menu ();
#ifdef HAVE_NTGUI
syms_of_w32term ();
syms_of_fontset ();
#endif /* HAVE_NTGUI */
-#if defined (MAC_OSX) && defined (HAVE_CARBON)
- syms_of_macterm ();
- syms_of_macfns ();
- syms_of_macmenu ();
- syms_of_macselect ();
+#ifdef MSDOS
+ syms_of_xmenu ();
+#endif /* MSDOS */
+
+#ifdef HAVE_NS
+ syms_of_nsterm ();
+ syms_of_nsfns ();
+ syms_of_nsmenu ();
+ syms_of_nsselect ();
syms_of_fontset ();
-#endif /* MAC_OSX && HAVE_CARBON */
+#endif /* HAVE_NS */
#ifdef HAVE_DBUS
syms_of_dbusbind ();
keys_of_buffer ();
keys_of_keyboard ();
keys_of_keymap ();
- keys_of_minibuf ();
keys_of_window ();
}
else
init_editfns (); /* init_process uses Voperating_system_release. */
init_process (); /* init_display uses add_keyboard_wait_descriptor. */
init_keyboard (); /* This too must precede init_sys_modes. */
-#ifdef VMS
- init_vmsproc (); /* And this too. */
-#endif /* VMS */
if (!noninteractive)
- {
-#ifdef VMS
- init_vms_input ();/* init_display calls get_tty_size, that needs this. */
-#endif /* VMS */
- init_display (); /* Determine terminal type. Calls init_sys_modes. */
- }
+ init_display (); /* Determine terminal type. Calls init_sys_modes. */
init_fns ();
init_xdisp ();
#ifdef HAVE_WINDOW_SYSTEM
#endif /* HAVE_WINDOW_SYSTEM */
init_macros ();
init_floatfns ();
-#ifdef VMS
- init_vmsfns ();
-#endif /* VMS */
#ifdef HAVE_SOUND
init_sound ();
#endif
{ "-version", "--version", 150, 0 },
#ifdef HAVE_SHM
{ "-nl", "--no-shared-memory", 140, 0 },
-#endif
-#ifdef VMS
- { "-map", "--map-data", 130, 0 },
#endif
{ "-t", "--terminal", 120, 1 },
{ "-nw", "--no-window-system", 110, 0 },
{ "-nw", "--no-windows", 110, 0 },
{ "-batch", "--batch", 100, 0 },
{ "-script", "--script", 100, 1 },
+ { "-daemon", "--daemon", 99, 0 },
{ "-help", "--help", 90, 0 },
{ "-no-unibyte", "--no-unibyte", 83, 0 },
{ "-multibyte", "--multibyte", 82, 0 },
{ "-unibyte", "--unibyte", 81, 0 },
{ "-no-multibyte", "--no-multibyte", 80, 0 },
{ "-nl", "--no-loadup", 70, 0 },
- { "-enable-font-backend", "--enable-font-backend", 65, 0 },
- { "-disable-font-backend", "--disable-font-backend", 65, 0 },
/* -d must come last before the options handled in startup.el. */
{ "-d", "--display", 60, 1 },
{ "-display", 0, 60, 1 },
{ "-color", "--color", 5, 0},
{ "-no-splash", "--no-splash", 3, 0 },
{ "-no-desktop", "--no-desktop", 3, 0 },
+#ifdef HAVE_NS
+ { "-NSAutoLaunch", 0, 5, 1 },
+ { "-NXAutoLaunch", 0, 5, 1 },
+ { "-disable-font-backend", "--disable-font-backend", 65, 0 },
+ { "-_NSMachLaunch", 0, 85, 1 },
+ { "-MachLaunch", 0, 85, 1 },
+ { "-macosx", 0, 85, 0 },
+ { "-NSHost", 0, 85, 1 },
+#endif
/* These have the same priority as ordinary file name args,
so they are not reordered with respect to those. */
{ "-L", "--directory", 0, 1 },
{ "-directory", 0, 0, 1 },
{ "-l", "--load", 0, 1 },
{ "-load", 0, 0, 1 },
- { "-scriptload", "--scriptload", 0, 1 },
+ /* This has no longname, because using --scriptload confuses sort_args,
+ because then the --script long option seems to match twice; ie
+ you can't have a long option which is a prefix of another long
+ option. In any case, this is entirely an internal option. */
+ { "-scriptload", NULL, 0, 1 },
{ "-f", "--funcall", 0, 1 },
{ "-funcall", 0, 0, 1 },
{ "-eval", "--eval", 0, 1 },
{ "-visit", "--visit", 0, 1 },
{ "-file", "--file", 0, 1 },
{ "-insert", "--insert", 0, 1 },
+#ifdef HAVE_NS
+ { "-NXOpen", 0, 0, 1 },
+ { "-NXOpenTemp", 0, 0, 1 },
+ { "-NSOpen", 0, 0, 1 },
+ { "-NSOpenTemp", 0, 0, 1 },
+ { "-GSFilePath", 0, 0, 1 },
+#endif
/* This should be processed after ordinary file name args and the like. */
{ "-kill", "--kill", -10, 0 },
};
fatal ("Option `%s' requires an argument\n", argv[from]);
from += options[from];
}
+ /* FIXME When match < 0, shouldn't there be some error,
+ or at least indication to the user that there was a
+ problem? */
}
done: ;
}
UNGCPRO;
-/* Is it really necessary to do this deassign
- when we are going to exit anyway? */
-/* #ifdef VMS
- stop_vms_input ();
- #endif */
-
shut_down_emacs (0, 0, STRINGP (arg) ? arg : Qnil);
/* If we have an auto-save list file,
unlock_all_files ();
#endif
-#ifdef VMS
- kill_vms_processes ();
-#endif
-
#if 0 /* This triggers a bug in XCloseDisplay and is not needed. */
#ifdef HAVE_X_WINDOWS
/* It's not safe to call intern here. Maybe we are crashing. */
#ifdef MSDOS
dos_cleanup ();
#endif
+
+#ifdef HAVE_NS
+ ns_term_shutdown (sig);
+#endif
}
#endif
fflush (stdout);
-#ifdef VMS
- mapout_data (SDATA (filename));
-#else
/* Tell malloc where start of impure now is. */
/* Also arrange for warnings when nearly out of space. */
#ifndef SYSTEM_MALLOC
#ifdef DOUG_LEA_MALLOC
free (malloc_state_ptr);
#endif
-#endif /* not VMS */
Vpurify_flag = tem;
return Fnreverse (lpath);
}
+DEFUN ("daemonp", Fdaemonp, Sdaemonp, 0, 0, 0,
+ doc: /* Return non-nil if the current emacs process is a daemon.
+If the daemon was given a name argument, return that name. */)
+ ()
+{
+ if (IS_DAEMON)
+ if (daemon_name)
+ return build_string (daemon_name);
+ else
+ return Qt;
+ else
+ return Qnil;
+}
+
+DEFUN ("daemon-initialized", Fdaemon_initialized, Sdaemon_initialized, 0, 0, 0,
+ doc: /* Mark the Emacs daemon as being initialized.
+This finishes the daemonization process by doing the other half of detaching
+from the parent process and its tty file descriptors. */)
+ ()
+{
+ int nfd;
+
+ if (!IS_DAEMON)
+ error ("This function can only be called if emacs is run as a daemon");
+
+ if (daemon_pipe[1] < 0)
+ error ("The daemon has already been initialized");
+
+ if (NILP (Vafter_init_time))
+ error ("This function can only be called after loading the init files");
+
+ /* Get rid of stdin, stdout and stderr. */
+ nfd = open ("/dev/null", O_RDWR);
+ dup2 (nfd, 0);
+ dup2 (nfd, 1);
+ dup2 (nfd, 2);
+ close (nfd);
+
+ /* Closing the pipe will notify the parent that it can exit.
+ FIXME: In case some other process inherited the pipe, closing it here
+ won't notify the parent because it's still open elsewhere, so we
+ additionally send a byte, just to make sure the parent really exits.
+ Instead, we should probably close the pipe in start-process and
+ call-process to make sure the pipe is never inherited by
+ subprocesses. */
+ write (daemon_pipe[1], "\n", 1);
+ close (daemon_pipe[1]);
+ /* Set it to an invalid value so we know we've already run this function. */
+ daemon_pipe[1] = -1;
+ return Qt;
+}
+
void
syms_of_emacs ()
{
defsubr (&Sinvocation_name);
defsubr (&Sinvocation_directory);
+ defsubr (&Sdaemonp);
+ defsubr (&Sdaemon_initialized);
DEFVAR_LISP ("command-line-args", &Vcommand_line_args,
doc: /* Args passed by shell to Emacs, as a list of strings.
DEFVAR_LISP ("system-type", &Vsystem_type,
doc: /* Value is symbol indicating type of operating system you are using.
Special values:
+ `gnu' compiled for a GNU Hurd system.
`gnu/linux' compiled for a GNU/Linux system.
`darwin' compiled for Darwin (GNU-Darwin, Mac OS X, ...).
- `macos' compiled for Mac OS 9.
`ms-dos' compiled as an MS-DOS application.
`windows-nt' compiled as a native W32 application.
`cygwin' compiled using the Cygwin library.
- `vax-vms' or
- `axp-vms' compiled for a (Open)VMS system.
Anything else indicates some sort of Unix system. */);
Vsystem_type = intern (SYSTEM_TYPE);
DEFVAR_LISP ("previous-system-time-locale", &Vprevious_system_time_locale,
doc: /* Most recently used system locale for time. */);
Vprevious_system_time_locale = Qnil;
+
+ DEFVAR_LISP ("before-init-time", &Vbefore_init_time,
+ doc: /* Value of `current-time' before Emacs begins initialization. */);
+ Vbefore_init_time = Qnil;
+
+ DEFVAR_LISP ("after-init-time", &Vafter_init_time,
+ doc: /* Value of `current-time' after loading the init files.
+This is nil during initialization. */);
+ Vafter_init_time = Qnil;
+
+ /* Make sure IS_DAEMON starts up as false. */
+ daemon_pipe[1] = 0;
}
/* arch-tag: 7bfd356a-c720-4612-8ab6-aa4222931c2e