1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
20
21
22 #include <config.h>
23 #include <signal.h>
24 #include <errno.h>
25 #include <stdio.h>
26
27 #include <sys/types.h>
28 #include <sys/file.h>
29 #include <setjmp.h>
30
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34
35 #ifdef HAVE_SYS_IOCTL_H
36 #include <sys/ioctl.h>
37 #endif
38
39 #ifdef WINDOWSNT
40 #include <fcntl.h>
41 #include <windows.h>
42 #include "w32.h"
43 #include "w32heap.h"
44 #endif
45
46 #ifdef NS_IMPL_GNUSTEP
47
48 #include <GNUstepBase/GSConfig.h>
49 #endif
50
51 #include "lisp.h"
52 #include "commands.h"
53 #include "intervals.h"
54 #include "buffer.h"
55 #include "window.h"
56
57 #include "systty.h"
58 #include "blockinput.h"
59 #include "syssignal.h"
60 #include "process.h"
61 #include "frame.h"
62 #include "termhooks.h"
63 #include "keyboard.h"
64 #include "keymap.h"
65
66 #ifdef HAVE_SETLOCALE
67 #include <locale.h>
68 #endif
69
70 #ifdef HAVE_SETRLIMIT
71 #include <sys/time.h>
72 #include <sys/resource.h>
73 #endif
74
75 #ifdef HAVE_PERSONALITY_LINUX32
76 #include <sys/personality.h>
77 #endif
78
79 #ifndef O_RDWR
80 #define O_RDWR 2
81 #endif
82
83 #ifdef HAVE_SETPGID
84 #if !defined (USG)
85 #undef setpgrp
86 #define setpgrp setpgid
87 #endif
88 #endif
89
90 const char emacs_copyright[] = "Copyright (C) 2010 Free Software Foundation, Inc.";
91 const char emacs_version[] = "24.0.50";
92
93 extern void malloc_warning P_ ((char *));
94 extern void set_time_zone_rule P_ ((char *));
95 #ifdef HAVE_INDEX
96 extern char *index P_ ((const char *, int));
97 #endif
98
99
100
101 #ifdef USE_LSB_TAG
102 int gdb_use_lsb = 1;
103 #else
104 int gdb_use_lsb = 0;
105 #endif
106 #ifndef USE_LISP_UNION_TYPE
107 int gdb_use_union = 0;
108 #else
109 int gdb_use_union = 1;
110 #endif
111 EMACS_INT gdb_valbits = VALBITS;
112 EMACS_INT gdb_gctypebits = GCTYPEBITS;
113 #if defined (DATA_SEG_BITS) && ! defined (USE_LSB_TAG)
114 EMACS_INT gdb_data_seg_bits = DATA_SEG_BITS;
115 #else
116 EMACS_INT gdb_data_seg_bits = 0;
117 #endif
118 EMACS_INT PVEC_FLAG = PSEUDOVECTOR_FLAG;
119 EMACS_INT gdb_array_mark_flag = ARRAY_MARK_FLAG;
120 121
122 enum pvec_type gdb_pvec_type = PVEC_TYPE_MASK;
123
124
125 Lisp_Object Vcommand_line_args;
126
127 128
129 Lisp_Object Vinvocation_name;
130
131
132 Lisp_Object Vinvocation_directory;
133
134 135
136 Lisp_Object Vinstallation_directory;
137
138
139 Lisp_Object Vbefore_init_time, Vafter_init_time;
140
141
142 Lisp_Object Vkill_emacs_hook;
143
144
145 Lisp_Object empty_unibyte_string, empty_multibyte_string;
146
147
148 Lisp_Object Vpath_separator;
149
150 151 152
153 int initialized;
154
155 #ifdef DOUG_LEA_MALLOC
156 157
158 void *malloc_state_ptr;
159
160 extern void *malloc_get_state ();
161
162 extern int malloc_set_state ();
163 164
165 int malloc_using_checking;
166 #endif
167
168
169 Lisp_Object Vsystem_type;
170
171
172 Lisp_Object Vsystem_configuration;
173
174 175
176 Lisp_Object Vsystem_configuration_options;
177
178 Lisp_Object Qfile_name_handler_alist;
179
180
181 Lisp_Object Vsystem_messages_locale;
182 Lisp_Object Vprevious_system_messages_locale;
183 Lisp_Object Vsystem_time_locale;
184 Lisp_Object Vprevious_system_time_locale;
185
186 187
188 Lisp_Object Vemacs_copyright, Vemacs_version;
189
190 191
192 int inhibit_window_system;
193
194 195 196
197 EMACS_INT emacs_priority;
198
199 200
201 int running_asynch_code;
202
203 #if defined(HAVE_X_WINDOWS) || defined(HAVE_NS)
204
205 int display_arg;
206 #endif
207
208 209
210 char *stack_bottom;
211
212
213 static void *my_heap_start;
214
215
216 static unsigned long heap_bss_diff;
217
218 219
220 #define MAX_HEAP_BSS_DIFF (1024*1024)
221
222
223 #ifdef HAVE_WINDOW_SYSTEM
224 extern Lisp_Object Vinitial_window_system;
225 #endif
226
227 extern Lisp_Object Vauto_save_list_file_name;
228
229 extern Lisp_Object Vinhibit_redisplay;
230
231
232
233 int noninteractive;
234
235 236 237
238
239 int noninteractive1;
240
241
242 int inhibit_x_resources;
243
244
245 static char *daemon_name;
246
247 248
249 int daemon_pipe[2];
250
251
252 char **initial_argv;
253 int initial_argc;
254
255 static void sort_args ();
256 void syms_of_emacs ();
257
258 259
260 #define USAGE1 "\
261 Usage: %s [OPTION-OR-FILENAME]...\n\
262 \n\
263 Run Emacs, the extensible, customizable, self-documenting real-time\n\
264 display editor. The recommended way to start Emacs for normal editing\n\
265 is with no options at all.\n\
266 \n\
267 Run M-x info RET m emacs RET m emacs invocation RET inside Emacs to\n\
268 read the main documentation for these command-line arguments.\n\
269 \n\
270 Initialization options:\n\
271 \n\
272 --batch do not do interactive display; implies -q\n\
273 --chdir DIR change to directory DIR\n\
274 --daemon start a server in the background\n\
275 --debug-init enable Emacs Lisp debugger for init file\n\
276 --display, -d DISPLAY use X server DISPLAY\n\
277 --no-desktop do not load a saved desktop\n\
278 --no-init-file, -q load neither ~/.emacs nor default.el\n\
279 --no-shared-memory, -nl do not use shared memory\n\
280 --no-site-file do not load site-start.el\n\
281 --no-splash do not display a splash screen on startup\n\
282 --no-window-system, -nw do not communicate with X, ignoring $DISPLAY\n\
283 --quick, -Q equivalent to -q --no-site-file --no-splash\n\
284 --script FILE run FILE as an Emacs Lisp script\n\
285 --terminal, -t DEVICE use DEVICE for terminal I/O\n\
286 --user, -u USER load ~USER/.emacs instead of your own\n\
287 \n%s"
288
289 #define USAGE2 "\
290 Action options:\n\
291 \n\
292 FILE visit FILE using find-file\n\
293 +LINE go to line LINE in next FILE\n\
294 +LINE:COLUMN go to line LINE, column COLUMN, in next FILE\n\
295 --directory, -L DIR add DIR to variable load-path\n\
296 --eval EXPR evaluate Emacs Lisp expression EXPR\n\
297 --execute EXPR evaluate Emacs Lisp expression EXPR\n\
298 --file FILE visit FILE using find-file\n\
299 --find-file FILE visit FILE using find-file\n\
300 --funcall, -f FUNC call Emacs Lisp function FUNC with no arguments\n\
301 --insert FILE insert contents of FILE into current buffer\n\
302 --kill exit without asking for confirmation\n\
303 --load, -l FILE load Emacs Lisp FILE using the load function\n\
304 --visit FILE visit FILE using find-file\n\
305 \n"
306
307 #define USAGE3 "\
308 Display options:\n\
309 \n\
310 --background-color, -bg COLOR window background color\n\
311 --basic-display, -D disable many display features;\n\
312 used for debugging Emacs\n\
313 --border-color, -bd COLOR main border color\n\
314 --border-width, -bw WIDTH width of main border\n\
315 --color, --color=MODE override color mode for character terminals;\n\
316 MODE defaults to `auto', and can also\n\
317 be `never', `auto', `always',\n\
318 or a mode name like `ansi8'\n\
319 --cursor-color, -cr COLOR color of the Emacs cursor indicating point\n\
320 --font, -fn FONT default font; must be fixed-width\n\
321 --foreground-color, -fg COLOR window foreground color\n\
322 --fullheight, -fh make the first frame high as the screen\n\
323 --fullscreen, -fs make first frame fullscreen\n\
324 --fullwidth, -fw make the first frame wide as the screen\n\
325 --maximized, -mm make the first frame maximized\n\
326 --geometry, -g GEOMETRY window geometry\n\
327 --no-bitmap-icon, -nbi do not use picture of gnu for Emacs icon\n\
328 --iconic start Emacs in iconified state\n\
329 --internal-border, -ib WIDTH width between text and main border\n\
330 --line-spacing, -lsp PIXELS additional space to put between lines\n\
331 --mouse-color, -ms COLOR mouse cursor color in Emacs window\n\
332 --name NAME title for initial Emacs frame\n\
333 --no-blinking-cursor, -nbc disable blinking cursor\n\
334 --reverse-video, -r, -rv switch foreground and background\n\
335 --title, -T TITLE title for initial Emacs frame\n\
336 --vertical-scroll-bars, -vb enable vertical scroll bars\n\
337 --xrm XRESOURCES set additional X resources\n\
338 --parent-id XID set parent window\n\
339 --help display this help and exit\n\
340 --version output version information and exit\n\
341 \n"
342
343 #define USAGE4 "\
344 You can generally also specify long option names with a single -; for\n\
345 example, -batch as well as --batch. You can use any unambiguous\n\
346 abbreviation for a --option.\n\
347 \n\
348 Various environment variables and window system resources also affect\n\
349 Emacs' operation. See the main documentation.\n\
350 \n\
351 Report bugs to bug-gnu-emacs@gnu.org. First, please see the Bugs\n\
352 section of the Emacs manual or the file BUGS.\n"
353
354
355
356 int fatal_error_code;
357
358
359 int fatal_error_in_progress;
360
361 362
363
364 void (*fatal_error_signal_hook) P_ ((void));
365
366 #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
367 368 369
370
371 pthread_t main_thread;
372 #endif
373
374
375
376 SIGTYPE
377 fatal_error_signal (sig)
378 int sig;
379 {
380 SIGNAL_THREAD_CHECK (sig);
381 fatal_error_code = sig;
382 signal (sig, SIG_DFL);
383
384 TOTALLY_UNBLOCK_INPUT;
385
386
387 if (! fatal_error_in_progress)
388 {
389 fatal_error_in_progress = 1;
390
391 if (sig == SIGTERM || sig == SIGHUP)
392 Fkill_emacs (make_number (sig));
393
394 shut_down_emacs (sig, 0, Qnil);
395 }
396
397 398 399 400
401 #ifndef MSDOS
402 sigunblock (sigmask (fatal_error_code));
403 #endif
404
405 if (fatal_error_signal_hook)
406 fatal_error_signal_hook ();
407
408 kill (getpid (), fatal_error_code);
409 }
410
411 #ifdef SIGDANGER
412
413
414 SIGTYPE
415 memory_warning_signal (sig)
416 int sig;
417 {
418 signal (sig, memory_warning_signal);
419 SIGNAL_THREAD_CHECK (sig);
420
421 malloc_warning ("Operating system warns that virtual memory is running low.\n");
422
423
424 force_auto_save_soon ();
425 }
426 #endif
427
428 429 430
431
432 #if ! defined (DOS_NT) && ! defined (NO_ABORT)
433
434 void
435 abort ()
436 {
437 kill (getpid (), SIGABRT);
438
439 exit (1);
440 }
441 #endif
442
443
444
445
446 static void
447 init_cmdargs (argc, argv, skip_args)
448 int argc;
449 char **argv;
450 int skip_args;
451 {
452 register int i;
453 Lisp_Object name, dir, tem;
454 int count = SPECPDL_INDEX ();
455 Lisp_Object raw_name;
456
457 initial_argv = argv;
458 initial_argc = argc;
459
460 raw_name = build_string (argv[0]);
461
462 463
464 tem = Ffind_file_name_handler (raw_name, Qt);
465 if (! NILP (tem))
466 raw_name = concat2 (build_string ("/:"), raw_name);
467
468 Vinvocation_name = Ffile_name_nondirectory (raw_name);
469 Vinvocation_directory = Ffile_name_directory (raw_name);
470
471 472
473 if (NILP (Vinvocation_directory))
474 {
475 Lisp_Object found;
476 int yes = openp (Vexec_path, Vinvocation_name,
477 Vexec_suffixes, &found, make_number (X_OK));
478 if (yes == 1)
479 {
480 481
482 tem = Ffind_file_name_handler (found, Qt);
483 if (! NILP (tem))
484 found = concat2 (build_string ("/:"), found);
485 Vinvocation_directory = Ffile_name_directory (found);
486 }
487 }
488
489 if (!NILP (Vinvocation_directory)
490 && NILP (Ffile_name_absolute_p (Vinvocation_directory)))
491 492
493 Vinvocation_directory = Fexpand_file_name (Vinvocation_directory, Qnil);
494
495 Vinstallation_directory = Qnil;
496
497 if (!NILP (Vinvocation_directory))
498 {
499 dir = Vinvocation_directory;
500 name = Fexpand_file_name (Vinvocation_name, dir);
501 while (1)
502 {
503 Lisp_Object tem, lib_src_exists;
504 Lisp_Object etc_exists, info_exists;
505
506 507 508
509 tem = Fexpand_file_name (build_string ("lib-src"), dir);
510 lib_src_exists = Ffile_exists_p (tem);
511
512 #ifdef MSDOS
513 514 515
516 tem = Fexpand_file_name (build_string ("info"), dir);
517 info_exists = Ffile_exists_p (tem);
518 #else
519 info_exists = Qnil;
520 #endif
521
522 if (!NILP (lib_src_exists) || !NILP (info_exists))
523 {
524 tem = Fexpand_file_name (build_string ("etc"), dir);
525 etc_exists = Ffile_exists_p (tem);
526 if (!NILP (etc_exists))
527 {
528 Vinstallation_directory
529 = Ffile_name_as_directory (dir);
530 break;
531 }
532 }
533
534
535 tem = Fexpand_file_name (build_string ("../lib-src"), dir);
536 lib_src_exists = Ffile_exists_p (tem);
537
538
539 #ifdef MSDOS
540
541 tem = Fexpand_file_name (build_string ("../info"), dir);
542 info_exists = Ffile_exists_p (tem);
543 #else
544 info_exists = Qnil;
545 #endif
546
547 if (!NILP (lib_src_exists) || !NILP (info_exists))
548 {
549 tem = Fexpand_file_name (build_string ("../etc"), dir);
550 etc_exists = Ffile_exists_p (tem);
551 if (!NILP (etc_exists))
552 {
553 tem = Fexpand_file_name (build_string (".."), dir);
554 Vinstallation_directory
555 = Ffile_name_as_directory (tem);
556 break;
557 }
558 }
559
560 561
562 tem = Ffile_symlink_p (name);
563 if (!NILP (tem))
564 {
565 name = Fexpand_file_name (tem, dir);
566 dir = Ffile_name_directory (name);
567 }
568 else
569 break;
570 }
571 }
572
573 Vcommand_line_args = Qnil;
574
575 for (i = argc - 1; i >= 0; i--)
576 {
577 if (i == 0 || i > skip_args)
578 579 580
581 Vcommand_line_args
582 = Fcons (make_unibyte_string (argv[i], strlen (argv[i])),
583 Vcommand_line_args);
584 }
585
586 unbind_to (count, Qnil);
587 }
588
589 DEFUN ("invocation-name", Finvocation_name, Sinvocation_name, 0, 0, 0,
590 doc: 591 )
592 ()
593 {
594 return Fcopy_sequence (Vinvocation_name);
595 }
596
597 DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory,
598 0, 0, 0,
599 doc: )
600 ()
601 {
602 return Fcopy_sequence (Vinvocation_directory);
603 }
604
605
606 #ifdef HAVE_TZSET
607 608
609 static char dump_tz[] = "UtC0";
610 #endif
611
612 #ifndef ORDINARY_LINK
613 614 615 616
617 #ifdef __GNUC__
618 #ifndef GCC_CTORS_IN_LIBC
619 void __do_global_ctors ()
620 {}
621 void __do_global_ctors_aux ()
622 {}
623 void __do_global_dtors ()
624 {}
625
626 #ifndef GNU_LINUX
627 char * __CTOR_LIST__[2] = { (char *) (-1), 0 };
628 #endif
629 char * __DTOR_LIST__[2] = { (char *) (-1), 0 };
630 #endif
631 void __main ()
632 {}
633 #endif
634 #endif
635
636 637 638 639 640 641 642 643 644
645
646 static int
647 argmatch (argv, argc, sstr, lstr, minlen, valptr, skipptr)
648 char **argv;
649 int argc;
650 char *sstr;
651 char *lstr;
652 int minlen;
653 char **valptr;
654 int *skipptr;
655 {
656 char *p = NULL;
657 int arglen;
658 char *arg;
659
660
661 if (argc <= *skipptr + 1)
662 return 0;
663
664 arg = argv[*skipptr+1];
665 if (arg == NULL)
666 return 0;
667 if (strcmp (arg, sstr) == 0)
668 {
669 if (valptr != NULL)
670 {
671 *valptr = argv[*skipptr+2];
672 *skipptr += 2;
673 }
674 else
675 *skipptr += 1;
676 return 1;
677 }
678 arglen = (valptr != NULL && (p = index (arg, '=')) != NULL
679 ? p - arg : strlen (arg));
680 if (lstr == 0 || arglen < minlen || strncmp (arg, lstr, arglen) != 0)
681 return 0;
682 else if (valptr == NULL)
683 {
684 *skipptr += 1;
685 return 1;
686 }
687 else if (p != NULL)
688 {
689 *valptr = p+1;
690 *skipptr += 1;
691 return 1;
692 }
693 else if (argv[*skipptr+2] != NULL)
694 {
695 *valptr = argv[*skipptr+2];
696 *skipptr += 2;
697 return 1;
698 }
699 else
700 {
701 return 0;
702 }
703 }
704
705 #ifdef DOUG_LEA_MALLOC
706
707 708 709
710
711 static void
712 malloc_initialize_hook ()
713 {
714 #ifndef USE_CRT_DLL
715 extern char **environ;
716 #endif
717
718 if (initialized)
719 {
720 if (!malloc_using_checking)
721 722 723
724 {
725 char **p;
726
727 for (p = environ; p && *p; p++)
728 if (strncmp (*p, "MALLOC_CHECK_=", 14) == 0)
729 {
730 do
731 *p = p[1];
732 while (*++p);
733 break;
734 }
735 }
736
737 malloc_set_state (malloc_state_ptr);
738 #ifndef XMALLOC_OVERRUN_CHECK
739 free (malloc_state_ptr);
740 #endif
741 }
742 else
743 {
744 if (my_heap_start == 0)
745 my_heap_start = sbrk (0);
746 malloc_using_checking = getenv ("MALLOC_CHECK_") != NULL;
747 }
748 }
749
750 void (*__malloc_initialize_hook) () = malloc_initialize_hook;
751
752 #endif
753
754
755
756 int
757 main (int argc, char **argv)
758 {
759 #if GC_MARK_STACK
760 Lisp_Object dummy;
761 #endif
762 char stack_bottom_variable;
763 int do_initial_setlocale;
764 int skip_args = 0;
765 #ifdef HAVE_SETRLIMIT
766 struct rlimit rlim;
767 #endif
768 int no_loadup = 0;
769 char *junk = 0;
770 char *dname_arg = 0;
771 #ifdef NS_IMPL_COCOA
772 char dname_arg2[80];
773 #endif
774 char *ch_to_dir;
775
776 #if GC_MARK_STACK
777 extern Lisp_Object *stack_base;
778 stack_base = &dummy;
779 #endif
780
781 #if defined (USE_GTK) && defined (G_SLICE_ALWAYS_MALLOC)
782
783 setenv ("G_SLICE", "always-malloc", 1);
784 #endif
785
786 if (!initialized)
787 {
788 extern char my_endbss[];
789 extern char *my_endbss_static;
790
791 if (my_heap_start == 0)
792 my_heap_start = sbrk (0);
793
794 heap_bss_diff = (char *)my_heap_start - max (my_endbss, my_endbss_static);
795 }
796
797 #ifdef RUN_TIME_REMAP
798 if (initialized)
799 run_time_remap (argv[0]);
800 #endif
801
802
803 #ifdef DARWIN_OS
804 if (!initialized)
805 unexec_init_emacs_zone ();
806 #endif
807
808 sort_args (argc, argv);
809 argc = 0;
810 while (argv[argc]) argc++;
811
812 if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args))
813 {
814 const char *version, *copyright;
815 if (initialized)
816 {
817 Lisp_Object tem, tem2;
818 tem = Fsymbol_value (intern_c_string ("emacs-version"));
819 tem2 = Fsymbol_value (intern_c_string ("emacs-copyright"));
820 if (!STRINGP (tem))
821 {
822 fprintf (stderr, "Invalid value of `emacs-version'\n");
823 exit (1);
824 }
825 if (!STRINGP (tem2))
826 {
827 fprintf (stderr, "Invalid value of `emacs-copyright'\n");
828 exit (1);
829 }
830 else
831 {
832 version = SDATA (tem);
833 copyright = SDATA (tem2);
834 }
835 }
836 else
837 {
838 version = emacs_version;
839 copyright = emacs_copyright;
840 }
841 printf ("GNU Emacs %s\n", version);
842 printf ("%s\n", copyright);
843 printf ("GNU Emacs comes with ABSOLUTELY NO WARRANTY.\n");
844 printf ("You may redistribute copies of Emacs\n");
845 printf ("under the terms of the GNU General Public License.\n");
846 printf ("For more information about these matters, ");
847 printf ("see the file named COPYING.\n");
848 exit (0);
849 }
850 if (argmatch (argv, argc, "-chdir", "--chdir", 2, &ch_to_dir, &skip_args))
851 if (chdir (ch_to_dir) == -1)
852 {
853 fprintf (stderr, "%s: Can't chdir to %s: %s\n",
854 argv[0], ch_to_dir, strerror (errno));
855 exit (1);
856 }
857
858
859 #ifdef HAVE_PERSONALITY_LINUX32
860 if (!initialized
861 && (strcmp (argv[argc-1], "dump") == 0
862 || strcmp (argv[argc-1], "bootstrap") == 0)
863 && ! getenv ("EMACS_HEAP_EXEC"))
864 {
865
866 putenv("EMACS_HEAP_EXEC=true");
867
868 869
870 #define ADD_NO_RANDOMIZE 0x0040000
871 personality (PER_LINUX32 | ADD_NO_RANDOMIZE);
872 #undef ADD_NO_RANDOMIZE
873
874 execvp (argv[0], argv);
875
876
877 perror ("execvp");
878 }
879 #endif
880
881
882
883 #ifdef HAVE_SHM
884 if (argmatch (argv, argc, "-nl", "--no-shared-memory", 6, NULL, &skip_args))
885 {
886 map_in_data (0);
887
888 skip_args = 1;
889 }
890 else
891 {
892 map_in_data (1);
893
894 skip_args = 0;
895 }
896 #endif
897
898 #if defined (HAVE_SETRLIMIT) && defined (RLIMIT_STACK)
899 900 901
902 if (1
903 #ifndef CANNOT_DUMP
904 && (!noninteractive || initialized)
905 #endif
906 && !getrlimit (RLIMIT_STACK, &rlim))
907 {
908 long newlim;
909 extern size_t re_max_failures;
910
911 int ratio = 20 * sizeof (char *);
912 913
914 ratio += ratio / 3;
915 916
917 newlim = re_max_failures * ratio + 200000;
918 #ifdef __NetBSD__
919 920 921 922
923 newlim = (newlim + getpagesize () - 1) / getpagesize () * getpagesize();
924 #endif
925 if (newlim > rlim.rlim_max)
926 {
927 newlim = rlim.rlim_max;
928
929 re_max_failures = (newlim - 200000) / ratio;
930 }
931 if (rlim.rlim_cur < newlim)
932 rlim.rlim_cur = newlim;
933
934 setrlimit (RLIMIT_STACK, &rlim);
935 }
936 #endif
937
938
939 stack_bottom = &stack_bottom_variable;
940
941 clearerr (stdin);
942
943 #ifndef SYSTEM_MALLOC
944
945 memory_warnings (0, malloc_warning);
946
947 948
949 free (realloc (malloc (4), 4));
950
951 # ifndef SYNC_INPUT
952
953 uninterrupt_malloc ();
954 # endif
955 #endif
956
957 #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
958 main_thread = pthread_self ();
959 #endif
960
961 #if defined (MSDOS) || defined (WINDOWSNT)
962 963
964 _fmode = O_BINARY;
965 #endif
966
967 #ifdef MSDOS
968 if (!isatty (fileno (stdin)))
969 setmode (fileno (stdin), O_BINARY);
970 if (!isatty (fileno (stdout)))
971 {
972 fflush (stdout);
973 setmode (fileno (stdout), O_BINARY);
974 }
975 #endif
976
977 #ifdef SET_EMACS_PRIORITY
978 if (emacs_priority)
979 nice (emacs_priority);
980 setuid (getuid ());
981 #endif
982
983 984 985 986
987 {
988 char *lc_all = getenv ("LC_ALL");
989 do_initial_setlocale = ! lc_all || strcmp (lc_all, "C");
990 }
991
992 993
994 if (do_initial_setlocale)
995 setlocale (LC_ALL, "");
996
997 inhibit_window_system = 0;
998
999
1000 while (1)
1001 {
1002 char *term;
1003 if (argmatch (argv, argc, "-t", "--terminal", 4, &term, &skip_args))
1004 {
1005 int result;
1006 emacs_close (0);
1007 emacs_close (1);
1008 result = emacs_open (term, O_RDWR, 0);
1009 if (result < 0)
1010 {
1011 char *errstring = strerror (errno);
1012 fprintf (stderr, "%s: %s: %s\n", argv[0], term, errstring);
1013 exit (1);
1014 }
1015 dup (0);
1016 if (! isatty (0))
1017 {
1018 fprintf (stderr, "%s: %s: not a tty\n", argv[0], term);
1019 exit (1);
1020 }
1021 fprintf (stderr, "Using %s\n", term);
1022 #ifdef HAVE_WINDOW_SYSTEM
1023 inhibit_window_system = 1;
1024 #endif
1025 }
1026 else
1027 break;
1028 }
1029
1030 1031
1032 if (argmatch (argv, argc, "-nw", "--no-window-system", 6, NULL, &skip_args)
1033 || argmatch (argv, argc, "-nw", "--no-windows", 6, NULL, &skip_args))
1034 inhibit_window_system = 1;
1035
1036
1037 noninteractive = 0;
1038 if (argmatch (argv, argc, "-batch", "--batch", 5, NULL, &skip_args))
1039 {
1040 noninteractive = 1;
1041 Vundo_outer_limit = Qnil;
1042 }
1043 if (argmatch (argv, argc, "-script", "--script", 3, &junk, &skip_args))
1044 {
1045 noninteractive = 1;
1046 1047
1048
1049 argv[skip_args - 1] = "-scriptload";
1050 skip_args -= 2;
1051 sort_args (argc, argv);
1052 }
1053
1054
1055 if (argmatch (argv, argc, "-help", "--help", 3, NULL, &skip_args))
1056 {
1057 printf (USAGE1, argv[0], USAGE2);
1058 printf (USAGE3);
1059 printf (USAGE4);
1060 exit (0);
1061 }
1062
1063 if (argmatch (argv, argc, "-daemon", "--daemon", 5, NULL, &skip_args)
1064 || argmatch (argv, argc, "-daemon", "--daemon", 5, &dname_arg, &skip_args))
1065 {
1066 #ifndef DOS_NT
1067 pid_t f;
1068
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089
1090 if (pipe (daemon_pipe) == -1)
1091 {
1092 fprintf (stderr, "Cannot pipe!\n");
1093 exit (1);
1094 }
1095
1096 #ifndef NS_IMPL_COCOA
1097 f = fork ();
1098 #else
1099 1100 1101 1102 1103 1104
1105 if (!dname_arg || !strchr (dname_arg, '\n'))
1106 f = fork ();
1107 else
1108 f = 0;
1109 #endif
1110 if (f > 0)
1111 {
1112 int retval;
1113 char buf[1];
1114
1115
1116 close (daemon_pipe[1]);
1117
1118
1119 do
1120 {
1121 retval = read (daemon_pipe[0], &buf, 1);
1122 }
1123 while (retval == -1 && errno == EINTR);
1124
1125 if (retval < 0)
1126 {
1127 fprintf (stderr, "Error reading status from child\n");
1128 exit (1);
1129 }
1130 else if (retval == 0)
1131 {
1132 fprintf (stderr, "Error: server did not start correctly\n");
1133 exit (1);
1134 }
1135
1136 close (daemon_pipe[0]);
1137 exit (0);
1138 }
1139 if (f < 0)
1140 {
1141 fprintf (stderr, "Cannot fork!\n");
1142 exit (1);
1143 }
1144
1145 #ifdef NS_IMPL_COCOA
1146 {
1147
1148 if (!dname_arg || !strchr (dname_arg, '\n'))
1149 {
1150 char fdStr[80];
1151
1152 if (dname_arg && strlen (dname_arg) > 70)
1153 {
1154 fprintf (stderr, "daemon: child name too long\n");
1155 exit (1);
1156 }
1157
1158 sprintf (fdStr, "--daemon=\n%d,%d\n%s", daemon_pipe[0],
1159 daemon_pipe[1], dname_arg ? dname_arg : "");
1160 argv[skip_args] = fdStr;
1161
1162 execv (argv[0], argv);
1163 fprintf (stderr, "emacs daemon: exec failed: %d\n", errno);
1164 exit (1);
1165 }
1166
1167
1168 if (!dname_arg || !strchr (dname_arg, '\n')
1169 || strlen (dname_arg) < 1 || strlen (dname_arg) > 70)
1170 {
1171 fprintf (stderr, "emacs daemon: daemon name absent or too long\n");
1172 exit(1);
1173 }
1174 dname_arg2[0] = '\0';
1175 sscanf (dname_arg, "\n%d,%d\n%s", &(daemon_pipe[0]), &(daemon_pipe[1]),
1176 dname_arg2);
1177 dname_arg = strlen (dname_arg2) ? dname_arg2 : NULL;
1178 }
1179 #endif
1180
1181 if (dname_arg)
1182 daemon_name = xstrdup (dname_arg);
1183
1184 close (daemon_pipe[0]);
1185 1186
1187 fcntl (daemon_pipe[1], F_SETFD, FD_CLOEXEC);
1188
1189 #ifdef HAVE_SETSID
1190 setsid();
1191 #endif
1192 #else
1193 fprintf (stderr, "This platform does not support the -daemon flag.\n");
1194 exit (1);
1195 #endif
1196 }
1197
1198 if (! noninteractive)
1199 {
1200 #if defined (USG5) && defined (INTERRUPT_INPUT)
1201 setpgrp ();
1202 #endif
1203 #if defined (HAVE_GTK_AND_PTHREAD) && !defined (SYSTEM_MALLOC) && !defined (DOUG_LEA_MALLOC)
1204 {
1205 extern void malloc_enable_thread P_ ((void));
1206
1207 malloc_enable_thread ();
1208 }
1209 #endif
1210 }
1211
1212 init_signals ();
1213
1214
1215 if (1
1216 #ifndef CANNOT_DUMP
1217 && initialized
1218 #endif
1219 )
1220 {
1221 sigblock (sigmask (SIGHUP));
1222 1223
1224 if (! noninteractive
1225 || signal (SIGHUP, SIG_IGN) != SIG_IGN)
1226 signal (SIGHUP, fatal_error_signal);
1227 sigunblock (sigmask (SIGHUP));
1228 }
1229
1230 if (
1231 #ifndef CANNOT_DUMP
1232 ! noninteractive || initialized
1233 #else
1234 1
1235 #endif
1236 )
1237 {
1238 1239 1240
1241 signal (SIGQUIT, fatal_error_signal);
1242 signal (SIGILL, fatal_error_signal);
1243 signal (SIGTRAP, fatal_error_signal);
1244 #ifdef SIGUSR1
1245 add_user_signal (SIGUSR1, "sigusr1");
1246 #endif
1247 #ifdef SIGUSR2
1248 add_user_signal (SIGUSR2, "sigusr2");
1249 #endif
1250 #ifdef SIGABRT
1251 signal (SIGABRT, fatal_error_signal);
1252 #endif
1253 #ifdef SIGHWE
1254 signal (SIGHWE, fatal_error_signal);
1255 #endif
1256 #ifdef SIGPRE
1257 signal (SIGPRE, fatal_error_signal);
1258 #endif
1259 #ifdef SIGORE
1260 signal (SIGORE, fatal_error_signal);
1261 #endif
1262 #ifdef SIGUME
1263 signal (SIGUME, fatal_error_signal);
1264 #endif
1265 #ifdef SIGDLK
1266 signal (SIGDLK, fatal_error_signal);
1267 #endif
1268 #ifdef SIGCPULIM
1269 signal (SIGCPULIM, fatal_error_signal);
1270 #endif
1271 #ifdef SIGIOT
1272
1273 signal (SIGIOT, fatal_error_signal);
1274 #endif
1275 #ifdef SIGEMT
1276 signal (SIGEMT, fatal_error_signal);
1277 #endif
1278 signal (SIGFPE, fatal_error_signal);
1279 #ifdef SIGBUS
1280 signal (SIGBUS, fatal_error_signal);
1281 #endif
1282 signal (SIGSEGV, fatal_error_signal);
1283 #ifdef SIGSYS
1284 signal (SIGSYS, fatal_error_signal);
1285 #endif
1286 signal (SIGTERM, fatal_error_signal);
1287 #ifdef SIGXCPU
1288 signal (SIGXCPU, fatal_error_signal);
1289 #endif
1290 #ifdef SIGXFSZ
1291 signal (SIGXFSZ, fatal_error_signal);
1292 #endif
1293
1294 #ifdef SIGDANGER
1295
1296 signal (SIGDANGER, memory_warning_signal);
1297 #endif
1298
1299 #ifdef AIX
1300
1301 signal (SIGXCPU, fatal_error_signal);
1302 #ifndef _I386
1303 signal (SIGIOINT, fatal_error_signal);
1304 #endif
1305 signal (SIGGRANT, fatal_error_signal);
1306 signal (SIGRETRACT, fatal_error_signal);
1307 signal (SIGSOUND, fatal_error_signal);
1308 signal (SIGMSG, fatal_error_signal);
1309 #endif
1310 }
1311
1312 noninteractive1 = noninteractive;
1313
1314
1315
1316 if (!initialized)
1317 {
1318 init_alloc_once ();
1319 init_obarray ();
1320 init_eval_once ();
1321 init_character_once ();
1322 init_charset_once ();
1323 init_coding_once ();
1324 init_syntax_once ();
1325 init_category_once ();
1326
1327 init_casetab_once ();
1328 init_buffer_once ();
1329 init_minibuf_once ();
1330
1331
1332 1333 1334 1335
1336 syms_of_xfaces ();
1337 1338
1339 syms_of_keymap ();
1340 1341 1342 1343
1344 syms_of_keyboard ();
1345
1346
1347 syms_of_data ();
1348 syms_of_fileio ();
1349
1350 syms_of_alloc ();
1351
1352 syms_of_charset ();
1353 1354
1355 syms_of_coding ();
1356
1357 init_window_once ();
1358 #ifdef HAVE_WINDOW_SYSTEM
1359 init_fringe_once ();
1360 #endif
1361 }
1362
1363 init_alloc ();
1364
1365 if (do_initial_setlocale)
1366 {
1367 fixup_locale ();
1368 Vsystem_messages_locale = Vprevious_system_messages_locale;
1369 Vsystem_time_locale = Vprevious_system_time_locale;
1370 }
1371
1372 init_eval ();
1373 init_data ();
1374 #ifdef CLASH_DETECTION
1375 init_filelock ();
1376 #endif
1377 init_atimer ();
1378 running_asynch_code = 0;
1379
1380 1381
1382 if (1)
1383 {
1384 int inhibit_unibyte = 0;
1385
1386
1387 if (argmatch (argv, argc, "-no-unibyte", "--no-unibyte", 4, NULL, &skip_args)
1388 || argmatch (argv, argc, "-multibyte", "--multibyte", 4, NULL, &skip_args)
1389
1390 || (!initialized && noninteractive))
1391 inhibit_unibyte = 1;
1392
1393 1394 1395 1396
1397 1398 1399 1400 1401 1402
1403 if (argmatch (argv, argc, "-unibyte", "--unibyte", 4, NULL, &skip_args)
1404 || argmatch (argv, argc, "-no-multibyte", "--no-multibyte", 4, NULL, &skip_args)
1405 || (getenv ("EMACS_UNIBYTE") && !inhibit_unibyte))
1406 {
1407 Lisp_Object old_log_max;
1408 Lisp_Object symbol, tail;
1409
1410 symbol = intern_c_string ("enable-multibyte-characters");
1411 Fset_default (symbol, Qnil);
1412
1413 if (initialized)
1414 {
1415
1416 old_log_max = Vmessage_log_max;
1417 XSETFASTINT (Vmessage_log_max, 0);
1418 message_dolog ("", 0, 1, 0);
1419 Vmessage_log_max = old_log_max;
1420 }
1421
1422 for (tail = Vbuffer_alist; CONSP (tail);
1423 tail = XCDR (tail))
1424 {
1425 Lisp_Object buffer;
1426
1427 buffer = Fcdr (XCAR (tail));
1428
1429 if (BUF_Z_BYTE (XBUFFER (buffer)) > BUF_Z (XBUFFER (buffer)))
1430 {
1431 struct buffer *current = current_buffer;
1432
1433 set_buffer_temp (XBUFFER (buffer));
1434 Fset_buffer_multibyte (Qnil);
1435 set_buffer_temp (current);
1436 }
1437 }
1438 message ("Warning: unibyte sessions are obsolete and will disappear");
1439 }
1440 }
1441
1442 no_loadup
1443 = argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args);
1444
1445 #ifdef HAVE_NS
1446 ns_alloc_autorelease_pool();
1447 if (!noninteractive)
1448 {
1449 #ifdef NS_IMPL_COCOA
1450 if (skip_args < argc)
1451 {
1452 if (!strncmp(argv[skip_args], "-psn", 4))
1453 {
1454 skip_args += 1;
1455 chdir (getenv ("HOME"));
1456 }
1457 else if (skip_args+1 < argc && !strncmp(argv[skip_args+1], "-psn", 4))
1458 {
1459 skip_args += 2;
1460 chdir (getenv ("HOME"));
1461 }
1462 }
1463 #endif
1464 }
1465 #endif
1466
1467 #ifdef HAVE_X_WINDOWS
1468 1469 1470 1471
1472 {
1473 char *displayname = 0;
1474 int count_before = skip_args;
1475
1476
1477 while (1)
1478 {
1479 int count_before_this = skip_args;
1480
1481 if (argmatch (argv, argc, "-d", "--display", 3, &displayname, &skip_args))
1482 display_arg = 1;
1483 else if (argmatch (argv, argc, "-display", 0, 3, &displayname, &skip_args))
1484 display_arg = 1;
1485 else
1486 break;
1487
1488 count_before = count_before_this;
1489 }
1490
1491 1492 1493
1494 if (displayname != 0 && skip_args - count_before == 1)
1495 {
1496 char **new = (char **) xmalloc (sizeof (char *) * (argc + 2));
1497 int j;
1498
1499 for (j = 0; j < count_before + 1; j++)
1500 new[j] = argv[j];
1501 new[count_before + 1] = "-d";
1502 new[count_before + 2] = displayname;
1503 for (j = count_before + 2; j <argc; j++)
1504 new[j + 1] = argv[j];
1505 argv = new;
1506 argc++;
1507 }
1508
1509 else if (displayname != 0 && skip_args > count_before
1510 && argv[count_before + 1][1] == '-')
1511 argv[count_before + 1] = "-d";
1512
1513
1514 skip_args = count_before;
1515 }
1516 #endif
1517
1518 1519 1520
1521
1522 #ifdef MSDOS
1523
1524 init_dosfns ();
1525
1526 if (initialized)
1527 init_environment (argc, argv, skip_args);
1528 else
1529 tzset ();
1530 #endif
1531
1532 #ifdef WINDOWSNT
1533 globals_of_w32 ();
1534
1535 init_environment (argv);
1536 init_ntproc ();
1537 #endif
1538
1539 #ifdef HAVE_NS
1540 #ifndef CANNOT_DUMP
1541 if (initialized)
1542 #endif
1543 ns_init_paths ();
1544 #endif
1545
1546 1547 1548
1549 if (!initialized)
1550 syms_of_callproc ();
1551 1552 1553
1554 set_initial_environment ();
1555 1556 1557
1558
1559 #ifdef AIX
1560 putenv ("LANG=C");
1561 #endif
1562
1563 init_buffer ();
1564
1565 init_callproc_1 ();
1566 init_cmdargs (argc, argv, skip_args);
1567
1568 if (initialized)
1569 {
1570
1571 Lisp_Object old_log_max;
1572 old_log_max = Vmessage_log_max;
1573 XSETFASTINT (Vmessage_log_max, 0);
1574 message_dolog ("", 0, 1, 0);
1575 Vmessage_log_max = old_log_max;
1576 }
1577
1578 init_callproc ();
1579 init_lread ();
1580
1581 1582
1583
1584 if (!initialized)
1585 {
1586 1587
1588 syms_of_chartab ();
1589 syms_of_lread ();
1590 syms_of_print ();
1591 syms_of_eval ();
1592 syms_of_fns ();
1593 syms_of_floatfns ();
1594
1595 syms_of_buffer ();
1596 syms_of_bytecode ();
1597 syms_of_callint ();
1598 syms_of_casefiddle ();
1599 syms_of_casetab ();
1600 syms_of_category ();
1601 syms_of_ccl ();
1602 syms_of_character ();
1603 syms_of_cmds ();
1604 syms_of_dired ();
1605 syms_of_display ();
1606 syms_of_doc ();
1607 syms_of_editfns ();
1608 syms_of_emacs ();
1609 #ifdef CLASH_DETECTION
1610 syms_of_filelock ();
1611 #endif
1612 syms_of_indent ();
1613 syms_of_insdel ();
1614
1615 syms_of_macros ();
1616 syms_of_marker ();
1617 syms_of_minibuf ();
1618 syms_of_process ();
1619 syms_of_search ();
1620 syms_of_frame ();
1621 syms_of_syntax ();
1622 syms_of_terminal ();
1623 syms_of_term ();
1624 syms_of_undo ();
1625 #ifdef HAVE_SOUND
1626 syms_of_sound ();
1627 #endif
1628 syms_of_textprop ();
1629 syms_of_composite ();
1630 #ifdef WINDOWSNT
1631 syms_of_ntproc ();
1632 #endif
1633 syms_of_window ();
1634 syms_of_xdisp ();
1635 syms_of_font ();
1636 #ifdef HAVE_WINDOW_SYSTEM
1637 syms_of_fringe ();
1638 syms_of_image ();
1639 #endif
1640 #ifdef HAVE_X_WINDOWS
1641 syms_of_xterm ();
1642 syms_of_xfns ();
1643 syms_of_xmenu ();
1644 syms_of_fontset ();
1645 syms_of_xsettings ();
1646 #ifdef HAVE_X_SM
1647 syms_of_xsmfns ();
1648 #endif
1649 #ifdef HAVE_X11
1650 syms_of_xselect ();
1651 #endif
1652 #endif
1653
1654 syms_of_menu ();
1655
1656 #ifdef HAVE_NTGUI
1657 syms_of_w32term ();
1658 syms_of_w32fns ();
1659 syms_of_w32select ();
1660 syms_of_w32menu ();
1661 syms_of_fontset ();
1662 #endif
1663
1664 #ifdef MSDOS
1665 syms_of_xmenu ();
1666 #endif
1667
1668 #ifdef HAVE_NS
1669 syms_of_nsterm ();
1670 syms_of_nsfns ();
1671 syms_of_nsmenu ();
1672 syms_of_nsselect ();
1673 syms_of_fontset ();
1674 #endif
1675
1676 #ifdef HAVE_DBUS
1677 syms_of_dbusbind ();
1678 #endif
1679
1680 #ifdef SYMS_SYSTEM
1681 SYMS_SYSTEM;
1682 #endif
1683
1684 #ifdef SYMS_MACHINE
1685 SYMS_MACHINE;
1686 #endif
1687
1688 keys_of_casefiddle ();
1689 keys_of_cmds ();
1690 keys_of_buffer ();
1691 keys_of_keyboard ();
1692 keys_of_keymap ();
1693 keys_of_window ();
1694 }
1695 else
1696 {
1697 1698
1699 #ifdef HAVE_NTGUI
1700 globals_of_w32fns ();
1701 globals_of_w32menu ();
1702 globals_of_w32select ();
1703 #endif
1704 }
1705
1706 init_charset ();
1707
1708 init_editfns ();
1709 init_process ();
1710 init_keyboard ();
1711 if (!noninteractive)
1712 init_display ();
1713 init_fns ();
1714 init_xdisp ();
1715 #ifdef HAVE_WINDOW_SYSTEM
1716 init_fringe ();
1717 init_image ();
1718 #endif
1719 init_macros ();
1720 init_floatfns ();
1721 #ifdef HAVE_SOUND
1722 init_sound ();
1723 #endif
1724 init_window ();
1725 init_font ();
1726
1727 if (!initialized)
1728 {
1729 char *file;
1730
1731 if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args))
1732 Vtop_level = Fcons (intern_c_string ("load"),
1733 Fcons (build_string (file), Qnil));
1734
1735 if (! no_loadup)
1736 Vtop_level = Fcons (intern_c_string ("load"),
1737 Fcons (build_string ("loadup.el"), Qnil));
1738 }
1739
1740 if (initialized)
1741 {
1742 #ifdef HAVE_TZSET
1743 {
1744 1745 1746 1747 1748
1749 char *tz = getenv ("TZ");
1750 if (tz && !strcmp (tz, dump_tz))
1751 {
1752 ++*tz;
1753 tzset ();
1754 --*tz;
1755 }
1756 }
1757 #endif
1758 }
1759
1760 1761 1762 1763
1764 #if defined (__FreeBSD__) || defined (GNU_LINUX) || defined(__MINGW32__)
1765 #ifdef PROFILING
1766 if (initialized)
1767 {
1768 extern void _mcleanup ();
1769 #ifdef __MINGW32__
1770 extern unsigned char etext asm ("etext");
1771 #else
1772 extern char etext;
1773 #endif
1774 extern void safe_bcopy ();
1775 extern void dump_opcode_frequencies ();
1776
1777 atexit (_mcleanup);
1778 1779 1780 1781
1782 monstartup (safe_bcopy, &etext);
1783 }
1784 else
1785 moncontrol (0);
1786 #endif
1787 #endif
1788
1789 initialized = 1;
1790
1791 #ifdef LOCALTIME_CACHE
1792 1793 1794 1795 1796
1797 tzset ();
1798 #endif
1799
1800
1801 Frecursive_edit ();
1802
1803 return 0;
1804 }
1805
1806 1807
1808
1809
1810
1811 struct standard_args
1812 {
1813 const char *name;
1814 const char *longname;
1815 int priority;
1816 int nargs;
1817 };
1818
1819 const struct standard_args standard_args[] =
1820 {
1821 { "-version", "--version", 150, 0 },
1822 { "-chdir", "--chdir", 130, 1 },
1823 { "-t", "--terminal", 120, 1 },
1824 { "-nw", "--no-window-system", 110, 0 },
1825 { "-nw", "--no-windows", 110, 0 },
1826 { "-batch", "--batch", 100, 0 },
1827 { "-script", "--script", 100, 1 },
1828 { "-daemon", "--daemon", 99, 0 },
1829 { "-help", "--help", 90, 0 },
1830 { "-no-unibyte", "--no-unibyte", 83, 0 },
1831 { "-multibyte", "--multibyte", 82, 0 },
1832 { "-unibyte", "--unibyte", 81, 0 },
1833 { "-no-multibyte", "--no-multibyte", 80, 0 },
1834 { "-nl", "--no-loadup", 70, 0 },
1835
1836 { "-d", "--display", 60, 1 },
1837 { "-display", 0, 60, 1 },
1838
1839 { "-Q", "--quick", 55, 0 },
1840 { "-quick", 0, 55, 0 },
1841 { "-q", "--no-init-file", 50, 0 },
1842 { "-no-init-file", 0, 50, 0 },
1843 { "-no-site-file", "--no-site-file", 40, 0 },
1844 { "-u", "--user", 30, 1 },
1845 { "-user", 0, 30, 1 },
1846 { "-debug-init", "--debug-init", 20, 0 },
1847 { "-iconic", "--iconic", 15, 0 },
1848 { "-D", "--basic-display", 12, 0},
1849 { "-basic-display", 0, 12, 0},
1850 { "-nbc", "--no-blinking-cursor", 12, 0 },
1851
1852 { "-nbi", "--no-bitmap-icon", 10, 0 },
1853 { "-bg", "--background-color", 10, 1 },
1854 { "-background", 0, 10, 1 },
1855 { "-fg", "--foreground-color", 10, 1 },
1856 { "-foreground", 0, 10, 1 },
1857 { "-bd", "--border-color", 10, 1 },
1858 { "-bw", "--border-width", 10, 1 },
1859 { "-ib", "--internal-border", 10, 1 },
1860 { "-ms", "--mouse-color", 10, 1 },
1861 { "-cr", "--cursor-color", 10, 1 },
1862 { "-fn", "--font", 10, 1 },
1863 { "-font", 0, 10, 1 },
1864 { "-fs", "--fullscreen", 10, 0 },
1865 { "-fw", "--fullwidth", 10, 0 },
1866 { "-fh", "--fullheight", 10, 0 },
1867 { "-mm", "--maximized", 10, 0 },
1868 { "-g", "--geometry", 10, 1 },
1869 { "-geometry", 0, 10, 1 },
1870 { "-T", "--title", 10, 1 },
1871 { "-title", 0, 10, 1 },
1872 { "-name", "--name", 10, 1 },
1873 { "-xrm", "--xrm", 10, 1 },
1874 { "-parent-id", "--parent-id", 10, 1 },
1875 { "-r", "--reverse-video", 5, 0 },
1876 { "-rv", 0, 5, 0 },
1877 { "-reverse", 0, 5, 0 },
1878 { "-hb", "--horizontal-scroll-bars", 5, 0 },
1879 { "-vb", "--vertical-scroll-bars", 5, 0 },
1880 { "-color", "--color", 5, 0},
1881 { "-no-splash", "--no-splash", 3, 0 },
1882 { "-no-desktop", "--no-desktop", 3, 0 },
1883 #ifdef HAVE_NS
1884 { "-NSAutoLaunch", 0, 5, 1 },
1885 { "-NXAutoLaunch", 0, 5, 1 },
1886 { "-disable-font-backend", "--disable-font-backend", 65, 0 },
1887 { "-_NSMachLaunch", 0, 85, 1 },
1888 { "-MachLaunch", 0, 85, 1 },
1889 { "-macosx", 0, 85, 0 },
1890 { "-NSHost", 0, 85, 1 },
1891 #endif
1892 1893
1894 { "-L", "--directory", 0, 1 },
1895 { "-directory", 0, 0, 1 },
1896 { "-l", "--load", 0, 1 },
1897 { "-load", 0, 0, 1 },
1898 1899 1900 1901
1902 { "-scriptload", NULL, 0, 1 },
1903 { "-f", "--funcall", 0, 1 },
1904 { "-funcall", 0, 0, 1 },
1905 { "-eval", "--eval", 0, 1 },
1906 { "-execute", "--execute", 0, 1 },
1907 { "-find-file", "--find-file", 0, 1 },
1908 { "-visit", "--visit", 0, 1 },
1909 { "-file", "--file", 0, 1 },
1910 { "-insert", "--insert", 0, 1 },
1911 #ifdef HAVE_NS
1912 { "-NXOpen", 0, 0, 1 },
1913 { "-NXOpenTemp", 0, 0, 1 },
1914 { "-NSOpen", 0, 0, 1 },
1915 { "-NSOpenTemp", 0, 0, 1 },
1916 { "-GSFilePath", 0, 0, 1 },
1917 #endif
1918
1919 { "-kill", "--kill", -10, 0 },
1920 };
1921
1922 1923 1924 1925 1926 1927 1928
1929
1930 static void
1931 sort_args (argc, argv)
1932 int argc;
1933 char **argv;
1934 {
1935 char **new = (char **) xmalloc (sizeof (char *) * argc);
1936 1937 1938 1939 1940
1941 int *options = (int *) xmalloc (sizeof (int) * argc);
1942 int *priority = (int *) xmalloc (sizeof (int) * argc);
1943 int to = 1;
1944 int incoming_used = 1;
1945 int from;
1946 int i;
1947
1948 1949
1950 for (from = 1; from < argc; from++)
1951 {
1952 options[from] = -1;
1953 priority[from] = 0;
1954 if (argv[from][0] == '-')
1955 {
1956 int match, thislen;
1957 char *equals;
1958
1959 1960
1961 if (argv[from][1] == '-' && argv[from][2] == 0)
1962 {
1963
1964 for (; from < argc; from++)
1965 {
1966 priority[from] = -100;
1967 options[from] = -1;
1968 }
1969 break;
1970 }
1971
1972
1973 for (i = 0; i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
1974 if (!strcmp (argv[from], standard_args[i].name))
1975 {
1976 options[from] = standard_args[i].nargs;
1977 priority[from] = standard_args[i].priority;
1978 if (from + standard_args[i].nargs >= argc)
1979 fatal ("Option `%s' requires an argument\n", argv[from]);
1980 from += standard_args[i].nargs;
1981 goto done;
1982 }
1983
1984 1985 1986
1987 if (argv[from][1] == '-')
1988 {
1989 match = -1;
1990 thislen = strlen (argv[from]);
1991 equals = index (argv[from], '=');
1992 if (equals != 0)
1993 thislen = equals - argv[from];
1994
1995 for (i = 0;
1996 i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
1997 if (standard_args[i].longname
1998 && !strncmp (argv[from], standard_args[i].longname,
1999 thislen))
2000 {
2001 if (match == -1)
2002 match = i;
2003 else
2004 match = -2;
2005 }
2006
2007
2008 if (match >= 0)
2009 {
2010 options[from] = standard_args[match].nargs;
2011 priority[from] = standard_args[match].priority;
2012 2013
2014 if (equals != 0)
2015 options[from] = 0;
2016 if (from + options[from] >= argc)
2017 fatal ("Option `%s' requires an argument\n", argv[from]);
2018 from += options[from];
2019 }
2020 2021 2022
2023 }
2024 done: ;
2025 }
2026 }
2027
2028
2029 new[0] = argv[0];
2030 while (incoming_used < argc)
2031 {
2032 int best = -1;
2033 int best_priority = -9999;
2034
2035 2036
2037 for (from = 1; from < argc; from++)
2038 {
2039 if (argv[from] != 0 && priority[from] > best_priority)
2040 {
2041 best_priority = priority[from];
2042 best = from;
2043 }
2044
2045 if (options[from] > 0)
2046 from += options[from];
2047 }
2048
2049 if (best < 0)
2050 abort ();
2051
2052 2053
2054 if (! (options[best] == 0
2055 && ! strcmp (new[to - 1], argv[best])))
2056 {
2057 new[to++] = argv[best];
2058 for (i = 0; i < options[best]; i++)
2059 new[to++] = argv[best + i + 1];
2060 }
2061
2062 incoming_used += 1 + (options[best] > 0 ? options[best] : 0);
2063
2064
2065 argv[best] = 0;
2066 for (i = 0; i < options[best]; i++)
2067 argv[best + i + 1] = 0;
2068 }
2069
2070
2071 while (to < argc)
2072 new[to++] = 0;
2073
2074 bcopy (new, argv, sizeof (char *) * argc);
2075
2076 xfree (options);
2077 xfree (new);
2078 xfree (priority);
2079 }
2080
2081 DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P",
2082 doc: 2083 2084 2085 2086 2087 2088 )
2089 (arg)
2090 Lisp_Object arg;
2091 {
2092 struct gcpro gcpro1;
2093
2094 GCPRO1 (arg);
2095
2096 if (feof (stdin))
2097 arg = Qt;
2098
2099 if (!NILP (Vrun_hooks) && !noninteractive)
2100 call1 (Vrun_hooks, intern ("kill-emacs-hook"));
2101
2102 UNGCPRO;
2103
2104 shut_down_emacs (0, 0, STRINGP (arg) ? arg : Qnil);
2105
2106 2107 2108
2109 if (STRINGP (Vauto_save_list_file_name))
2110 unlink (SDATA (Vauto_save_list_file_name));
2111
2112 exit (INTEGERP (arg) ? XINT (arg) : EXIT_SUCCESS);
2113
2114 return Qnil;
2115 }
2116
2117
2118 2119 2120 2121 2122 2123 2124 2125 2126 2127
2128
2129 void
2130 shut_down_emacs (sig, no_x, stuff)
2131 int sig, no_x;
2132 Lisp_Object stuff;
2133 {
2134
2135 Vrun_hooks = Qnil;
2136
2137
2138 Vinhibit_redisplay = Qt;
2139
2140
2141 #ifdef EMACS_HAVE_TTY_PGRP
2142 {
2143 int pgrp = EMACS_GETPGRP (0);
2144
2145 int tpgrp;
2146 if (EMACS_GET_TTY_PGRP (0, &tpgrp) != -1
2147 && tpgrp == pgrp)
2148 {
2149 reset_all_sys_modes ();
2150 if (sig && sig != SIGTERM)
2151 fprintf (stderr, "Fatal error (%d)", sig);
2152 }
2153 }
2154 #else
2155 fflush (stdout);
2156 reset_all_sys_modes ();
2157 #endif
2158
2159 stuff_buffered_input (stuff);
2160
2161 #ifdef subprocesses
2162 inhibit_sentinels = 1;
2163 #endif
2164 kill_buffer_processes (Qnil);
2165 Fdo_auto_save (Qt, Qnil);
2166
2167 #ifdef CLASH_DETECTION
2168 unlock_all_files ();
2169 #endif
2170
2171 #if 0
2172 #ifdef HAVE_X_WINDOWS
2173
2174 if (!noninteractive && SYMBOLP (Vinitial_window_system)
2175 && SCHARS (SYMBOL_NAME (Vinitial_window_system)) == 1
2176 && SREF (SYMBOL_NAME (Vinitial_window_system), 0) == 'x'
2177 && ! no_x)
2178 Fx_close_current_connection ();
2179 #endif
2180 #endif
2181
2182 #ifdef SIGIO
2183 2184
2185 unrequest_sigio ();
2186 signal (SIGIO, SIG_IGN);
2187 #endif
2188
2189 #ifdef WINDOWSNT
2190 term_ntproc ();
2191 #endif
2192
2193 2194
2195 if (sig == 0 || sig == SIGTERM)
2196 {
2197 check_glyph_memory ();
2198 check_message_stack ();
2199 }
2200
2201 #ifdef MSDOS
2202 dos_cleanup ();
2203 #endif
2204
2205 #ifdef HAVE_NS
2206 ns_term_shutdown (sig);
2207 #endif
2208 }
2209
2210
2211
2212 #ifndef CANNOT_DUMP
2213
2214 DEFUN ("dump-emacs", Fdump_emacs, Sdump_emacs, 2, 2, 0,
2215 doc: 2216 2217 2218 2219 )
2220 (filename, symfile)
2221 Lisp_Object filename, symfile;
2222 {
2223 extern char my_edata[];
2224 Lisp_Object tem;
2225 Lisp_Object symbol;
2226 int count = SPECPDL_INDEX ();
2227
2228 check_pure_size ();
2229
2230 if (! noninteractive)
2231 error ("Dumping Emacs works only in batch mode");
2232
2233 #ifdef GNU_LINUX
2234 if (heap_bss_diff > MAX_HEAP_BSS_DIFF)
2235 {
2236 fprintf (stderr, "**************************************************\n");
2237 fprintf (stderr, "Warning: Your system has a gap between BSS and the\n");
2238 fprintf (stderr, "heap (%lu bytes). This usually means that exec-shield\n",
2239 heap_bss_diff);
2240 fprintf (stderr, "or something similar is in effect. The dump may\n");
2241 fprintf (stderr, "fail because of this. See the section about\n");
2242 fprintf (stderr, "exec-shield in etc/PROBLEMS for more information.\n");
2243 fprintf (stderr, "**************************************************\n");
2244 }
2245 #endif
2246
2247 2248 2249
2250 symbol = intern ("command-line-processed");
2251 specbind (symbol, Qnil);
2252
2253 CHECK_STRING (filename);
2254 filename = Fexpand_file_name (filename, Qnil);
2255 if (!NILP (symfile))
2256 {
2257 CHECK_STRING (symfile);
2258 if (SCHARS (symfile))
2259 symfile = Fexpand_file_name (symfile, Qnil);
2260 }
2261
2262 tem = Vpurify_flag;
2263 Vpurify_flag = Qnil;
2264
2265 #ifdef HAVE_TZSET
2266 set_time_zone_rule (dump_tz);
2267 #ifndef LOCALTIME_CACHE
2268
2269 tzset ();
2270 #endif
2271 #endif
2272
2273 fflush (stdout);
2274
2275
2276 #ifndef SYSTEM_MALLOC
2277 #ifndef WINDOWSNT
2278 2279
2280 memory_warnings (my_edata, malloc_warning);
2281 #endif
2282 #endif
2283 #if !defined (SYSTEM_MALLOC) && defined (HAVE_GTK_AND_PTHREAD) && !defined SYNC_INPUT
2284 2285 2286
2287 reset_malloc_hooks ();
2288 #endif
2289 #ifdef DOUG_LEA_MALLOC
2290 malloc_state_ptr = malloc_get_state ();
2291 #endif
2292
2293 #ifdef USE_MMAP_FOR_BUFFERS
2294 mmap_set_vars (0);
2295 #endif
2296 unexec (SDATA (filename),
2297 !NILP (symfile) ? SDATA (symfile) : 0, my_edata, 0, 0);
2298 #ifdef USE_MMAP_FOR_BUFFERS
2299 mmap_set_vars (1);
2300 #endif
2301 #ifdef DOUG_LEA_MALLOC
2302 free (malloc_state_ptr);
2303 #endif
2304
2305 Vpurify_flag = tem;
2306
2307 return unbind_to (count, Qnil);
2308 }
2309
2310 #endif
2311
2312 #if HAVE_SETLOCALE
2313
2314 void
2315 fixup_locale ()
2316 {
2317 2318
2319 setlocale (LC_NUMERIC, "C");
2320 }
2321
2322 2323
2324 static void
2325 synchronize_locale (category, plocale, desired_locale)
2326 int category;
2327 Lisp_Object *plocale;
2328 Lisp_Object desired_locale;
2329 {
2330 if (! EQ (*plocale, desired_locale))
2331 {
2332 *plocale = desired_locale;
2333 setlocale (category, (STRINGP (desired_locale)
2334 ? (char *) SDATA (desired_locale)
2335 : ""));
2336 }
2337 }
2338
2339
2340 void
2341 synchronize_system_time_locale ()
2342 {
2343 synchronize_locale (LC_TIME, &Vprevious_system_time_locale,
2344 Vsystem_time_locale);
2345 }
2346
2347 2348
2349 void
2350 synchronize_system_messages_locale ()
2351 {
2352 #ifdef LC_MESSAGES
2353 synchronize_locale (LC_MESSAGES, &Vprevious_system_messages_locale,
2354 Vsystem_messages_locale);
2355 #endif
2356 }
2357 #endif
2358
2359 #ifndef SEPCHAR
2360 #define SEPCHAR ':'
2361 #endif
2362
2363 Lisp_Object
2364 decode_env_path (evarname, defalt)
2365 char *evarname, *defalt;
2366 {
2367 register char *path, *p;
2368 Lisp_Object lpath, element, tem;
2369
2370 2371 2372
2373 if (evarname != 0)
2374 path = (char *) getenv (evarname);
2375 else
2376 path = 0;
2377 if (!path)
2378 path = defalt;
2379 #ifdef DOS_NT
2380
2381 if (path)
2382 {
2383 p = alloca (strlen (path) + 1);
2384 strcpy (p, path);
2385 path = p;
2386
2387 if ('/' == DIRECTORY_SEP)
2388 dostounix_filename (path);
2389 else
2390 unixtodos_filename (path);
2391 }
2392 #endif
2393 lpath = Qnil;
2394 while (1)
2395 {
2396 p = index (path, SEPCHAR);
2397 if (!p) p = path + strlen (path);
2398 element = (p - path ? make_string (path, p - path)
2399 : build_string ("."));
2400
2401 2402
2403 tem = Ffind_file_name_handler (element, Qt);
2404
2405 2406
2407 if (SYMBOLP (tem))
2408 {
2409 Lisp_Object prop;
2410 prop = Fget (tem, intern ("safe-magic"));
2411 if (! NILP (prop))
2412 tem = Qnil;
2413 }
2414
2415 if (! NILP (tem))
2416 element = concat2 (build_string ("/:"), element);
2417
2418 lpath = Fcons (element, lpath);
2419 if (*p)
2420 path = p + 1;
2421 else
2422 break;
2423 }
2424 return Fnreverse (lpath);
2425 }
2426
2427 DEFUN ("daemonp", Fdaemonp, Sdaemonp, 0, 0, 0,
2428 doc: 2429 )
2430 ()
2431 {
2432 if (IS_DAEMON)
2433 if (daemon_name)
2434 return build_string (daemon_name);
2435 else
2436 return Qt;
2437 else
2438 return Qnil;
2439 }
2440
2441 DEFUN ("daemon-initialized", Fdaemon_initialized, Sdaemon_initialized, 0, 0, 0,
2442 doc: 2443 2444 )
2445 ()
2446 {
2447 int nfd;
2448
2449 if (!IS_DAEMON)
2450 error ("This function can only be called if emacs is run as a daemon");
2451
2452 if (daemon_pipe[1] < 0)
2453 error ("The daemon has already been initialized");
2454
2455 if (NILP (Vafter_init_time))
2456 error ("This function can only be called after loading the init files");
2457
2458
2459 nfd = open ("/dev/null", O_RDWR);
2460 dup2 (nfd, 0);
2461 dup2 (nfd, 1);
2462 dup2 (nfd, 2);
2463 close (nfd);
2464
2465 2466 2467 2468 2469 2470 2471
2472 write (daemon_pipe[1], "\n", 1);
2473 close (daemon_pipe[1]);
2474
2475 daemon_pipe[1] = -1;
2476 return Qt;
2477 }
2478
2479 void
2480 syms_of_emacs ()
2481 {
2482 Qfile_name_handler_alist = intern_c_string ("file-name-handler-alist");
2483 staticpro (&Qfile_name_handler_alist);
2484
2485 #ifndef CANNOT_DUMP
2486 defsubr (&Sdump_emacs);
2487 #endif
2488
2489 defsubr (&Skill_emacs);
2490
2491 defsubr (&Sinvocation_name);
2492 defsubr (&Sinvocation_directory);
2493 defsubr (&Sdaemonp);
2494 defsubr (&Sdaemon_initialized);
2495
2496 DEFVAR_LISP ("command-line-args", &Vcommand_line_args,
2497 doc: 2498 );
2499
2500 DEFVAR_LISP ("system-type", &Vsystem_type,
2501 doc: 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 );
2512 Vsystem_type = intern_c_string (SYSTEM_TYPE);
2513
2514 DEFVAR_LISP ("system-configuration", &Vsystem_configuration,
2515 doc: 2516 2517 );
2518 Vsystem_configuration = build_string (EMACS_CONFIGURATION);
2519
2520 DEFVAR_LISP ("system-configuration-options", &Vsystem_configuration_options,
2521 doc: );
2522 Vsystem_configuration_options = build_string (EMACS_CONFIG_OPTIONS);
2523
2524 DEFVAR_BOOL ("noninteractive", &noninteractive1,
2525 doc: );
2526
2527 DEFVAR_LISP ("kill-emacs-hook", &Vkill_emacs_hook,
2528 doc: 2529 2530 2531 2532 2533 2534 );
2535 Vkill_emacs_hook = Qnil;
2536
2537 DEFVAR_INT ("emacs-priority", &emacs_priority,
2538 doc: 2539 2540 2541 2542 2543 );
2544 emacs_priority = 0;
2545
2546 DEFVAR_LISP ("path-separator", &Vpath_separator,
2547 doc: 2548 );
2549 {
2550 char c = SEPCHAR;
2551 Vpath_separator = make_string (&c, 1);
2552 }
2553
2554 DEFVAR_LISP ("invocation-name", &Vinvocation_name,
2555 doc: 2556 );
2557
2558 DEFVAR_LISP ("invocation-directory", &Vinvocation_directory,
2559 doc: 2560 );
2561
2562 DEFVAR_LISP ("installation-directory", &Vinstallation_directory,
2563 doc: 2564 2565 2566 );
2567 Vinstallation_directory = Qnil;
2568
2569 DEFVAR_LISP ("system-messages-locale", &Vsystem_messages_locale,
2570 doc: );
2571 Vsystem_messages_locale = Qnil;
2572
2573 DEFVAR_LISP ("previous-system-messages-locale",
2574 &Vprevious_system_messages_locale,
2575 doc: );
2576 Vprevious_system_messages_locale = Qnil;
2577
2578 DEFVAR_LISP ("system-time-locale", &Vsystem_time_locale,
2579 doc: );
2580 Vsystem_time_locale = Qnil;
2581
2582 DEFVAR_LISP ("previous-system-time-locale", &Vprevious_system_time_locale,
2583 doc: );
2584 Vprevious_system_time_locale = Qnil;
2585
2586 DEFVAR_LISP ("before-init-time", &Vbefore_init_time,
2587 doc: );
2588 Vbefore_init_time = Qnil;
2589
2590 DEFVAR_LISP ("after-init-time", &Vafter_init_time,
2591 doc: 2592 );
2593 Vafter_init_time = Qnil;
2594
2595 DEFVAR_BOOL ("inhibit-x-resources", &inhibit_x_resources,
2596 doc: );
2597 inhibit_x_resources = 0;
2598
2599 DEFVAR_LISP ("emacs-copyright", &Vemacs_copyright,
2600 doc: );
2601 Vemacs_copyright = build_string (emacs_copyright);
2602
2603 DEFVAR_LISP ("emacs-version", &Vemacs_version,
2604 doc: );
2605 Vemacs_version = build_string (emacs_version);
2606
2607
2608 daemon_pipe[1] = 0;
2609 }
2610
2611 2612