X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/e390b7b54651d3c5a4c36168e84e96e197631f41..63750fd4ed4ff8bb9b3ff8868d4e36e3422adb21:/src/emacs.c diff --git a/src/emacs.c b/src/emacs.c index a51df0903b..53bcc9879a 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -54,18 +54,18 @@ along with GNU Emacs. If not, see . */ #ifdef MSDOS #include +#include "dosfns.h" #endif #ifdef HAVE_LIBSYSTEMD -#include -#include -#endif /* HAVE_LIBSYSTEMD */ +# include +# include +#endif #ifdef HAVE_WINDOW_SYSTEM #include TERM_HEADER #endif /* HAVE_WINDOW_SYSTEM */ -#include "coding.h" #include "intervals.h" #include "character.h" #include "buffer.h" @@ -90,6 +90,7 @@ along with GNU Emacs. If not, see . */ #include "systime.h" #include "puresize.h" +#include "getpagesize.h" #include "gnutls.h" #if (defined PROFILING \ @@ -111,10 +112,6 @@ extern void moncontrol (int mode); #include #endif -#ifdef HAVE_PERSONALITY_LINUX32 -#include -#endif - static const char emacs_version[] = PACKAGE_VERSION; static const char emacs_copyright[] = COPYRIGHT; static const char emacs_bugreport[] = PACKAGE_BUGREPORT; @@ -671,9 +668,6 @@ main (int argc, char **argv) bool do_initial_setlocale; bool dumping; int skip_args = 0; -#ifdef HAVE_SETRLIMIT - struct rlimit rlim; -#endif bool no_loadup = 0; char *junk = 0; char *dname_arg = 0; @@ -681,15 +675,36 @@ main (int argc, char **argv) char dname_arg2[80]; #endif char *ch_to_dir = 0; -#ifdef HAVE_LIBSYSTEMD - int systemd_socket; -#endif /* If we use --chdir, this records the original directory. */ char *original_pwd = 0; stack_base = &dummy; + dumping = !initialized && (strcmp (argv[argc - 1], "dump") == 0 + || strcmp (argv[argc - 1], "bootstrap") == 0); + + /* True if address randomization interferes with memory allocaiton. */ +# ifdef __PPC64__ + bool disable_aslr = true; +# else + bool disable_aslr = dumping; +# endif + + if (disable_aslr && disable_address_randomization ()) + { + /* Set this so the personality will be reverted before execs + after this one. */ + xputenv ("EMACS_HEAP_EXEC=true"); + + /* Address randomization was enabled, but is now disabled. + Re-execute Emacs to get a clean slate. */ + execvp (argv[0], argv); + + /* If the exec fails, warn and then try anyway. */ + perror (argv[0]); + } + #ifndef CANNOT_DUMP might_dump = !initialized; #endif @@ -798,28 +813,6 @@ main (int argc, char **argv) } } - dumping = !initialized && (strcmp (argv[argc - 1], "dump") == 0 - || strcmp (argv[argc - 1], "bootstrap") == 0); - -#ifdef HAVE_PERSONALITY_LINUX32 - if (dumping && ! getenv ("EMACS_HEAP_EXEC")) - { - /* Set this so we only do this once. */ - xputenv ("EMACS_HEAP_EXEC=true"); - - /* 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); -#undef ADD_NO_RANDOMIZE - - execvp (argv[0], argv); - - /* If the exec fails, try to dump anyway. */ - emacs_perror (argv[0]); - } -#endif /* HAVE_PERSONALITY_LINUX32 */ - #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 @@ -827,38 +820,54 @@ main (int argc, char **argv) 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) -#endif - && !getrlimit (RLIMIT_STACK, &rlim)) + struct rlimit rlim; + if (getrlimit (RLIMIT_STACK, &rlim) == 0 + && 0 <= rlim.rlim_cur && rlim.rlim_cur <= LONG_MAX) { - long newlim; - /* Approximate the amount regex.c needs per unit of re_max_failures. */ + long lim = rlim.rlim_cur; + + /* Approximate the amount regex.c needs per unit of + re_max_failures, then add 33% to cover the size of the + smaller stacks that regex.c successively allocates and + discards on its way to the maximum. */ int ratio = 20 * sizeof (char *); - /* Then add 33% to cover the size of the smaller stacks that regex.c - successively allocates and discards, on its way to the maximum. */ ratio += ratio / 3; - /* Add in some extra to cover - what we're likely to use for other reasons. */ - newlim = re_max_failures * ratio + 200000; -#ifdef __NetBSD__ - /* NetBSD (at least NetBSD 1.2G and former) has a bug in its - stack allocation routine for new process that the allocation - fails if stack limit is not on page boundary. So, round up the - new limit to page boundary. */ - newlim = (newlim + getpagesize () - 1) / getpagesize () * getpagesize (); -#endif - if (newlim > rlim.rlim_max) + + /* Extra space to cover what we're likely to use for other reasons. */ + int extra = 200000; + + bool try_to_grow_stack = true; +#ifndef CANNOT_DUMP + try_to_grow_stack = !noninteractive || initialized; +#endif + + if (try_to_grow_stack) { - newlim = rlim.rlim_max; - /* Don't let regex.c overflow the stack we have. */ - re_max_failures = (newlim - 200000) / ratio; + long newlim = re_max_failures * ratio + extra; + + /* Round the new limit to a page boundary; this is needed + for Darwin kernel 15.4.0 (see Bug#23622) and perhaps + other systems. Do not shrink the stack and do not exceed + rlim_max. Don't worry about exact values of + RLIM_INFINITY etc. since in practice when they are + nonnegative they are so large that the code does the + right thing anyway. */ + long pagesize = getpagesize (); + newlim += pagesize - 1; + if (0 <= rlim.rlim_max && rlim.rlim_max < newlim) + newlim = rlim.rlim_max; + newlim -= newlim % pagesize; + + if (pagesize <= newlim - lim) + { + rlim.rlim_cur = newlim; + if (setrlimit (RLIMIT_STACK, &rlim) == 0) + lim = newlim; + } } - if (rlim.rlim_cur < newlim) - rlim.rlim_cur = newlim; - setrlimit (RLIMIT_STACK, &rlim); + /* Don't let regex.c overflow the stack. */ + re_max_failures = lim < extra ? 0 : min (lim - extra, SIZE_MAX) / ratio; } #endif /* HAVE_SETRLIMIT and RLIMIT_STACK and not CYGWIN */ @@ -974,6 +983,9 @@ main (int argc, char **argv) w32_daemon_event = NULL; #endif + + int sockfd = -1; + if (argmatch (argv, argc, "-daemon", "--daemon", 5, NULL, &skip_args) || argmatch (argv, argc, "-daemon", "--daemon", 5, &dname_arg, &skip_args)) { @@ -1008,17 +1020,18 @@ main (int argc, char **argv) } #ifdef HAVE_LIBSYSTEMD - /* Read the number of sockets passed through by systemd. */ - systemd_socket = sd_listen_fds(1); + /* Read the number of sockets passed through by systemd. */ + int systemd_socket = sd_listen_fds (1); if (systemd_socket > 1) - fprintf (stderr, "\nWarning: systemd has passed more than one socket to the Emacs process.\n\ -Try adding 'Accept=false' in the Emacs socket unit file.\n"); - - else if (systemd_socket == 1 && - sd_is_socket (SD_LISTEN_FDS_START, - AF_UNSPEC, SOCK_STREAM, 1) >= 0) - set_external_socket_descriptor (SD_LISTEN_FDS_START); + fprintf (stderr, + ("\n" + "Warning: systemd passed more than one socket to Emacs.\n" + "Try 'Accept=false' in the Emacs socket unit file.\n")); + else if (systemd_socket == 1 + && (0 < sd_is_socket (SD_LISTEN_FDS_START, + AF_UNSPEC, SOCK_STREAM, 1))) + sockfd = SD_LISTEN_FDS_START; #endif /* HAVE_LIBSYSTEMD */ #ifndef DAEMON_MUST_EXEC @@ -1336,16 +1349,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem globals_of_gfilenotify (); #endif -#ifdef WINDOWSNT - globals_of_w32 (); -#ifdef HAVE_W32NOTIFY - globals_of_w32notify (); -#endif - /* Initialize environment from registry settings. */ - init_environment (argv); - init_ntproc (dumping); /* must precede init_editfns. */ -#endif - #ifdef HAVE_NS /* Initialize the locale from user defaults. */ ns_init_locale (); @@ -1362,6 +1365,20 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem if (! dumping) set_initial_environment (); +#ifdef WINDOWSNT + globals_of_w32 (); +#ifdef HAVE_W32NOTIFY + globals_of_w32notify (); +#endif + /* Initialize environment from registry settings. Make sure to do + this only after calling set_initial_environment so that + Vinitial_environment and Vprocess_environment will contain only + variables from the parent process without modifications from + Emacs. */ + init_environment (argv); + init_ntproc (dumping); /* must precede init_editfns. */ +#endif + /* AIX crashes are reported in system versions 3.2.3 and 3.2.4 if this is not done. Do it after set_global_environment so that we don't pollute Vglobal_environment. */ @@ -1577,7 +1594,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem /* 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_process_emacs (sockfd); init_keyboard (); /* This too must precede init_sys_modes. */ if (!noninteractive) @@ -2210,6 +2227,15 @@ synchronize_system_messages_locale (void) #endif } #endif /* HAVE_SETLOCALE */ + +/* Return a diagnostic string for ERROR_NUMBER, in the wording + and encoding appropriate for the current locale. */ +char * +emacs_strerror (int error_number) +{ + synchronize_system_messages_locale (); + return strerror (error_number); +} Lisp_Object