X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/a09a5b5bf7a958d5617b6e79fdc361eb2d35335c..9250c1e82544edcc8bf62ec9a5149e575fa3c73f:/src/emacs.c diff --git a/src/emacs.c b/src/emacs.c index d6ce9b1625..3e94f0fc6c 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1,14 +1,14 @@ /* Fully extensible Emacs, running on Unix, intended for GNU. Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1997, 1998, 1999, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. 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 @@ -16,9 +16,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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 . */ #include @@ -29,10 +27,6 @@ Boston, MA 02110-1301, USA. */ #include #include -#ifdef VMS -#include -#endif - #ifdef HAVE_UNISTD_H #include #endif @@ -48,6 +42,11 @@ Boston, MA 02110-1301, USA. */ #include "w32heap.h" /* for prototype of sbrk */ #endif +#ifdef NS_IMPL_GNUSTEP +/* At least under Debian, GSConfig is in a subdirectory. --Stef */ +#include +#endif + #include "lisp.h" #include "commands.h" #include "intervals.h" @@ -100,14 +99,14 @@ int gdb_use_lsb = 1; #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; #endif EMACS_INT gdb_valbits = VALBITS; EMACS_INT gdb_gctypebits = GCTYPEBITS; -#ifdef DATA_SEG_BITS +#if defined (DATA_SEG_BITS) && ! defined (USE_LSB_TAG) EMACS_INT gdb_data_seg_bits = DATA_SEG_BITS; #else EMACS_INT gdb_data_seg_bits = 0; @@ -132,6 +131,9 @@ Lisp_Object Vinvocation_directory; 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; @@ -195,11 +197,15 @@ int running_asynch_code; 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 +#ifdef HAVE_NS +extern char ns_no_defaults; +#endif + /* An address near the bottom of the stack. Tells GC how to save a copy of the stack. */ char *stack_bottom; @@ -210,8 +216,8 @@ static void *my_heap_start; /* 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) @@ -223,13 +229,6 @@ extern Lisp_Object Vauto_save_list_file_name; 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; @@ -240,6 +239,13 @@ 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; @@ -262,8 +268,8 @@ read the main documentation for these command-line arguments.\n\ 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\ @@ -283,8 +289,8 @@ Initialization options:\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\ @@ -355,10 +361,10 @@ int fatal_error_in_progress; 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 @@ -383,9 +389,6 @@ fatal_error_signal (sig) 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 @@ -398,7 +401,6 @@ fatal_error_signal (sig) fatal_error_signal_hook (); kill (getpid (), fatal_error_code); -#endif /* not VMS */ } #ifdef SIGDANGER @@ -596,14 +598,6 @@ DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory, } -#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. */ @@ -787,22 +781,10 @@ bug_reporting_address () 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; @@ -818,6 +800,10 @@ main (argc, argv #endif int no_loadup = 0; char *junk = 0; + char *dname_arg = 0; +#ifdef NS_IMPL_COCOA + char dname_arg2[80]; +#endif #if GC_MARK_STACK extern Lisp_Object *stack_base; @@ -836,6 +822,7 @@ main (argc, argv } #ifdef LINUX_SBRK_BUG + /* This is only used GNU/LINUX running on alpha when using libc5 */ __sbrk (1); #endif @@ -844,7 +831,8 @@ main (argc, argv 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 @@ -885,29 +873,24 @@ main (argc, argv } #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 */ @@ -928,52 +911,6 @@ main (argc, argv } #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) @@ -1017,11 +954,6 @@ main (argc, argv /* 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 @@ -1038,9 +970,9 @@ main (argc, argv # 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 @@ -1133,10 +1065,10 @@ main (argc, argv if (argmatch (argv, argc, "-script", "--script", 3, &junk, &skip_args)) { noninteractive = 1; /* Set batch mode. */ - /* Convert --script to -internal-script, 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] = "-internal-script"; + argv[skip_args - 1] = "-scriptload"; skip_args -= 2; sort_args (argc, argv); } @@ -1150,6 +1082,141 @@ main (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); + } + +#ifndef NS_IMPL_COCOA + f = fork (); +#else /* NS_IMPL_COCOA */ + /* Under Cocoa we must do fork+exec as CoreFoundation lib fails in + forked process: http://developer.apple.com/ReleaseNotes/ + CoreFoundation/CoreFoundation.html) + We mark being in the exec'd process by a daemon name argument of + form "--daemon=\nFD0,FD1\nNAME" where FD are the pipe file descriptors, + NAME is the original daemon name, if any. */ + if (!dname_arg || !strchr (dname_arg, '\n')) + f = fork (); /* in orig */ + else + f = 0; /* in exec'd */ +#endif /* NS_IMPL_COCOA */ + 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); + } + +#ifdef NS_IMPL_COCOA + { + /* In orig process, forked as child, OR in exec'd. */ + if (!dname_arg || !strchr (dname_arg, '\n')) + { /* In orig, child: now exec w/special daemon name. */ + char fdStr[80]; + + if (dname_arg && strlen (dname_arg) > 70) + { + fprintf (stderr, "daemon: child name too long\n"); + exit (1); + } + + sprintf (fdStr, "--daemon=\n%d,%d\n%s", daemon_pipe[0], + daemon_pipe[1], dname_arg ? dname_arg : ""); + argv[skip_args] = fdStr; + + execv (argv[0], argv); + fprintf (stderr, "emacs daemon: exec failed: %d\t%d\n", errno); + exit (1); + } + + /* In exec'd: parse special dname into pipe and name info. */ + if (!dname_arg || !strchr (dname_arg, '\n') + || strlen (dname_arg) < 1 || strlen (dname_arg) > 70) + { + fprintf (stderr, "emacs daemon: daemon name absent or too long\n"); + exit(1); + } + dname_arg2[0] = '\0'; + sscanf (dname_arg, "\n%d,%d\n%s", &(daemon_pipe[0]), &(daemon_pipe[1]), + dname_arg2); + dname_arg = strlen (dname_arg2) ? dname_arg2 : NULL; + } +#endif /* NS_IMPL_COCOA */ + + 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 @@ -1306,27 +1373,6 @@ main (argc, argv 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 (); @@ -1426,12 +1472,48 @@ main (argc, argv no_loadup = argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args); -#ifdef USE_FONT_BACKEND - enable_font_backend = 1; - 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; + if (argmatch (argv, argc, "-q", "--no-init-file", 6, NULL, &skip_args)) + { + ns_no_defaults = 1; + skip_args--; + } + if (argmatch (argv, argc, "-Q", "--quick", 5, NULL, &skip_args)) + { + ns_no_defaults = 1; + skip_args--; + } +#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 @@ -1505,9 +1587,11 @@ main (argc, argv 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 @@ -1518,7 +1602,7 @@ main (argc, argv 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 @@ -1548,7 +1632,6 @@ main (argc, argv /* 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 (); @@ -1595,22 +1678,20 @@ main (argc, argv #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 (); @@ -1620,12 +1701,7 @@ main (argc, argv #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 (); @@ -1635,13 +1711,17 @@ main (argc, argv 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 (); @@ -1660,7 +1740,6 @@ main (argc, argv keys_of_buffer (); keys_of_keyboard (); keys_of_keymap (); - keys_of_minibuf (); keys_of_window (); } else @@ -1679,16 +1758,8 @@ main (argc, argv 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 @@ -1697,9 +1768,6 @@ main (argc, argv #endif /* HAVE_WINDOW_SYSTEM */ init_macros (); init_floatfns (); -#ifdef VMS - init_vmsfns (); -#endif /* VMS */ #ifdef HAVE_SOUND init_sound (); #endif @@ -1804,22 +1872,19 @@ struct standard_args standard_args[] = { "-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 }, - { "-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 }, @@ -1866,17 +1931,26 @@ struct standard_args standard_args[] = { "-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 }, - /* This was --scriptload, but that 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. */ - { "-internal-script", "--internal-script", 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 }, @@ -1885,6 +1959,13 @@ struct standard_args standard_args[] = { "-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 }, }; @@ -2071,12 +2152,6 @@ all of which are called before Emacs is actually killed. */) 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, @@ -2144,10 +2219,6 @@ shut_down_emacs (sig, no_x, stuff) 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. */ @@ -2181,6 +2252,10 @@ shut_down_emacs (sig, no_x, stuff) #ifdef MSDOS dos_cleanup (); #endif + +#ifdef HAVE_NS + ns_term_shutdown (sig); +#endif } @@ -2280,9 +2355,6 @@ You must run Emacs in batch mode in order to dump it. */) #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 @@ -2313,7 +2385,6 @@ You must run Emacs in batch mode in order to dump it. */) #ifdef DOUG_LEA_MALLOC free (malloc_state_ptr); #endif -#endif /* not VMS */ Vpurify_flag = tem; @@ -2439,6 +2510,58 @@ decode_env_path (evarname, defalt) 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 () { @@ -2457,6 +2580,8 @@ 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. @@ -2465,14 +2590,12 @@ Many arguments are deleted from the list as they are processed. */); 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); @@ -2547,6 +2670,18 @@ was found. */); 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