#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 "intervals.h"
#include "character.h"
#include "charset.h"
#include "composite.h"
#include "dispextern.h"
+#include "regex.h"
#include "syntax.h"
+#include "sysselect.h"
#include "systime.h"
#include "gnutls.h"
#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;
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
/* 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;
/* 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;
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[] =
{ "\
--no-init-file, -q load neither ~/.emacs nor default.el\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\
"\
--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\
Various environment variables and window system resources also affect\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"
};
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));
static void
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;
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);
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);
}
}
}
\f
-#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
stack_base = &dummy;
#endif
-#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);
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");
&& !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
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);
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.
{
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))
}
#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 ();
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_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 ();
+
+ /* 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 (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"));
- }
-
- 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;
- }
- }
-#endif
+ Vtop_level = list2 (Qload, build_string ("loadup.el"));
}
/* Set up for profiling. This is known to work on FreeBSD,
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 */
{ "-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 },
}
/* 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;
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))
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;
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);
+ run_hook (Qkill_emacs_hook);
UNGCPRO;
#ifdef HAVE_X_WINDOWS
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);
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. */
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. */
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
{
if (! EQ (*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 and use LC_ALL instead. */
+ category = LC_ALL;
+#endif
*plocale = desired_locale;
setlocale (category, (STRINGP (desired_locale)
? SSDATA (desired_locale)
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))
{
}
if (! NILP (tem))
- element = concat2 (build_string ("/:"), element);
+ {
+ AUTO_STRING (slash_colon, "/:");
+ element = concat2 (slash_colon, element);
+ }
} /* !NILP (element) */
lpath = Fcons (element, lpath);
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);
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");
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. */);
+ Vsystem_configuration_features = build_string (EMACS_CONFIG_FEATURES);
+
DEFVAR_BOOL ("noninteractive", noninteractive1,
doc: /* Non-nil means Emacs is running without interactive terminal. */);
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