#include <sys/file.h>
#include <unistd.h>
+#include <close-stream.h>
#include <ignore-value.h>
#include "lisp.h"
-#ifdef HAVE_WINDOW_SYSTEM
-#include TERM_HEADER
-#endif /* HAVE_WINDOW_SYSTEM */
-
#ifdef WINDOWSNT
#include <fcntl.h>
-#include <windows.h> /* just for w32.h */
#include "w32.h"
-#include "w32heap.h" /* for prototype of sbrk */
+#include "w32heap.h"
+#endif
+
+#if defined WINDOWSNT || defined HAVE_NTGUI
+#include "w32select.h"
+#include "w32font.h"
+#endif
+
+#if defined HAVE_NTGUI && defined CYGWIN
+#include "cygw32.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>
#include <sys/personality.h>
#endif
-#ifndef O_RDWR
-#define O_RDWR 2
-#endif
-
static const char emacs_version[] = VERSION;
static const char emacs_copyright[] = COPYRIGHT;
/* Empty lisp strings. To avoid having to build any others. */
Lisp_Object empty_unibyte_string, empty_multibyte_string;
+#ifdef WINDOWSNT
+/* Cache for externally loaded libraries. */
+Lisp_Object Vlibrary_cache;
+#endif
+
/* Set after Emacs has started up the first time.
Prevents reinitialization of the Lisp world and keymaps
on subsequent starts. */
static uprintmax_t heap_bss_diff;
#endif
+/* To run as a daemon under Cocoa or Windows, we must do a fork+exec,
+ not a simple fork.
+
+ On Cocoa, CoreFoundation lib fails in forked process:
+ http://developer.apple.com/ReleaseNotes/
+ CoreFoundation/CoreFoundation.html)
+
+ On Windows, a Cygwin fork child cannot access the USER subsystem.
+
+ 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 defined NS_IMPL_COCOA || (defined HAVE_NTGUI && defined CYGWIN)
+# define DAEMON_MUST_EXEC
+#endif
+
/* True means running Emacs without interactive terminal. */
bool noninteractive;
_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. */
#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 dump_tz[] = "UtC0";
+static char const dump_tz[] = "UtC0";
#endif
#ifndef ORDINARY_LINK
#endif /* DOUG_LEA_MALLOC */
+/* Close standard output and standard error, reporting any write
+ errors as best we can. This is intended for use with atexit. */
+static void
+close_output_streams (void)
+{
+ if (close_stream (stdout) != 0)
+ {
+ fprintf (stderr, "Write error to standard output: %s\n",
+ strerror (errno));
+ fflush (stderr);
+ _exit (EXIT_FAILURE);
+ }
+
+ if (close_stream (stderr) != 0)
+ _exit (EXIT_FAILURE);
+}
/* ARGSUSED */
int
bool no_loadup = 0;
char *junk = 0;
char *dname_arg = 0;
-#ifdef NS_IMPL_COCOA
+#ifdef DAEMON_MUST_EXEC
char dname_arg2[80];
#endif
char *ch_to_dir;
stack_base = &dummy;
#endif
-#if defined (USE_GTK) && defined (G_SLICE_ALWAYS_MALLOC)
+#ifdef G_SLICE_ALWAYS_MALLOC
/* This is used by the Cygwin build. */
- setenv ("G_SLICE", "always-malloc", 1);
+ xputenv ("G_SLICE=always-malloc");
#endif
#ifdef GNU_LINUX
unexec_init_emacs_zone ();
#endif
+ atexit (close_output_streams);
+
sort_args (argc, argv);
argc = 0;
while (argv[argc]) argc++;
#ifdef HAVE_PERSONALITY_LINUX32
if (dumping && ! getenv ("EMACS_HEAP_EXEC"))
{
- static char heapexec[] = "EMACS_HEAP_EXEC=true";
/* Set this so we only do this once. */
- putenv (heapexec);
+ xputenv ("EMACS_HEAP_EXEC=true");
/* A flag to turn off address randomization which is introduced
in linux kernel shipped with fedora core 4 */
exit (1);
}
-#ifndef NS_IMPL_COCOA
+#ifndef DAEMON_MUST_EXEC
#ifdef USE_GTK
fprintf (stderr, "\nWarning: due to a long standing Gtk+ bug\nhttp://bugzilla.gnome.org/show_bug.cgi?id=85715\n\
Emacs might crash when run in daemon mode and the X11 connection is unexpectedly lost.\n\
Using an Emacs configured with --with-x-toolkit=lucid does not have this problem.\n");
-#endif
+#endif /* USE_GTK */
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. */
+#else /* DAEMON_MUST_EXEC */
if (!dname_arg || !strchr (dname_arg, '\n'))
f = fork (); /* in orig */
else
f = 0; /* in exec'd */
-#endif /* NS_IMPL_COCOA */
+#endif /* !DAEMON_MUST_EXEC */
if (f > 0)
{
int retval;
exit (1);
}
-#ifdef NS_IMPL_COCOA
+#ifdef DAEMON_MUST_EXEC
{
/* In orig process, forked as child, OR in exec'd. */
if (!dname_arg || !strchr (dname_arg, '\n'))
dname_arg2);
dname_arg = *dname_arg2 ? dname_arg2 : NULL;
}
-#endif /* NS_IMPL_COCOA */
+#endif /* DAEMON_MUST_EXEC */
if (dname_arg)
daemon_name = xstrdup (dname_arg);
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 defined (HAVE_PTHREAD) && !defined (SYSTEM_MALLOC) && !defined (DOUG_LEA_MALLOC)
if (! noninteractive)
{
-#if defined (USG5) && defined (INTERRUPT_INPUT)
- setpgrp ();
-#endif
-#if defined (HAVE_PTHREAD) && !defined (SYSTEM_MALLOC) && !defined (DOUG_LEA_MALLOC)
- {
- extern void malloc_enable_thread (void);
+ extern void malloc_enable_thread (void);
- malloc_enable_thread ();
- }
-#endif
+ malloc_enable_thread ();
}
+#endif
init_signals (dumping);
/* Called before syms_of_fileio, because it sets up Qerror_condition. */
syms_of_data ();
+ syms_of_fns (); /* Before syms_of_charset which uses hashtables. */
syms_of_fileio ();
/* Before syms_of_coding to initialize Vgc_cons_threshold. */
syms_of_alloc ();
init_window_once (); /* Init the window system. */
#ifdef HAVE_WINDOW_SYSTEM
- init_fringe_once (); /* Swap bitmaps if necessary. */
+ init_fringe_once (); /* Swap bitmaps if necessary. */
#endif /* HAVE_WINDOW_SYSTEM */
}
globals_of_w32 ();
/* Initialize environment from registry settings. */
init_environment (argv);
- init_ntproc (); /* must precede init_editfns. */
+ init_ntproc (dumping); /* must precede init_editfns. */
#endif
/* Initialize and GC-protect Vinitial_environment and
don't pollute Vglobal_environment. */
/* Setting LANG here will defeat the startup locale processing... */
#ifdef AIX
- putenv ("LANG=C");
+ xputenv ("LANG=C");
#endif
init_buffer (); /* Init default directory of main buffer. */
syms_of_lread ();
syms_of_print ();
syms_of_eval ();
- syms_of_fns ();
syms_of_floatfns ();
syms_of_buffer ();
#ifdef WINDOWSNT
syms_of_ntproc ();
#endif /* WINDOWSNT */
+#if defined CYGWIN && defined HAVE_NTGUI
+ syms_of_cygw32 ();
+#endif
syms_of_window ();
syms_of_xdisp ();
syms_of_font ();
#ifdef HAVE_NTGUI
syms_of_w32term ();
syms_of_w32fns ();
- syms_of_w32select ();
syms_of_w32menu ();
syms_of_fontset ();
#endif /* HAVE_NTGUI */
+#if defined WINDOWSNT || defined HAVE_NTGUI
+ syms_of_w32select ();
+#endif
+
#ifdef MSDOS
syms_of_xmenu ();
syms_of_dosfns ();
syms_of_ntterm ();
#endif /* WINDOWSNT */
+ syms_of_profiler ();
+
keys_of_casefiddle ();
keys_of_cmds ();
keys_of_buffer ();
globals_of_w32font ();
globals_of_w32fns ();
globals_of_w32menu ();
- globals_of_w32select ();
#endif /* HAVE_NTGUI */
+
+#if defined WINDOWSNT || defined HAVE_NTGUI
+ globals_of_w32select ();
+#endif
}
init_charset ();
exit_code = (XINT (arg) < 0
? XINT (arg) | INT_MIN
: XINT (arg) & INT_MAX);
- else if (noninteractive && (fflush (stdout) || ferror (stdout)))
- exit_code = EXIT_FAILURE;
else
exit_code = EXIT_SUCCESS;
exit (exit_code);
/* If we are controlling the terminal, reset terminal modes. */
#ifndef DOS_NT
{
- int pgrp = EMACS_GETPGRP (0);
- int tpgrp = tcgetpgrp (0);
+ pid_t pgrp = getpgrp ();
+ pid_t tpgrp = tcgetpgrp (0);
if ((tpgrp != -1) && tpgrp == pgrp)
{
reset_all_sys_modes ();
static char const format[] = "Fatal error %d: ";
char buf[sizeof format - 2 + INT_STRLEN_BOUND (int)];
int buflen = sprintf (buf, format, sig);
- char const *sig_desc = strsignal (sig);
+ char const *sig_desc = safe_strsignal (sig);
ignore_value (write (STDERR_FILENO, buf, buflen));
ignore_value (write (STDERR_FILENO, sig_desc, strlen (sig_desc)));
}
unrequest_sigio ();
ignore_sigio ();
-#ifdef WINDOWSNT
- term_ntproc ();
-#endif
-
/* Do this only if terminating normally, we want glyph matrices
etc. in a core dump. */
if (sig == 0 || sig == SIGTERM)
#ifdef HAVE_LIBXML2
xml_cleanup_parser ();
#endif
+
+#ifdef WINDOWSNT
+ term_ntproc (0);
+#endif
}
free (malloc_state_ptr);
#endif
+#ifdef WINDOWSNT
+ Vlibrary_cache = Qnil;
+#endif
+#ifdef HAVE_WINDOW_SYSTEM
+ reset_image_types ();
+#endif
+
Vpurify_flag = tem;
return unbind_to (count, Qnil);
Vdynamic_library_alist = Qnil;
Fput (intern_c_string ("dynamic-library-alist"), Qrisky_local_variable, Qt);
+#ifdef WINDOWSNT
+ Vlibrary_cache = Qnil;
+ staticpro (&Vlibrary_cache);
+#endif
+
/* Make sure IS_DAEMON starts up as false. */
daemon_pipe[1] = 0;
}