summaryrefslogtreecommitdiff
path: root/src/emacs.c
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@raeburn.org>2015-11-01 01:42:21 -0400
committerKen Raeburn <raeburn@raeburn.org>2015-11-01 01:42:21 -0400
commit39372e1a1032521be74575bb06f95a3898fbae30 (patch)
tree754bd242a23d2358ea116126fcb0a629947bd9ec /src/emacs.c
parent6a3121904d76e3b2f63007341d48c5c1af55de80 (diff)
parente11aaee266da52937a3a031cb108fe13f68958c3 (diff)
downloademacs-39372e1a1032521be74575bb06f95a3898fbae30.tar.gz
merge from trunk
Diffstat (limited to 'src/emacs.c')
-rw-r--r--src/emacs.c562
1 files changed, 351 insertions, 211 deletions
diff --git a/src/emacs.c b/src/emacs.c
index 22bca915c7e..9dc4e423547 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1,6 +1,6 @@
/* Fully extensible Emacs, running on Unix, intended for GNU.
-Copyright (C) 1985-1987, 1993-1995, 1997-1999, 2001-2013 Free Software
+Copyright (C) 1985-1987, 1993-1995, 1997-1999, 2001-2015 Free Software
Foundation, Inc.
This file is part of GNU Emacs.
@@ -18,9 +18,11 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
-
+#define INLINE EXTERN_INLINE
#include <config.h>
+
#include <errno.h>
+#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
@@ -32,9 +34,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifdef WINDOWSNT
#include <fcntl.h>
#include <sys/socket.h>
+#include <mbstring.h>
#include "w32heap.h"
#endif
+#define MAIN_PROGRAM
#include "lisp.h"
#if defined WINDOWSNT || defined HAVE_NTGUI
@@ -50,22 +54,20 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "cygw32.h"
#endif
+#ifdef MSDOS
+#include <binary-io.h>
+#endif
+
#ifdef HAVE_WINDOW_SYSTEM
#include TERM_HEADER
#endif /* HAVE_WINDOW_SYSTEM */
-#ifdef NS_IMPL_GNUSTEP
-/* At least under Debian, GSConfig is in a subdirectory. --Stef */
-#include <GNUstepBase/GSConfig.h>
-#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"
@@ -74,10 +76,17 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "termhooks.h"
#include "keyboard.h"
#include "keymap.h"
+#include "category.h"
+#include "charset.h"
+#include "composite.h"
+#include "dispextern.h"
+#include "regex.h"
+#include "syntax.h"
+#include "sysselect.h"
+#include "systime.h"
+#include "puresize.h"
-#ifdef HAVE_GNUTLS
#include "gnutls.h"
-#endif
#if (defined PROFILING \
&& (defined __FreeBSD__ || defined GNU_LINUX || defined __MINGW32__))
@@ -89,6 +98,10 @@ extern void moncontrol (int mode);
#include <locale.h>
#endif
+#if HAVE_WCHAR_H
+# include <wchar.h>
+#endif
+
#ifdef HAVE_SETRLIMIT
#include <sys/time.h>
#include <sys/resource.h>
@@ -98,8 +111,9 @@ extern void moncontrol (int mode);
#include <sys/personality.h>
#endif
-static const char emacs_version[] = VERSION;
+static const char emacs_version[] = PACKAGE_VERSION;
static const char emacs_copyright[] = COPYRIGHT;
+static const char emacs_bugreport[] = PACKAGE_BUGREPORT;
/* Empty lisp strings. To avoid having to build any others. */
Lisp_Object empty_unibyte_string, empty_multibyte_string;
@@ -114,6 +128,9 @@ Lisp_Object Vlibrary_cache;
on subsequent starts. */
bool initialized;
+/* Set to true if this instance of Emacs might dump. */
+bool might_dump;
+
#ifdef DARWIN_OS
extern void unexec_init_emacs_zone (void);
#endif
@@ -125,21 +142,14 @@ static void *malloc_state_ptr;
/* From glibc, a routine that returns a copy of the malloc internal state. */
extern void *malloc_get_state (void);
/* From glibc, a routine that overwrites the malloc internal state. */
-extern int malloc_set_state (void*);
+extern int malloc_set_state (void *);
/* True if the MALLOC_CHECK_ environment variable was set while
dumping. Used to work around a bug in glibc's malloc. */
static bool malloc_using_checking;
-#elif defined HAVE_PTHREAD && !defined SYSTEM_MALLOC
+#elif defined HAVE_PTHREAD && !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
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;
@@ -188,9 +198,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;
@@ -199,7 +213,7 @@ int initial_argc;
static void sort_args (int argc, char **argv);
static void syms_of_emacs (void);
-/* C89 needs each string be at most 509 characters, so the usage
+/* C99 needs each string to be at most 4095 characters, and the usage
strings below are split to not overflow this limit. */
static char const *const usage_message[] =
{ "\
@@ -224,8 +238,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\
@@ -233,6 +248,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\
@@ -244,7 +260,7 @@ Action options:\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\
---directory, -L DIR add DIR to variable load-path\n\
+--directory, -L DIR prepend DIR to load-path (with :DIR, append DIR)\n\
--eval EXPR evaluate Emacs Lisp expression EXPR\n\
--execute EXPR evaluate Emacs Lisp expression EXPR\n\
",
@@ -308,9 +324,9 @@ example, -batch as well as --batch. You can use any unambiguous\n\
abbreviation for a --option.\n\
\n\
Various environment variables and window system resources also affect\n\
-Emacs' operation. See the main documentation.\n\
+the operation of Emacs. See the main documentation.\n\
\n\
-Report bugs to bug-gnu-emacs@gnu.org. First, please see the Bugs\n\
+Report bugs to " PACKAGE_BUGREPORT ". First, please see the Bugs\n\
section of the Emacs manual or the file BUGS.\n"
};
@@ -331,6 +347,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. */
@@ -338,13 +367,13 @@ _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)
{
fatal_error_in_progress = 1;
+ totally_unblock_input ();
if (sig == SIGTERM || sig == SIGHUP || sig == SIGINT)
Fkill_emacs (make_number (sig));
@@ -373,23 +402,37 @@ terminate_due_to_signal (int sig, int backtrace_limit)
/* Code for dealing with Lisp access to the Unix command line. */
static void
-init_cmdargs (int argc, char **argv, int skip_args)
+init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd)
{
- register int i;
+ int i;
Lisp_Object name, dir, handler;
ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object raw_name;
+ AUTO_STRING (slash_colon, "/:");
initial_argv = argv;
initial_argc = argc;
- raw_name = build_string (argv[0]);
+#ifdef WINDOWSNT
+ /* Must use argv[0] converted to UTF-8, as it begets many standard
+ file and directory names. */
+ {
+ char argv0[MAX_UTF8_PATH];
+
+ if (filename_from_ansi (argv[0], argv0) == 0)
+ raw_name = build_unibyte_string (argv0);
+ else
+ raw_name = build_unibyte_string (argv[0]);
+ }
+#else
+ raw_name = build_unibyte_string (argv[0]);
+#endif
/* Add /: to the front of the name
if it would otherwise be treated as magic. */
handler = Ffind_file_name_handler (raw_name, Qt);
if (! NILP (handler))
- raw_name = concat2 (build_string ("/:"), raw_name);
+ raw_name = concat2 (slash_colon, raw_name);
Vinvocation_name = Ffile_name_nondirectory (raw_name);
Vinvocation_directory = Ffile_name_directory (raw_name);
@@ -400,14 +443,14 @@ init_cmdargs (int argc, char **argv, int skip_args)
{
Lisp_Object found;
int yes = openp (Vexec_path, Vinvocation_name,
- Vexec_suffixes, &found, make_number (X_OK));
+ Vexec_suffixes, &found, make_number (X_OK), false);
if (yes == 1)
{
/* Add /: to the front of the name
if it would otherwise be treated as magic. */
handler = Ffind_file_name_handler (found, Qt);
if (! NILP (handler))
- found = concat2 (build_string ("/:"), found);
+ found = concat2 (slash_colon, found);
Vinvocation_directory = Ffile_name_directory (found);
}
}
@@ -416,7 +459,12 @@ init_cmdargs (int argc, char **argv, int skip_args)
&& NILP (Ffile_name_absolute_p (Vinvocation_directory)))
/* Emacs was started with relative path, like ./emacs.
Make it absolute. */
- Vinvocation_directory = Fexpand_file_name (Vinvocation_directory, Qnil);
+ {
+ Lisp_Object odir =
+ original_pwd ? build_unibyte_string (original_pwd) : Qnil;
+
+ Vinvocation_directory = Fexpand_file_name (Vinvocation_directory, odir);
+ }
Vinstallation_directory = Qnil;
@@ -538,12 +586,6 @@ DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory,
}
-#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. */
-static char const dump_tz[] = "UtC0";
-#endif
-
/* Test whether the next argument in ARGV matches SSTR or a prefix of
LSTR (at least MINLEN characters). If so, then if VALPTR is non-null
(the argument is supposed to have a value) store in *VALPTR either
@@ -684,23 +726,21 @@ main (int argc, char **argv)
#ifdef DAEMON_MUST_EXEC
char dname_arg2[80];
#endif
- char *ch_to_dir;
+ char *ch_to_dir = 0;
+
+ /* If we use --chdir, this records the original directory. */
+ char *original_pwd = 0;
/* Record (approximately) where the stack begins. */
stack_bottom = &stack_bottom_variable;
-#ifdef G_SLICE_ALWAYS_MALLOC
- /* This is used by the Cygwin build. It's not needed starting with
- cygwin-1.7.24, but it doesn't do any harm. */
- xputenv ("G_SLICE=always-malloc");
+#ifndef CANNOT_DUMP
+ might_dump = !initialized;
#endif
#ifdef GNU_LINUX
if (!initialized)
{
- extern char my_endbss[];
- extern char *my_endbss_static;
-
if (my_heap_start == 0)
my_heap_start = sbrk (0);
@@ -713,6 +753,12 @@ main (int argc, char **argv)
early as possible. (unexw32.c calls this function as well, but
the additional call here is harmless.) */
cache_system_info ();
+#ifdef WINDOWSNT
+ /* On Windows 9X, we have to load UNICOWS.DLL as early as possible,
+ to have non-stub implementations of APIs we need to convert file
+ names between UTF-8 and the system's ANSI codepage. */
+ maybe_load_unicows_dll ();
+#endif
#endif
#ifdef RUN_TIME_REMAP
@@ -742,12 +788,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
@@ -761,10 +807,10 @@ main (int argc, char **argv)
version = emacs_version;
copyright = emacs_copyright;
}
- printf ("GNU Emacs %s\n", version);
+ printf ("%s %s\n", PACKAGE_NAME, version);
printf ("%s\n", copyright);
- printf ("GNU Emacs comes with ABSOLUTELY NO WARRANTY.\n");
- printf ("You may redistribute copies of Emacs\n");
+ printf ("%s comes with ABSOLUTELY NO WARRANTY.\n", PACKAGE_NAME);
+ printf ("You may redistribute copies of %s\n", PACKAGE_NAME);
printf ("under the terms of the GNU General Public License.\n");
printf ("For more information about these matters, ");
printf ("see the file named COPYING.\n");
@@ -772,12 +818,23 @@ main (int argc, char **argv)
}
if (argmatch (argv, argc, "-chdir", "--chdir", 4, &ch_to_dir, &skip_args))
- if (chdir (ch_to_dir) == -1)
- {
- fprintf (stderr, "%s: Can't chdir to %s: %s\n",
- argv[0], ch_to_dir, strerror (errno));
- exit (1);
- }
+ {
+#ifdef WINDOWSNT
+ /* argv[] array is kept in its original ANSI codepage encoding,
+ we need to convert to UTF-8, for chdir to work. */
+ char newdir[MAX_UTF8_PATH];
+
+ filename_from_ansi (ch_to_dir, newdir);
+ ch_to_dir = newdir;
+#endif
+ original_pwd = get_current_dir_name ();
+ if (chdir (ch_to_dir) != 0)
+ {
+ fprintf (stderr, "%s: Can't chdir to %s: %s\n",
+ argv[0], ch_to_dir, strerror (errno));
+ exit (1);
+ }
+ }
dumping = !initialized && (strcmp (argv[argc - 1], "dump") == 0
|| strcmp (argv[argc - 1], "bootstrap") == 0);
@@ -801,10 +858,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)
@@ -812,7 +872,6 @@ main (int argc, char **argv)
&& !getrlimit (RLIMIT_STACK, &rlim))
{
long newlim;
- extern size_t re_max_failures;
/* Approximate the amount regex.c needs per unit of re_max_failures. */
int ratio = 20 * sizeof (char *);
/* Then add 33% to cover the size of the smaller stacks that regex.c
@@ -839,11 +898,13 @@ main (int argc, char **argv)
setrlimit (RLIMIT_STACK, &rlim);
}
-#endif /* HAVE_SETRLIMIT and RLIMIT_STACK */
+#endif /* HAVE_SETRLIMIT and RLIMIT_STACK and not CYGWIN */
clearerr (stdin);
-#ifndef SYSTEM_MALLOC
+ emacs_backtrace (-1);
+
+#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
/* Arrange to get warning messages as memory fills up. */
memory_warnings (0, malloc_warning);
@@ -851,22 +912,12 @@ main (int argc, char **argv)
Also call realloc and free for consistency. */
free (realloc (malloc (4), 4));
-#endif /* not SYSTEM_MALLOC */
-
-#if defined (MSDOS) || defined (WINDOWSNT)
- /* We do all file input/output as binary files. When we need to translate
- newlines, we do that manually. */
- _fmode = O_BINARY;
-#endif /* MSDOS || WINDOWSNT */
+#endif /* not SYSTEM_MALLOC and not HYBRID_MALLOC */
#ifdef MSDOS
- if (!isatty (fileno (stdin)))
- setmode (fileno (stdin), O_BINARY);
- if (!isatty (fileno (stdout)))
- {
- fflush (stdout);
- setmode (fileno (stdout), O_BINARY);
- }
+ SET_BINARY (fileno (stdin));
+ fflush (stdout);
+ SET_BINARY (fileno (stdout));
#endif /* MSDOS */
/* Skip initial setlocale if LC_ALL is "C", as it's not needed in that case.
@@ -882,6 +933,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;
@@ -944,11 +996,18 @@ main (int argc, char **argv)
{
int i;
printf ("Usage: %s [OPTION-OR-FILENAME]...\n", argv[0]);
- for (i = 0; i < sizeof usage_message / sizeof *usage_message; i++)
+ for (i = 0; i < ARRAYELTS (usage_message); i++)
fputs (usage_message[i], stdout);
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))
{
@@ -1049,6 +1108,8 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
argv[skip_args] = fdStr;
+ fcntl (daemon_pipe[0], F_SETFD, 0);
+ fcntl (daemon_pipe[1], F_SETFD, 0);
execvp (argv[0], argv);
emacs_perror (argv[0]);
exit (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
@@ -1065,27 +1126,38 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
sscanf (dname_arg, "\n%d,%d\n%s", &(daemon_pipe[0]), &(daemon_pipe[1]),
dname_arg2);
dname_arg = *dname_arg2 ? dname_arg2 : NULL;
+ fcntl (daemon_pipe[1], F_SETFD, FD_CLOEXEC);
}
#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 && !defined DOUG_LEA_MALLOC
+#if defined HAVE_PTHREAD && !defined SYSTEM_MALLOC \
+ && !defined DOUG_LEA_MALLOC && !defined HYBRID_MALLOC
# ifndef CANNOT_DUMP
/* Do not make gmalloc thread-safe when creating bootstrap-emacs, as
- that causes an infinite recursive loop with FreeBSD. But do make
- it thread-safe when creating emacs, otherwise bootstrap-emacs
- fails on Cygwin. See Bug#14569. */
+ that causes an infinite recursive loop with FreeBSD. See
+ Bug#14569. The part of this bug involving Cygwin is no longer
+ relevant, now that Cygwin defines HYBRID_MALLOC. */
if (!noninteractive || initialized)
# endif
malloc_enable_thread ();
@@ -1169,22 +1241,30 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
#ifdef HAVE_NS
ns_pool = ns_alloc_autorelease_pool ();
+#ifdef NS_IMPL_GNUSTEP
+ /* GNUstep stupidly resets our locale settings after we made them. */
+ fixup_locale ();
+#endif
+
if (!noninteractive)
{
#ifdef NS_IMPL_COCOA
+ /* Started from GUI? */
+ /* FIXME: Do the right thing if getenv returns NULL, or if
+ chdir fails. */
+ if (! inhibit_window_system && ! isatty (0) && ! ch_to_dir)
+ chdir (getenv ("HOME"));
if (skip_args < argc)
{
- /* FIXME: Do the right thing if getenv returns NULL, or if
- chdir fails. */
if (!strncmp (argv[skip_args], "-psn", 4))
{
skip_args += 1;
- chdir (getenv ("HOME"));
+ if (! ch_to_dir) chdir (getenv ("HOME"));
}
else if (skip_args+1 < argc && !strncmp (argv[skip_args+1], "-psn", 4))
{
skip_args += 2;
- chdir (getenv ("HOME"));
+ if (! ch_to_dir) chdir (getenv ("HOME"));
}
}
#endif /* COCOA */
@@ -1300,10 +1380,13 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
xputenv ("LANG=C");
#endif
- init_buffer (); /* Init default directory of main buffer. */
+ /* Init buffer storage and default directory of main buffer. */
+ init_buffer (initialized);
init_callproc_1 (); /* Must precede init_cmdargs and init_sys_modes. */
- init_cmdargs (argc, argv, skip_args); /* Must precede init_lread. */
+
+ /* Must precede init_lread. */
+ init_cmdargs (argc, argv, skip_args, original_pwd);
if (initialized)
{
@@ -1432,9 +1515,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
syms_of_fontset ();
#endif /* HAVE_NS */
-#ifdef HAVE_GNUTLS
syms_of_gnutls ();
-#endif
#ifdef HAVE_GFILENOTIFY
syms_of_gfilenotify ();
@@ -1482,11 +1563,30 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
init_charset ();
- init_editfns (); /* init_process_emacs uses Voperating_system_release. */
- init_process_emacs (); /* init_display uses add_keyboard_wait_descriptor. */
+ /* This calls putenv and so must precede init_process_emacs. Also,
+ it sets Voperating_system_release, which init_process_emacs uses. */
+ init_editfns (dumping);
+
+ /* These two call putenv. */
+#ifdef HAVE_DBUS
+ init_dbusbind ();
+#endif
+#ifdef USE_GTK
+ init_xterm ();
+#endif
+
+ /* This can create a thread that may call getenv, so it must follow
+ all calls to putenv and setenv. Also, this sets up
+ add_keyboard_wait_descriptor, which init_display uses. */
+ init_process_emacs ();
+
init_keyboard (); /* This too must precede init_sys_modes. */
if (!noninteractive)
init_display (); /* Determine terminal type. Calls init_sys_modes. */
+#if HAVE_W32NOTIFY
+ else
+ init_crit (); /* w32notify.c needs this in batch mode. */
+#endif /* HAVE_W32NOTIFY */
init_xdisp ();
#ifdef HAVE_WINDOW_SYSTEM
init_fringe ();
@@ -1500,31 +1600,18 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
char *file;
/* Handle -l loadup, args passed by Makefile. */
if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args))
- Vtop_level = list2 (intern_c_string ("load"), build_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"));
- }
+ {
+#ifdef WINDOWSNT
+ char file_utf8[MAX_UTF8_PATH];
- if (initialized)
- {
-#ifdef HAVE_TZSET
- {
- /* If the execution TZ happens to be the same as the dump TZ,
- change it to some other value and then change it back,
- to force the underlying implementation to reload the TZ info.
- This is needed on implementations that load TZ info from files,
- since the TZ file contents may differ between dump and execution. */
- char *tz = getenv ("TZ");
- if (tz && !strcmp (tz, dump_tz))
- {
- ++*tz;
- tzset ();
- --*tz;
- }
- }
+ if (filename_from_ansi (file, file_utf8) == 0)
+ file = file_utf8;
#endif
+ Vtop_level = list2 (Qload, build_unibyte_string (file));
+ }
+ /* Unless next switch is -nl, load "loadup.el" first thing. */
+ if (! no_loadup)
+ Vtop_level = list2 (Qload, build_string ("loadup.el"));
}
/* Set up for profiling. This is known to work on FreeBSD,
@@ -1551,15 +1638,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
initialized = 1;
-#ifdef LOCALTIME_CACHE
- /* Some versions of localtime have a bug. They cache the value of the time
- zone rather than looking it up every time. Since localtime() is
- called to bolt the undumping time into the undumped emacs, this
- results in localtime ignoring the TZ environment variable.
- This flushes the new TZ value into localtime. */
- tzset ();
-#endif /* defined (LOCALTIME_CACHE) */
-
/* Enter editor command loop. This never returns. */
Frecursive_edit ();
/* NOTREACHED */
@@ -1601,6 +1679,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 },
@@ -1644,7 +1723,6 @@ static const struct standard_args standard_args[] =
#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 },
@@ -1728,13 +1806,13 @@ sort_args (int argc, char **argv)
}
/* Look for a match with a known old-fashioned option. */
- for (i = 0; i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
+ for (i = 0; i < ARRAYELTS (standard_args); i++)
if (!strcmp (argv[from], standard_args[i].name))
{
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;
}
@@ -1750,8 +1828,7 @@ sort_args (int argc, char **argv)
match = -1;
- for (i = 0;
- i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
+ for (i = 0; i < ARRAYELTS (standard_args); i++)
if (standard_args[i].longname
&& !strncmp (argv[from], standard_args[i].longname,
thislen))
@@ -1772,7 +1849,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,
@@ -1846,29 +1923,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);
@@ -1944,14 +2015,11 @@ shut_down_emacs (int sig, Lisp_Object stuff)
kill_buffer_processes (Qnil);
Fdo_auto_save (Qt, Qnil);
-#ifdef CLASH_DETECTION
unlock_all_files ();
-#endif
/* 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. */
@@ -2001,6 +2069,9 @@ You must run Emacs in batch mode in order to dump it. */)
if (! noninteractive)
error ("Dumping Emacs works only in batch mode");
+ if (!might_dump)
+ error ("Emacs can be dumped only once");
+
#ifdef GNU_LINUX
/* Warn if the gap between BSS end and heap start is larger than this. */
@@ -2027,48 +2098,36 @@ You must run Emacs in batch mode in order to dump it. */)
CHECK_STRING (filename);
filename = Fexpand_file_name (filename, Qnil);
+ filename = ENCODE_FILE (filename);
if (!NILP (symfile))
{
CHECK_STRING (symfile);
if (SCHARS (symfile))
- symfile = Fexpand_file_name (symfile, Qnil);
+ {
+ symfile = Fexpand_file_name (symfile, Qnil);
+ symfile = ENCODE_FILE (symfile);
+ }
}
tem = Vpurify_flag;
Vpurify_flag = Qnil;
-#ifdef HAVE_TZSET
- set_time_zone_rule (dump_tz);
-#ifndef LOCALTIME_CACHE
- /* Force a tz reload, since set_time_zone_rule doesn't. */
- tzset ();
-#endif
-#endif
-
fflush (stdout);
/* Tell malloc where start of impure now is. */
/* Also arrange for warnings when nearly out of space. */
-#ifndef SYSTEM_MALLOC
+#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
#ifndef WINDOWSNT
/* On Windows, this was done before dumping, and that once suffices.
Meanwhile, my_edata is not valid on Windows. */
- {
- extern char my_edata[];
- memory_warnings (my_edata, malloc_warning);
- }
+ memory_warnings (my_edata, malloc_warning);
#endif /* not WINDOWSNT */
-#endif /* not SYSTEM_MALLOC */
+#endif /* not SYSTEM_MALLOC and not HYBRID_MALLOC */
#ifdef DOUG_LEA_MALLOC
malloc_state_ptr = malloc_get_state ();
#endif
-#ifdef USE_MMAP_FOR_BUFFERS
- mmap_set_vars (0);
-#endif
unexec (SSDATA (filename), !NILP (symfile) ? SSDATA (symfile) : 0);
-#ifdef USE_MMAP_FOR_BUFFERS
- mmap_set_vars (1);
-#endif
+
#ifdef DOUG_LEA_MALLOC
free (malloc_state_ptr);
#endif
@@ -2105,9 +2164,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 */
}
}
@@ -2133,15 +2205,25 @@ synchronize_system_messages_locale (void)
Lisp_Object
-decode_env_path (const char *evarname, const char *defalt)
+decode_env_path (const char *evarname, const char *defalt, bool empty)
{
const char *path, *p;
Lisp_Object lpath, element, tem;
+ /* Default is to use "." for empty path elements.
+ But if argument EMPTY is true, use nil instead. */
+ Lisp_Object empty_element = empty ? Qnil : build_string (".");
#ifdef WINDOWSNT
bool defaulted = 0;
- const char *emacs_dir = egetenv ("emacs_dir");
static const char *emacs_dir_env = "%emacs_dir%/";
const size_t emacs_dir_len = strlen (emacs_dir_env);
+ const char *edir = egetenv ("emacs_dir");
+ char emacs_dir[MAX_UTF8_PATH];
+
+ /* egetenv looks in process-environment, which holds the variables
+ in their original system-locale encoding. We need emacs_dir to
+ be in UTF-8. */
+ if (edir)
+ filename_from_ansi (edir, emacs_dir);
#endif
/* It's okay to use getenv here, because this function is only used
@@ -2162,9 +2244,44 @@ decode_env_path (const char *evarname, const char *defalt)
/* Ensure values from the environment use the proper directory separator. */
if (path)
{
- char *path_copy = alloca (strlen (path) + 1);
+ char *path_copy;
+
+#ifdef WINDOWSNT
+ char *path_utf8, *q, *d;
+ int cnv_result;
+
+ /* Convert each element of PATH to UTF-8. */
+ p = path_copy = alloca (strlen (path) + 1);
strcpy (path_copy, path);
- dostounix_filename (path_copy, 0);
+ d = path_utf8 = alloca (4 * strlen (path) + 1);
+ *d = '\0';
+ do {
+ q = _mbschr (p, SEPCHAR);
+ if (q)
+ *q = '\0';
+ cnv_result = filename_from_ansi (p, d);
+ if (q)
+ {
+ *q++ = SEPCHAR;
+ p = q;
+ /* If conversion of this PATH elements fails, make sure
+ destination pointer will stay put, thus effectively
+ ignoring the offending element. */
+ if (cnv_result == 0)
+ {
+ d += strlen (d);
+ *d++ = SEPCHAR;
+ }
+ }
+ else if (cnv_result != 0 && d > path_utf8)
+ d[-1] = '\0'; /* remove last semi-colon and null-terminate PATH */
+ } while (q);
+ path_copy = path_utf8;
+#else /* MSDOS */
+ path_copy = alloca (strlen (path) + 1);
+ strcpy (path_copy, path);
+#endif
+ dostounix_filename (path_copy);
path = path_copy;
}
#endif
@@ -2174,35 +2291,42 @@ decode_env_path (const char *evarname, const char *defalt)
p = strchr (path, SEPCHAR);
if (!p)
p = path + strlen (path);
- element = (p - path ? make_string (path, p - path)
- : build_string ("."));
+ element = ((p - path) ? make_unibyte_string (path, p - path)
+ : empty_element);
+ if (! NILP (element))
+ {
#ifdef WINDOWSNT
- /* Relative file names in the default path are interpreted as
- being relative to $emacs_dir. */
- if (emacs_dir && defaulted
- && strncmp (path, emacs_dir_env, emacs_dir_len) == 0)
- element = Fexpand_file_name (Fsubstring (element,
- make_number (emacs_dir_len),
- Qnil),
- build_string (emacs_dir));
-#endif
-
- /* Add /: to the front of the name
- if it would otherwise be treated as magic. */
- tem = Ffind_file_name_handler (element, Qt);
-
- /* However, if the handler says "I'm safe",
- don't bother adding /:. */
- if (SYMBOLP (tem))
- {
- Lisp_Object prop;
- prop = Fget (tem, intern ("safe-magic"));
- if (! NILP (prop))
- tem = Qnil;
- }
+ /* Relative file names in the default path are interpreted as
+ being relative to $emacs_dir. */
+ if (edir && defaulted
+ && strncmp (path, emacs_dir_env, emacs_dir_len) == 0)
+ element = Fexpand_file_name (Fsubstring
+ (element,
+ make_number (emacs_dir_len),
+ Qnil),
+ build_unibyte_string (emacs_dir));
+#endif
+
+ /* Add /: to the front of the name
+ if it would otherwise be treated as magic. */
+ tem = Ffind_file_name_handler (element, Qt);
+
+ /* However, if the handler says "I'm safe",
+ don't bother adding /:. */
+ if (SYMBOLP (tem))
+ {
+ Lisp_Object prop;
+ prop = Fget (tem, intern ("safe-magic"));
+ if (! NILP (prop))
+ tem = Qnil;
+ }
- if (! NILP (tem))
- element = concat2 (build_string ("/:"), element);
+ if (! NILP (tem))
+ {
+ AUTO_STRING (slash_colon, "/:");
+ element = concat2 (slash_colon, element);
+ }
+ } /* !NILP (element) */
lpath = Fcons (element, lpath);
if (*p)
@@ -2233,17 +2357,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);
@@ -2264,6 +2389,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");
@@ -2306,18 +2438,25 @@ 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,
doc: /* String containing the configuration options Emacs was built with. */);
Vsystem_configuration_options = build_string (EMACS_CONFIG_OPTIONS);
+ 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.
+
+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,
doc: /* Non-nil means Emacs is running without interactive terminal. */);
@@ -2395,6 +2534,10 @@ This is nil during initialization. */);
doc: /* Version numbers of this version of Emacs. */);
Vemacs_version = build_string (emacs_version);
+ DEFVAR_LISP ("report-emacs-bug-address", Vreport_emacs_bug_address,
+ doc: /* Address of mailing list for GNU Emacs bugs. */);
+ Vreport_emacs_bug_address = build_string (emacs_bugreport);
+
DEFVAR_LISP ("dynamic-library-alist", Vdynamic_library_alist,
doc: /* Alist of dynamic libraries vs external files implementing them.
Each element is a list (LIBRARY FILE...), where the car is a symbol
@@ -2417,7 +2560,4 @@ libraries; only those already known by Emacs will be loaded. */);
Vlibrary_cache = Qnil;
staticpro (&Vlibrary_cache);
#endif
-
- /* Make sure IS_DAEMON starts up as false. */
- daemon_pipe[1] = 0;
}