You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include <signal.h>
#include <ssdef.h>
#endif
-#ifdef BSD
+#ifdef BSD_SYSTEM
#include <sys/ioctl.h>
#endif
#include "intervals.h"
#include "systty.h"
+#include "blockinput.h"
#include "syssignal.h"
#include "process.h"
+#ifdef HAVE_SETRLIMIT
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+
#ifndef O_RDWR
#define O_RDWR 2
#endif
extern void malloc_warning ();
+extern void set_time_zone_rule ();
extern char *index ();
extern char *strerror ();
on subsequent starts. */
int initialized;
+#ifdef DOUG_LEA_MALLOC
+/* Preserves a pointer to the memory allocated that copies that
+ static data inside glibc's malloc. */
+void *malloc_state_ptr;
+/* From glibc, a routine that returns a copy of the malloc internal state. */
+extern void *malloc_get_state ();
+/* From glibc, a routine that overwrites the malloc internal state. */
+extern void malloc_set_state ();
+#endif
+
/* Variable whose value is symbol giving operating system type. */
Lisp_Object Vsystem_type;
for use when reporting bugs. */
Lisp_Object Vsystem_configuration_options;
+Lisp_Object Qfile_name_handler_alist;
+
/* If non-zero, emacs should not attempt to use an window-specific code,
but instead should use the virtual terminal under which it was started */
int inhibit_window_system;
fatal_error_code = sig;
signal (sig, SIG_DFL);
+ TOTALLY_UNBLOCK_INPUT;
+
/* If fatal error occurs in code below, avoid infinite recursion. */
if (! fatal_error_in_progress)
{
int skip_args;
{
register int i;
- Lisp_Object name, dir;
+ Lisp_Object name, dir, tem;
+ int count = specpdl_ptr - specpdl;
+ Lisp_Object raw_name;
initial_argv = argv;
initial_argc = argc;
- Vinvocation_name = Ffile_name_nondirectory (build_string (argv[0]));
- Vinvocation_directory = Ffile_name_directory (build_string (argv[0]));
+ raw_name = build_string (argv[0]);
+
+ /* Add /: to the front of the name
+ if it would otherwise be treated as magic. */
+ tem = Ffind_file_name_handler (raw_name, Qt);
+ if (! NILP (tem))
+ raw_name = concat2 (build_string ("/:"), raw_name);
+
+ Vinvocation_name = Ffile_name_nondirectory (raw_name);
+ Vinvocation_directory = Ffile_name_directory (raw_name);
+
/* If we got no directory in argv[0], search PATH to find where
Emacs actually came from. */
if (NILP (Vinvocation_directory))
int yes = openp (Vexec_path, Vinvocation_name,
EXEC_SUFFIXES, &found, 1);
if (yes == 1)
- Vinvocation_directory = Ffile_name_directory (found);
+ {
+ /* Add /: to the front of the name
+ if it would otherwise be treated as magic. */
+ tem = Ffind_file_name_handler (found, Qt);
+ if (! NILP (tem))
+ found = concat2 (build_string ("/:"), found);
+ Vinvocation_directory = Ffile_name_directory (found);
+ }
}
if (!NILP (Vinvocation_directory)
&& NILP (Ffile_name_absolute_p (Vinvocation_directory)))
- /* Emacs was started with relative path, like ./emacs */
+ /* Emacs was started with relative path, like ./emacs.
+ Make it absolute. */
Vinvocation_directory = Fexpand_file_name (Vinvocation_directory, Qnil);
Vinstallation_directory = Qnil;
not including lisp and info. */
tem = Fexpand_file_name (build_string ("lib-src"), dir);
lib_src_exists = Ffile_exists_p (tem);
- if (!NILP (lib_src_exists))
+
+#ifdef MSDOS
+ /* MSDOS installations frequently remove lib-src, but we still
+ must set installation-directory, or else info won't find
+ its files (it uses the value of installation-directory). */
+ tem = Fexpand_file_name (build_string ("info"), dir);
+ info_exists = Ffile_exists_p (tem);
+#else
+ info_exists = Qnil;
+#endif
+
+ if (!NILP (lib_src_exists) || !NILP (info_exists))
{
tem = Fexpand_file_name (build_string ("etc"), dir);
etc_exists = Ffile_exists_p (tem);
/* See if dir's parent contains those subdirs. */
tem = Fexpand_file_name (build_string ("../lib-src"), dir);
lib_src_exists = Ffile_exists_p (tem);
- if (!NILP (lib_src_exists))
+
+
+#ifdef MSDOS
+ /* See the MSDOS commentary above. */
+ tem = Fexpand_file_name (build_string ("../info"), dir);
+ info_exists = Ffile_exists_p (tem);
+#else
+ info_exists = Qnil;
+#endif
+
+ if (!NILP (lib_src_exists) || !NILP (info_exists))
{
tem = Fexpand_file_name (build_string ("../etc"), dir);
etc_exists = Ffile_exists_p (tem);
Vcommand_line_args
= Fcons (build_string (argv[i]), Vcommand_line_args);
}
+
+ unbind_to (count, Qnil);
}
DEFUN ("invocation-name", Finvocation_name, Sinvocation_name, 0, 0, 0,
\f
#ifdef VMS
#ifdef LINK_CRTL_SHARE
-#ifdef SHAREABLE_LIB_BUG
+#ifdef SHARABLE_LIB_BUG
extern noshare char **environ;
-#endif /* SHAREABLE_LIB_BUG */
+#endif /* SHARABLE_LIB_BUG */
#endif /* LINK_CRTL_SHARE */
#endif /* VMS */
+#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";
+#endif
+
#ifndef ORDINARY_LINK
/* We don't include crtbegin.o and crtend.o in the link,
so these functions and variables might be missed.
int skip_args = 0;
extern int errno;
extern sys_nerr;
+#ifdef HAVE_SETRLIMIT
+ struct rlimit rlim;
+#endif
+
+#ifdef LINUX_SBRK_BUG
+ __sbrk (1);
+#endif
+
+#ifdef DOUG_LEA_MALLOC
+ if (initialized)
+ {
+ malloc_set_state (malloc_state_ptr);
+ free (malloc_state_ptr);
+ }
+#endif
sort_args (argc, argv);
}
else
{
- printf ("%s\n", XSTRING (tem)->data);
+ printf ("GNU Emacs %s\n", XSTRING (tem)->data);
+ printf ("Copyright (C) 1996 Free Software Foundation, Inc.\n");
+ printf ("GNU Emacs comes with ABSOLUTELY NO WARRANTY.\n");
+ printf ("You may redistribute copies of Emacs\n");
+ printf ("under the terms of the GNU General Public License.\n");
+ printf ("For more information about these matters, ");
+ printf ("see the files named COPYING.\n");
exit (0);
}
}
}
#ifdef LINK_CRTL_SHARE
-#ifdef SHAREABLE_LIB_BUG
+#ifdef SHARABLE_LIB_BUG
/* Bletcherous shared libraries! */
if (!stdin)
stdin = fdopen (0, "r");
stderr = fdopen (2, "w");
if (!environ)
environ = envp;
-#endif /* SHAREABLE_LIB_BUG */
+#endif /* SHARABLE_LIB_BUG */
#endif /* LINK_CRTL_SHARE */
#endif /* VMS */
+#ifdef HAVE_SETRLIMIT
+ /* Extend the stack space available. */
+ if (!getrlimit (RLIMIT_STACK, &rlim))
+ {
+ long newlim;
+ /* Approximate the amount regex.c needs, plus some more. */
+ newlim = 800000 * sizeof (char *);
+ if (newlim > rlim.rlim_max)
+ newlim = rlim.rlim_max;
+ if (rlim.rlim_cur < newlim)
+ rlim.rlim_cur = newlim;
+
+ setrlimit (RLIMIT_STACK, &rlim);
+ }
+#endif
+
/* Record (approximately) where the stack begins. */
stack_bottom = &stack_bottom_variable;
/* We do all file input/output as binary files. When we need to translate
newlines, we do that manually. */
_fmode = O_BINARY;
+
+#if __DJGPP__ >= 2
+ if (!isatty (fileno (stdin)))
+ setmode (fileno (stdin), O_BINARY);
+ if (!isatty (fileno (stdout)))
+ {
+ fflush (stdout);
+ setmode (fileno (stdout), O_BINARY);
+ }
+#else /* not __DJGPP__ >= 2 */
(stdin)->_flag &= ~_IOTEXT;
(stdout)->_flag &= ~_IOTEXT;
(stderr)->_flag &= ~_IOTEXT;
+#endif /* not __DJGPP__ >= 2 */
#endif /* MSDOS */
#ifdef SET_EMACS_PRIORITY
[-q] [--no-init-file] [-u user] [--user user] [--debug-init]\n\
[--version] [--no-site-file]\n\
[-f func] [--funcall func] [-l file] [--load file] [--insert file]\n\
- [+linenum] file-to-visit [--kill]\n", argv[0]);
+ [+linenum] file-to-visit [--kill]\n\
+Report bugs to bug-gnu-emacs@prep.ai.mit.edu. First, please see\n\
+the Bugs section of the Emacs manual or the file BUGS.", argv[0]);
exit (0);
}
because we don't even know which window system dependent code
to run until we've recognized this argument. */
{
- char *displayname;
+ char *displayname = 0;
int i;
int count_before = skip_args;
/* Change --display to -d, when its arg is separate. */
else if (displayname != 0 && skip_args > count_before
&& argv[count_before + 1][1] == '-')
- argv[count_before] = "-d";
+ argv[count_before + 1] = "-d";
/* Don't actually discard this arg. */
skip_args = count_before;
init_signals ();
#endif
+ /* Don't catch SIGHUP if dumping. */
+ if (1
+#ifndef CANNOT_DUMP
+ && initialized
+#endif
+ )
+ {
+ sigblock (sigmask (SIGHUP));
+ /* In --batch mode, don't catch SIGHUP if already ignored.
+ That makes nohup work. */
+ if (! noninteractive
+ || signal (SIGHUP, SIG_IGN) != SIG_IGN)
+ signal (SIGHUP, fatal_error_signal);
+ sigunblock (sigmask (SIGHUP));
+ }
+
if (
#ifndef CANNOT_DUMP
! noninteractive || initialized
#endif
)
{
- /* Don't catch these signals in batch mode if not initialized.
+ /* Don't catch these signals in batch mode if dumping.
On some machines, this sets static data that would make
signal fail to work right when the dumped Emacs is run. */
- signal (SIGHUP, fatal_error_signal);
signal (SIGQUIT, fatal_error_signal);
signal (SIGILL, fatal_error_signal);
signal (SIGTRAP, fatal_error_signal);
init_alloc_once ();
init_obarray ();
init_eval_once ();
+ init_charset_once ();
+ init_coding_once ();
init_syntax_once (); /* Create standard syntax table. */
+ init_category_once (); /* Create standard category table. */
/* Must be done before init_buffer */
init_casetab_once ();
init_buffer_once (); /* Create buffer table and some buffers */
/* Call early 'cause init_environment needs it. */
init_dosfns ();
/* Set defaults for several environment variables. */
- if (initialized) init_environment (argc, argv, skip_args);
- else init_gettimeofday ();
-#endif
+ if (initialized)
+ init_environment (argc, argv, skip_args);
+ else
+ tzset ();
+#endif /* MSDOS */
#ifdef WINDOWSNT
/* Initialize environment from registry settings. */
init_environment ();
+ init_ntproc (); /* must precede init_editfns */
#endif
/* egetenv is a pretty low-level facility, which may get called in
init_callproc_1 (); /* Must precede init_cmdargs and init_sys_modes. */
init_cmdargs (argc, argv, skip_args); /* Must precede init_lread. */
+
+ if (initialized)
+ {
+ /* Erase any pre-dump messages in the message log, to avoid confusion */
+ Lisp_Object old_log_max;
+ old_log_max = Vmessage_log_max;
+ XSETFASTINT (Vmessage_log_max, 0);
+ message_dolog ("", 0, 1);
+ Vmessage_log_max = old_log_max;
+ }
+
init_callproc (); /* Must follow init_cmdargs but not init_sys_modes. */
init_lread ();
syms_of_casefiddle ();
syms_of_casetab ();
syms_of_callproc ();
+ syms_of_category ();
+ syms_of_ccl ();
+ syms_of_charset ();
syms_of_cmds ();
#ifndef NO_DIR_LIBRARY
syms_of_dired ();
syms_of_editfns ();
syms_of_emacs ();
syms_of_fileio ();
+ syms_of_coding (); /* This should be after syms_of_fileio. */
#ifdef CLASH_DETECTION
syms_of_filelock ();
#endif /* CLASH_DETECTION */
syms_of_indent ();
+ syms_of_insdel ();
syms_of_keyboard ();
syms_of_keymap ();
syms_of_macros ();
#ifdef VMS
syms_of_vmsproc ();
#endif /* VMS */
+#ifdef WINDOWSNT
+ syms_of_ntproc ();
+#endif /* WINDOWSNT */
syms_of_window ();
syms_of_xdisp ();
#ifdef HAVE_X_WINDOWS
syms_of_xterm ();
syms_of_xfns ();
syms_of_xfaces ();
+ syms_of_fontset ();
#ifdef HAVE_X11
syms_of_xselect ();
#endif
-#ifdef HAVE_X_MENU
- syms_of_xmenu ();
-#endif /* HAVE_X_MENU */
#endif /* HAVE_X_WINDOWS */
#if defined (MSDOS) && !defined (HAVE_X_WINDOWS)
syms_of_xfaces ();
+#endif
+
+#ifndef HAVE_NTGUI
syms_of_xmenu ();
#endif
#ifdef HAVE_NTGUI
- syms_of_win32term ();
- syms_of_win32fns ();
- syms_of_win32faces ();
- syms_of_win32select ();
- syms_of_win32menu ();
+ syms_of_w32term ();
+ syms_of_w32fns ();
+ syms_of_w32faces ();
+ syms_of_w32select ();
+ syms_of_w32menu ();
#endif /* HAVE_NTGUI */
#ifdef SYMS_SYSTEM
if (initialized)
{
- /* Erase any pre-dump messages in the message log, to avoid confusion */
- Lisp_Object old_log_max;
- old_log_max = Vmessage_log_max;
- XSETFASTINT (Vmessage_log_max, 0);
- message_dolog ("", 0, 1);
- Vmessage_log_max = old_log_max;
+#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
}
initialized = 1;
{ "-g", "--geometry", 10, 1 },
{ "-geometry", 0, 10, 1 },
{ "-T", "--title", 10, 1 },
+ { "-title", 0, 10, 1 },
{ "-name", "--name", 10, 1 },
{ "-xrm", "--xrm", 10, 1 },
{ "-r", "--reverse-video", 5, 0 },
{ "-rv", 0, 5, 0 },
{ "-reverse", 0, 5, 0 },
+ { "-hb", "--horizontal-scroll-bars", 5, 0 },
{ "-vb", "--vertical-scroll-bars", 5, 0 },
/* These have the same priority as ordinary file name args,
so they are not reordered with respect to those. */
{ "-f", "--funcall", 0, 1 },
{ "-funcall", 0, 0, 1 },
{ "-eval", "--eval", 0, 1 },
+ { "-find-file", "--find-file", 0, 1 },
+ { "-visit", "--visit", 0, 1 },
{ "-insert", "--insert", 0, 1 },
/* This should be processed after ordinary file name args and the like. */
{ "-kill", "--kill", -10, 0 },
int to = 1;
int from;
int i;
+ int end_of_options = argc;
/* Categorize all the options,
and figure out which argv elts are option arguments. */
int match, thislen;
char *equals;
+ /* If we have found "--", don't consider
+ any more arguments as options. */
+ if (argv[from][1] == '-')
+ {
+ /* Leave the "--", and everything following it, at the end. */
+ for (; from < argc; from++)
+ {
+ priority[from] = -100;
+ options[from] = -1;
+ }
+ break;
+ }
+
/* Look for a match with a known old-fashioned option. */
for (i = 0; i < sizeof (standard_args) / sizeof (standard_args[0]); 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]);
from += standard_args[i].nargs;
goto done;
}
this option uses just one argv element. */
if (equals != 0)
options[from] = 0;
+ if (from + options[from] >= argc)
+ fatal ("Option `%s' requires an argument\n", argv[from]);
from += options[from];
}
}
}
bcopy (new, argv, sizeof (char *) * argc);
+
+ free (options);
+ free (new);
+ free (priority);
}
\f
DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P",
unrequest_sigio ();
signal (SIGIO, SIG_IGN);
#endif
+
+#ifdef WINDOWSNT
+ term_ntproc ();
+#endif
}
DEFUN ("dump-emacs-data", Fdump_emacs_data, Sdump_emacs_data, 1, 1, 0,
"Dump current state of Emacs into data file FILENAME.\n\
This function exists on systems that use HAVE_SHM.")
- (intoname)
- Lisp_Object intoname;
+ (filename)
+ Lisp_Object filename;
{
extern char my_edata[];
Lisp_Object tem;
- CHECK_STRING (intoname, 0);
- intoname = Fexpand_file_name (intoname, Qnil);
+ CHECK_STRING (filename, 0);
+ filename = Fexpand_file_name (filename, Qnil);
tem = Vpurify_flag;
Vpurify_flag = Qnil;
#ifndef SYSTEM_MALLOC
memory_warnings (my_edata, malloc_warning);
#endif
- map_out_data (XSTRING (intoname)->data);
+ map_out_data (XSTRING (filename)->data);
Vpurify_flag = tem;
Bind `command-line-processed' to nil before dumping,\n\
if you want the dumped Emacs to process its command line\n\
and announce itself normally when it is run.")
- (intoname, symname)
- Lisp_Object intoname, symname;
+ (filename, symfile)
+ Lisp_Object filename, symfile;
{
extern char my_edata[];
Lisp_Object tem;
- CHECK_STRING (intoname, 0);
- intoname = Fexpand_file_name (intoname, Qnil);
- if (!NILP (symname))
+ CHECK_STRING (filename, 0);
+ filename = Fexpand_file_name (filename, Qnil);
+ if (!NILP (symfile))
{
- CHECK_STRING (symname, 0);
- if (XSTRING (symname)->size)
- symname = Fexpand_file_name (symname, Qnil);
+ CHECK_STRING (symfile, 0);
+ if (XSTRING (symfile)->size)
+ symfile = Fexpand_file_name (symfile, Qnil);
}
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);
#ifdef VMS
- mapout_data (XSTRING (intoname)->data);
+ mapout_data (XSTRING (filename)->data);
#else
/* Tell malloc where start of impure now is */
/* Also arrange for warnings when nearly out of space. */
memory_warnings (my_edata, malloc_warning);
#endif /* not WINDOWSNT */
#endif
- unexec (XSTRING (intoname)->data,
- !NILP (symname) ? XSTRING (symname)->data : 0, my_edata, 0, 0);
+#ifdef DOUG_LEA_MALLOC
+ malloc_state_ptr = malloc_get_state ();
+#endif
+ unexec (XSTRING (filename)->data,
+ !NILP (symfile) ? XSTRING (symfile)->data : 0, my_edata, 0, 0);
+#ifdef DOUG_LEA_MALLOC
+ free (malloc_state_ptr);
+#endif
#endif /* not VMS */
Vpurify_flag = tem;
char *evarname, *defalt;
{
register char *path, *p;
-
- Lisp_Object lpath;
+ Lisp_Object lpath, element, tem;
/* It's okay to use getenv here, because this function is only used
to initialize variables when Emacs starts up, and isn't called
{
p = index (path, SEPCHAR);
if (!p) p = path + strlen (path);
- lpath = Fcons (p - path ? make_string (path, p - path)
- : build_string ("."),
- lpath);
+ element = (p - path ? make_string (path, p - path)
+ : build_string ("."));
+
+ /* Add /: to the front of the name
+ if it would otherwise be treated as magic. */
+ tem = Ffind_file_name_handler (element, Qt);
+ if (! NILP (tem))
+ element = concat2 (build_string ("/:"), element);
+
+ lpath = Fcons (element, lpath);
if (*p)
path = p + 1;
else
syms_of_emacs ()
{
+ Qfile_name_handler_alist = intern ("file-name-handler-alist");
+ staticpro (&Qfile_name_handler_alist);
+
#ifndef CANNOT_DUMP
#ifdef HAVE_SHM
defsubr (&Sdump_emacs_data);