X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/938d65136b6d8c4ea91313216c873d2084be4240..1dd4f26ab6c1f14628d9fcf03b0cca7e54d52302:/src/emacs.c diff --git a/src/emacs.c b/src/emacs.c index b9654d0e03..aaf058e4a8 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1,7 +1,7 @@ /* Fully extensible Emacs, running on Unix, intended for GNU. -Copyright (C) 1985-1987, 1993-1995, 1997-1999, 2001-2014 - Free Software Foundation, Inc. +Copyright (C) 1985-1987, 1993-1995, 1997-1999, 2001-2016 Free Software +Foundation, Inc. This file is part of GNU Emacs. @@ -22,6 +22,7 @@ along with GNU Emacs. If not, see . */ #include #include +#include #include #include @@ -59,18 +60,12 @@ along with GNU Emacs. If not, see . */ #include TERM_HEADER #endif /* HAVE_WINDOW_SYSTEM */ -#ifdef NS_IMPL_GNUSTEP -/* At least under Debian, GSConfig is in a subdirectory. --Stef */ -#include -#endif - -#include "commands.h" +#include "coding.h" #include "intervals.h" #include "character.h" #include "buffer.h" #include "window.h" -#include "systty.h" #include "atimer.h" #include "blockinput.h" #include "syssignal.h" @@ -87,6 +82,7 @@ along with GNU Emacs. If not, see . */ #include "syntax.h" #include "sysselect.h" #include "systime.h" +#include "puresize.h" #include "gnutls.h" @@ -100,6 +96,10 @@ extern void moncontrol (int mode); #include #endif +#if HAVE_WCHAR_H +# include +#endif + #ifdef HAVE_SETRLIMIT #include #include @@ -148,13 +148,6 @@ static bool malloc_using_checking; extern void malloc_enable_thread (void); #endif -Lisp_Object Qfile_name_handler_alist; - -Lisp_Object Qrisky_local_variable; - -Lisp_Object Qkill_emacs; -static Lisp_Object Qkill_emacs_hook; - /* If true, Emacs should not attempt to use a window-specific code, but instead should use the virtual terminal under which it was started. */ bool inhibit_window_system; @@ -207,9 +200,13 @@ bool no_site_lisp; /* Name for the server started by the daemon.*/ static char *daemon_name; +#ifndef WINDOWSNT /* Pipe used to send exit notification to the daemon parent at startup. */ int daemon_pipe[2]; +#else +HANDLE w32_daemon_event; +#endif /* Save argv and argc. */ char **initial_argv; @@ -243,8 +240,9 @@ Initialization options:\n\ "\ --no-desktop do not load a saved desktop\n\ --no-init-file, -q load neither ~/.emacs nor default.el\n\ ---no-shared-memory, -nl do not use shared memory\n\ +--no-loadup, -nl do not load loadup.el into bare Emacs\n\ --no-site-file do not load site-start.el\n\ +--no-x-resources do not load X resources\n\ --no-site-lisp, -nsl do not add site-lisp directories to load-path\n\ --no-splash do not display a splash screen on startup\n\ --no-window-system, -nw do not communicate with X, ignoring $DISPLAY\n\ @@ -252,6 +250,7 @@ Initialization options:\n\ "\ --quick, -Q equivalent to:\n\ -q --no-site-file --no-site-lisp --no-splash\n\ + --no-x-resources\n\ --script FILE run FILE as an Emacs Lisp script\n\ --terminal, -t DEVICE use DEVICE for terminal I/O\n\ --user, -u USER load ~USER/.emacs instead of your own\n\ @@ -350,6 +349,19 @@ setlocale (int cat, char const *locale) } #endif +/* True if the current system locale uses UTF-8 encoding. */ +static bool +using_utf8 (void) +{ +#ifdef HAVE_WCHAR_H + wchar_t wc; + mbstate_t mbs = { 0 }; + return mbrtowc (&wc, "\xc4\x80", 2, &mbs) == 2 && wc == 0x100; +#else + return false; +#endif +} + /* Report a fatal error due to signal SIG, output a backtrace of at most BACKTRACE_LIMIT lines, and exit. */ @@ -357,18 +369,21 @@ _Noreturn void terminate_due_to_signal (int sig, int backtrace_limit) { signal (sig, SIG_DFL); - totally_unblock_input (); - /* If fatal error occurs in code below, avoid infinite recursion. */ - if (! fatal_error_in_progress) + if (attempt_orderly_shutdown_on_fatal_signal) { - fatal_error_in_progress = 1; + /* If fatal error occurs in code below, avoid infinite recursion. */ + if (! fatal_error_in_progress) + { + fatal_error_in_progress = 1; - if (sig == SIGTERM || sig == SIGHUP || sig == SIGINT) - Fkill_emacs (make_number (sig)); + totally_unblock_input (); + if (sig == SIGTERM || sig == SIGHUP || sig == SIGINT) + Fkill_emacs (make_number (sig)); - shut_down_emacs (sig, Qnil); - emacs_backtrace (backtrace_limit); + shut_down_emacs (sig, Qnil); + emacs_backtrace (backtrace_limit); + } } /* Signal the same code; this time it will really be fatal. @@ -703,9 +718,7 @@ close_output_streams (void) int main (int argc, char **argv) { -#if GC_MARK_STACK Lisp_Object dummy; -#endif char stack_bottom_variable; bool do_initial_setlocale; bool dumping; @@ -724,9 +737,7 @@ main (int argc, char **argv) /* If we use --chdir, this records the original directory. */ char *original_pwd = 0; -#if GC_MARK_STACK stack_base = &dummy; -#endif #ifndef CANNOT_DUMP might_dump = !initialized; @@ -753,6 +764,9 @@ main (int argc, char **argv) names between UTF-8 and the system's ANSI codepage. */ maybe_load_unicows_dll (); #endif + /* This has to be done before module_init is called below, so that + the latter could use the thread ID of the main thread. */ + w32_init_main_thread (); #endif #ifdef RUN_TIME_REMAP @@ -768,6 +782,10 @@ main (int argc, char **argv) atexit (close_output_streams); +#ifdef HAVE_MODULES + module_init (); +#endif + sort_args (argc, argv); argc = 0; while (argv[argc]) argc++; @@ -782,12 +800,12 @@ main (int argc, char **argv) tem2 = Fsymbol_value (intern_c_string ("emacs-copyright")); if (!STRINGP (tem)) { - fprintf (stderr, "Invalid value of `emacs-version'\n"); + fprintf (stderr, "Invalid value of 'emacs-version'\n"); exit (1); } if (!STRINGP (tem2)) { - fprintf (stderr, "Invalid value of `emacs-copyright'\n"); + fprintf (stderr, "Invalid value of 'emacs-copyright'\n"); exit (1); } else @@ -852,10 +870,13 @@ main (int argc, char **argv) } #endif /* HAVE_PERSONALITY_LINUX32 */ -#if defined (HAVE_SETRLIMIT) && defined (RLIMIT_STACK) - /* Extend the stack space available. - Don't do that if dumping, since some systems (e.g. DJGPP) - might define a smaller stack limit at that time. */ +#if defined (HAVE_SETRLIMIT) && defined (RLIMIT_STACK) && !defined (CYGWIN) + /* Extend the stack space available. Don't do that if dumping, + since some systems (e.g. DJGPP) might define a smaller stack + limit at that time. And it's not needed on Cygwin, since emacs + is built with an 8MB stack. Moreover, the setrlimit call can + cause problems on Cygwin + (https://www.cygwin.com/ml/cygwin/2015-07/msg00096.html). */ if (1 #ifndef CANNOT_DUMP && (!noninteractive || initialized) @@ -889,13 +910,15 @@ main (int argc, char **argv) setrlimit (RLIMIT_STACK, &rlim); } -#endif /* HAVE_SETRLIMIT and RLIMIT_STACK */ +#endif /* HAVE_SETRLIMIT and RLIMIT_STACK and not CYGWIN */ /* Record (approximately) where the stack begins. */ stack_bottom = &stack_bottom_variable; clearerr (stdin); + emacs_backtrace (-1); + #if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC /* Arrange to get warning messages as memory fills up. */ memory_warnings (0, malloc_warning); @@ -925,6 +948,7 @@ main (int argc, char **argv) fixup_locale must wait until later, since it builds strings. */ if (do_initial_setlocale) setlocale (LC_ALL, ""); + text_quoting_flag = using_utf8 (); inhibit_window_system = 0; @@ -992,8 +1016,12 @@ main (int argc, char **argv) exit (0); } +#ifndef WINDOWSNT /* Make sure IS_DAEMON starts up as false. */ daemon_pipe[1] = 0; +#else + w32_daemon_event = NULL; +#endif if (argmatch (argv, argc, "-daemon", "--daemon", 5, NULL, &skip_args) || argmatch (argv, argc, "-daemon", "--daemon", 5, &dname_arg, &skip_args)) @@ -1117,16 +1145,25 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem } #endif /* DAEMON_MUST_EXEC */ - if (dname_arg) - daemon_name = xstrdup (dname_arg); /* Close unused reading end of the pipe. */ emacs_close (daemon_pipe[0]); setsid (); -#else /* DOS_NT */ +#elif defined(WINDOWSNT) + /* Indicate that we want daemon mode. */ + w32_daemon_event = CreateEvent (NULL, TRUE, FALSE, W32_DAEMON_EVENT); + if (w32_daemon_event == NULL) + { + fprintf (stderr, "Couldn't create MS-Windows event for daemon: %s\n", + w32_strerror (0)); + exit (1); + } +#else /* MSDOS */ fprintf (stderr, "This platform does not support the -daemon flag.\n"); exit (1); -#endif /* DOS_NT */ +#endif /* MSDOS */ + if (dname_arg) + daemon_name = xstrdup (dname_arg); } #if defined HAVE_PTHREAD && !defined SYSTEM_MALLOC \ @@ -1323,6 +1360,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem tzset (); #endif /* MSDOS */ +#ifdef HAVE_KQUEUE + globals_of_kqueue (); +#endif + #ifdef HAVE_GFILENOTIFY globals_of_gfilenotify (); #endif @@ -1423,6 +1464,11 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem syms_of_terminal (); syms_of_term (); syms_of_undo (); + +#ifdef HAVE_MODULES + syms_of_module (); +#endif + #ifdef HAVE_SOUND syms_of_sound (); #endif @@ -1493,14 +1539,18 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem syms_of_gnutls (); -#ifdef HAVE_GFILENOTIFY - syms_of_gfilenotify (); -#endif /* HAVE_GFILENOTIFY */ - #ifdef HAVE_INOTIFY syms_of_inotify (); #endif /* HAVE_INOTIFY */ +#ifdef HAVE_KQUEUE + syms_of_kqueue (); +#endif /* HAVE_KQUEUE */ + +#ifdef HAVE_GFILENOTIFY + syms_of_gfilenotify (); +#endif /* HAVE_GFILENOTIFY */ + #ifdef HAVE_DBUS syms_of_dbusbind (); #endif /* HAVE_DBUS */ @@ -1540,7 +1590,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem /* This calls putenv and so must precede init_process_emacs. Also, it sets Voperating_system_release, which init_process_emacs uses. */ - init_editfns (); + init_editfns (dumping); /* These two call putenv. */ #ifdef HAVE_DBUS @@ -1582,13 +1632,11 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem if (filename_from_ansi (file, file_utf8) == 0) file = file_utf8; #endif - Vtop_level = list2 (intern_c_string ("load"), - build_unibyte_string (file)); + Vtop_level = list2 (Qload, build_unibyte_string (file)); } /* Unless next switch is -nl, load "loadup.el" first thing. */ if (! no_loadup) - Vtop_level = list2 (intern_c_string ("load"), - build_string ("loadup.el")); + Vtop_level = list2 (Qload, build_string ("loadup.el")); } /* Set up for profiling. This is known to work on FreeBSD, @@ -1656,6 +1704,7 @@ static const struct standard_args standard_args[] = { "-quick", 0, 55, 0 }, { "-q", "--no-init-file", 50, 0 }, { "-no-init-file", 0, 50, 0 }, + { "-no-x-resources", "--no-x-resources", 40, 0 }, { "-no-site-file", "--no-site-file", 40, 0 }, { "-u", "--user", 30, 1 }, { "-user", 0, 30, 1 }, @@ -1788,7 +1837,7 @@ sort_args (int argc, char **argv) options[from] = standard_args[i].nargs; priority[from] = standard_args[i].priority; if (from + standard_args[i].nargs >= argc) - fatal ("Option `%s' requires an argument\n", argv[from]); + fatal ("Option '%s' requires an argument\n", argv[from]); from += standard_args[i].nargs; goto done; } @@ -1825,7 +1874,7 @@ sort_args (int argc, char **argv) if (equals != 0) options[from] = 0; if (from + options[from] >= argc) - fatal ("Option `%s' requires an argument\n", argv[from]); + fatal ("Option '%s' requires an argument\n", argv[from]); from += options[from]; } /* FIXME When match < 0, shouldn't there be some error, @@ -1899,29 +1948,23 @@ or SIGHUP, and upon SIGINT in batch mode. The value of `kill-emacs-hook', if not void, is a list of functions (of no args), -all of which are called before Emacs is actually killed. */) +all of which are called before Emacs is actually killed. */ + attributes: noreturn) (Lisp_Object arg) { - struct gcpro gcpro1; int exit_code; - GCPRO1 (arg); - - if (feof (stdin)) - arg = Qt; - /* Fsignal calls emacs_abort () if it sees that waiting_for_input is set. */ waiting_for_input = 0; - Frun_hooks (1, &Qkill_emacs_hook); - UNGCPRO; + run_hook (Qkill_emacs_hook); #ifdef HAVE_X_WINDOWS /* Transfer any clipboards we own to the clipboard manager. */ x_clipboard_manager_save_all (); #endif - shut_down_emacs (0, STRINGP (arg) ? arg : Qnil); + shut_down_emacs (0, (STRINGP (arg) && !feof (stdin)) ? arg : Qnil); #ifdef HAVE_NS ns_release_autorelease_pool (ns_pool); @@ -2002,7 +2045,6 @@ shut_down_emacs (int sig, Lisp_Object stuff) /* There is a tendency for a SIGIO signal to arrive within exit, and cause a SIGHUP because the input descriptor is already closed. */ unrequest_sigio (); - ignore_sigio (); /* Do this only if terminating normally, we want glyph matrices etc. in a core dump. */ @@ -2147,9 +2189,22 @@ synchronize_locale (int category, Lisp_Object *plocale, Lisp_Object desired_loca if (! EQ (*plocale, desired_locale)) { *plocale = desired_locale; +#ifdef WINDOWSNT + /* Changing categories like LC_TIME usually requires to specify + an encoding suitable for the new locale, but MS-Windows's + 'setlocale' will only switch the encoding when LC_ALL is + specified. So we ignore CATEGORY, use LC_ALL instead, and + then restore LC_NUMERIC to "C", so reading and printing + numbers is unaffected. */ + setlocale (LC_ALL, (STRINGP (desired_locale) + ? SSDATA (desired_locale) + : "")); + fixup_locale (); +#else /* !WINDOWSNT */ setlocale (category, (STRINGP (desired_locale) ? SSDATA (desired_locale) : "")); +#endif /* !WINDOWSNT */ } } @@ -2261,7 +2316,7 @@ decode_env_path (const char *evarname, const char *defalt, bool empty) p = strchr (path, SEPCHAR); if (!p) p = path + strlen (path); - element = (p - path ? make_unibyte_string (path, p - path) + element = ((p - path) ? make_unibyte_string (path, p - path) : empty_element); if (! NILP (element)) { @@ -2327,17 +2382,18 @@ This finishes the daemonization process by doing the other half of detaching from the parent process and its tty file descriptors. */) (void) { - int nfd; bool err = 0; if (!IS_DAEMON) error ("This function can only be called if emacs is run as a daemon"); - if (daemon_pipe[1] < 0) + if (!DAEMON_RUNNING) error ("The daemon has already been initialized"); if (NILP (Vafter_init_time)) error ("This function can only be called after loading the init files"); +#ifndef WINDOWSNT + int nfd; /* Get rid of stdin, stdout and stderr. */ nfd = emacs_open ("/dev/null", O_RDWR, 0); @@ -2358,6 +2414,13 @@ from the parent process and its tty file descriptors. */) err |= emacs_close (daemon_pipe[1]) != 0; /* Set it to an invalid value so we know we've already run this function. */ daemon_pipe[1] = -1; +#else /* WINDOWSNT */ + /* Signal the waiting emacsclient process. */ + err |= SetEvent (w32_daemon_event) == 0; + err |= CloseHandle (w32_daemon_event) == 0; + /* Set it to an invalid value so we know we've already run this function. */ + w32_daemon_event = INVALID_HANDLE_VALUE; +#endif if (err) error ("I/O error during daemon initialization"); @@ -2400,12 +2463,10 @@ Special values: Anything else (in Emacs 24.1, the possibilities are: aix, berkeley-unix, hpux, irix, usg-unix-v) indicates some sort of Unix system. */); Vsystem_type = intern_c_string (SYSTEM_TYPE); - /* See configure.ac (and config.nt) for the possible SYSTEM_TYPEs. */ + /* See configure.ac for the possible SYSTEM_TYPEs. */ DEFVAR_LISP ("system-configuration", Vsystem_configuration, - doc: /* Value is string indicating configuration Emacs was built for. -On MS-Windows, the value reflects the OS flavor and version on which -Emacs is running. */); + doc: /* Value is string indicating configuration Emacs was built for. */); Vsystem_configuration = build_string (EMACS_CONFIGURATION); DEFVAR_LISP ("system-configuration-options", Vsystem_configuration_options, @@ -2415,7 +2476,10 @@ Emacs is running. */); DEFVAR_LISP ("system-configuration-features", Vsystem_configuration_features, doc: /* String listing some of the main features this Emacs was compiled with. An element of the form \"FOO\" generally means that HAVE_FOO was -defined during the build. */); +defined during the build. + +This is mainly intended for diagnostic purposes in bug reports. +Don't rely on it for testing whether a feature you want to use is available. */); Vsystem_configuration_features = build_string (EMACS_CONFIG_FEATURES); DEFVAR_BOOL ("noninteractive", noninteractive1,