This source file includes following definitions.
- setlocale
- using_utf8
- terminate_due_to_signal
- init_cmdargs
- DEFUN
- DEFUN
- argmatch
- find_emacs_executable
- dump_error_to_string
- load_pdump
- emacs_seccomp
- read_full
- load_seccomp
- maybe_load_seccomp
- main
- sort_args
- shut_down_emacs
- fixup_locale
- synchronize_locale
- synchronize_system_time_locale
- synchronize_system_messages_locale
- emacs_strerror
- decode_env_path
- DEFUN
- DEFUN
- syms_of_emacs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #define INLINE EXTERN_INLINE
22 #include <config.h>
23
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <stdlib.h>
27
28 #include <sys/file.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31
32 #define MAIN_PROGRAM
33 #include "lisp.h"
34 #include "sysstdio.h"
35
36 #ifdef WINDOWSNT
37 #include <fcntl.h>
38 #include <sys/socket.h>
39 #include <mbstring.h>
40 #include <filename.h>
41 #include "w32.h"
42 #include "w32heap.h"
43 #endif
44
45 #if defined WINDOWSNT || defined HAVE_NTGUI
46 #include "w32select.h"
47 #include "w32font.h"
48 #include "w32common.h"
49 #endif
50
51 #if defined CYGWIN
52 #include "cygw32.h"
53 #endif
54
55 #ifdef MSDOS
56 #include <binary-io.h>
57 #include "dosfns.h"
58 #endif
59
60 #ifdef HAVE_LIBSYSTEMD
61 # include <systemd/sd-daemon.h>
62 # include <sys/socket.h>
63 #endif
64
65 #if defined HAVE_LINUX_SECCOMP_H && defined HAVE_LINUX_FILTER_H \
66 && HAVE_DECL_SECCOMP_SET_MODE_FILTER \
67 && HAVE_DECL_SECCOMP_FILTER_FLAG_TSYNC
68 # define SECCOMP_USABLE 1
69 #else
70 # define SECCOMP_USABLE 0
71 #endif
72
73 #if SECCOMP_USABLE
74 # include <linux/seccomp.h>
75 # include <linux/filter.h>
76 # include <sys/prctl.h>
77 # include <sys/syscall.h>
78 #endif
79
80 #ifdef HAVE_WINDOW_SYSTEM
81 #include TERM_HEADER
82 #endif
83
84 #include "bignum.h"
85 #include "itree.h"
86 #include "intervals.h"
87 #include "character.h"
88 #include "buffer.h"
89 #include "window.h"
90 #include "xwidget.h"
91 #include "atimer.h"
92 #include "blockinput.h"
93 #include "syssignal.h"
94 #include "process.h"
95 #include "frame.h"
96 #include "termhooks.h"
97 #include "keyboard.h"
98 #include "keymap.h"
99 #include "category.h"
100 #include "charset.h"
101 #include "composite.h"
102 #include "dispextern.h"
103 #include "regex-emacs.h"
104 #include "sheap.h"
105 #include "syntax.h"
106 #include "sysselect.h"
107 #include "systime.h"
108 #include "puresize.h"
109
110 #include "getpagesize.h"
111 #include "gnutls.h"
112
113 #ifdef HAVE_HAIKU
114 #include <kernel/OS.h>
115 #endif
116
117 #ifdef PROFILING
118 # include <sys/gmon.h>
119 extern void moncontrol (int mode);
120 # ifdef __MINGW32__
121 extern unsigned char etext asm ("etext");
122 # else
123 extern char etext;
124 # endif
125 #endif
126
127 #ifdef HAVE_SETLOCALE
128 #include <locale.h>
129 #endif
130
131 #if HAVE_WCHAR_H
132 # include <wchar.h>
133 #endif
134
135 #ifdef HAVE_SETRLIMIT
136 #include <sys/time.h>
137 #include <sys/resource.h>
138 #endif
139
140
141
142 #include "treesit.h"
143
144 #include "pdumper.h"
145 #include "fingerprint.h"
146 #include "epaths.h"
147
148
149 #include "comp.h"
150 #include "thread.h"
151
152 static const char emacs_version[] = PACKAGE_VERSION;
153 static const char emacs_copyright[] = COPYRIGHT;
154 static const char emacs_bugreport[] = PACKAGE_BUGREPORT;
155
156
157 char const EXTERNALLY_VISIBLE RCS_Id[]
158 = "$Id" ": GNU Emacs " PACKAGE_VERSION
159 " (" EMACS_CONFIGURATION " " EMACS_CONFIG_FEATURES ") $";
160
161
162 Lisp_Object empty_unibyte_string, empty_multibyte_string;
163
164 #ifdef WINDOWSNT
165
166 Lisp_Object Vlibrary_cache;
167
168 static char *initial_cmdline;
169
170 static const char *initial_wd;
171 #endif
172
173 struct gflags gflags;
174 bool initialized;
175
176
177
178 bool inhibit_window_system;
179
180
181
182 bool running_asynch_code;
183
184 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NS)
185
186 bool display_arg;
187 #endif
188
189 #if defined GNU_LINUX && defined HAVE_UNEXEC
190
191 static uintmax_t heap_bss_diff;
192 #endif
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210 #if defined NS_IMPL_COCOA || defined CYGWIN || defined HAVE_HAIKU
211 # define DAEMON_MUST_EXEC
212 #endif
213
214
215 bool noninteractive;
216
217
218 bool no_site_lisp;
219
220
221 bool build_details;
222
223
224 static char *daemon_name;
225
226
227
228 int daemon_type;
229
230 #ifndef WINDOWSNT
231
232
233 static int daemon_pipe[2];
234 #else
235 HANDLE w32_daemon_event;
236 #endif
237
238
239 char **initial_argv;
240 int initial_argc;
241 static char *initial_emacs_executable = NULL;
242
243
244 char const *emacs_wd;
245
246 static void sort_args (int argc, char **argv);
247 static void syms_of_emacs (void);
248
249
250
251 static char const *const usage_message[] =
252 { "\
253 \n\
254 Run Emacs, the extensible, customizable, self-documenting real-time\n\
255 display editor. The recommended way to start Emacs for normal editing\n\
256 is with no options at all.\n\
257 \n\
258 Run M-x info RET m emacs RET m emacs invocation RET inside Emacs to\n\
259 read the main documentation for these command-line arguments.\n\
260 \n\
261 Initialization options:\n\
262 \n\
263 ",
264 "\
265 --batch do not do interactive display; implies -q\n\
266 --chdir DIR change to directory DIR\n\
267 --daemon, --bg-daemon[=NAME] start a (named) server in the background\n\
268 --fg-daemon[=NAME] start a (named) server in the foreground\n\
269 --debug-init enable Emacs Lisp debugger for init file\n\
270 --display, -d DISPLAY use X server DISPLAY\n\
271 ",
272 #ifdef HAVE_MODULES
273 "\
274 --module-assertions assert behavior of dynamic modules\n\
275 ",
276 #endif
277 #ifdef HAVE_PDUMPER
278 "\
279 --dump-file FILE read dumped state from FILE\n\
280 --fingerprint output fingerprint and exit\n\
281 ",
282 #endif
283 #if SECCOMP_USABLE
284 "\
285 --seccomp=FILE read Seccomp BPF filter from FILE\n\
286 "
287 #endif
288 "\
289 --no-build-details do not add build details such as time stamps\n\
290 --no-desktop do not load a saved desktop\n\
291 --no-init-file, -q load neither ~/.emacs nor default.el\n\
292 --no-loadup, -nl do not load loadup.el into bare Emacs\n\
293 --no-site-file do not load site-start.el\n\
294 --no-x-resources do not load X resources\n\
295 --no-site-lisp, -nsl do not add site-lisp directories to load-path\n\
296 --no-splash do not display a splash screen on startup\n\
297 --no-window-system, -nw do not communicate with X, ignoring $DISPLAY\n\
298 --init-directory=DIR use DIR when looking for the Emacs init files.\n\
299 ",
300 "\
301 --quick, -Q equivalent to:\n\
302 -q --no-site-file --no-site-lisp --no-splash\n\
303 --no-x-resources\n\
304 --script FILE run FILE as an Emacs Lisp script\n\
305 -x to be used in #!/usr/bin/emacs -x\n\
306 and has approximately the same meaning\n\
307 as -Q --script\n\
308 --terminal, -t DEVICE use DEVICE for terminal I/O\n\
309 --user, -u USER load ~USER/.emacs instead of your own\n\
310 \n\
311 ",
312 "\
313 Action options:\n\
314 \n\
315 FILE visit FILE\n\
316 +LINE go to line LINE in next FILE\n\
317 +LINE:COLUMN go to line LINE, column COLUMN, in next FILE\n\
318 --directory, -L DIR prepend DIR to load-path (with :DIR, append DIR)\n\
319 --eval EXPR evaluate Emacs Lisp expression EXPR\n\
320 --execute EXPR evaluate Emacs Lisp expression EXPR\n\
321 ",
322 "\
323 --file FILE visit FILE\n\
324 --find-file FILE visit FILE\n\
325 --funcall, -f FUNC call Emacs Lisp function FUNC with no arguments\n\
326 --insert FILE insert contents of FILE into current buffer\n\
327 --kill exit without asking for confirmation\n\
328 --load, -l FILE load Emacs Lisp FILE using the load function\n\
329 --visit FILE visit FILE\n\
330 \n\
331 ",
332 "\
333 Display options:\n\
334 \n\
335 --background-color, -bg COLOR window background color\n\
336 --basic-display, -D disable many display features;\n\
337 used for debugging Emacs\n\
338 --border-color, -bd COLOR main border color\n\
339 --border-width, -bw WIDTH width of main border\n\
340 ",
341 "\
342 --color, --color=MODE override color mode for character terminals;\n\
343 MODE defaults to `auto', and\n\
344 can also be `never', `always',\n\
345 or a mode name like `ansi8'\n\
346 --cursor-color, -cr COLOR color of the Emacs cursor indicating point\n\
347 --font, -fn FONT default font; must be fixed-width\n\
348 --foreground-color, -fg COLOR window foreground color\n\
349 ",
350 "\
351 --fullheight, -fh make the first frame high as the screen\n\
352 --fullscreen, -fs make the first frame fullscreen\n\
353 --fullwidth, -fw make the first frame wide as the screen\n\
354 --maximized, -mm make the first frame maximized\n\
355 --geometry, -g GEOMETRY window geometry\n\
356 ",
357 "\
358 --no-bitmap-icon, -nbi do not use picture of gnu for Emacs icon\n\
359 --iconic start Emacs in iconified state\n\
360 --internal-border, -ib WIDTH width between text and main border\n\
361 --line-spacing, -lsp PIXELS additional space to put between lines\n\
362 --mouse-color, -ms COLOR mouse cursor color in Emacs window\n\
363 --name NAME title for initial Emacs frame\n\
364 ",
365 "\
366 --no-blinking-cursor, -nbc disable blinking cursor\n\
367 --reverse-video, -r, -rv switch foreground and background\n\
368 --title, -T TITLE title for initial Emacs frame\n\
369 --vertical-scroll-bars, -vb enable vertical scroll bars\n\
370 --xrm XRESOURCES set additional X resources\n\
371 --parent-id XID set parent window\n\
372 --help display this help and exit\n\
373 --version output version information and exit\n\
374 \n\
375 ",
376 "\
377 You can generally also specify long option names with a single -; for\n\
378 example, -batch as well as --batch. You can use any unambiguous\n\
379 abbreviation for a --option.\n\
380 \n\
381 Various environment variables and window system resources also affect\n\
382 the operation of Emacs. See the main documentation.\n\
383 \n\
384 Report bugs to " PACKAGE_BUGREPORT ". First, please see the Bugs\n\
385 section of the Emacs manual or the file BUGS.\n"
386 };
387
388
389
390 bool fatal_error_in_progress;
391
392 #ifdef HAVE_NS
393
394 static void *ns_pool;
395 #endif
396
397 #if !HAVE_SETLOCALE
398 static char *
399 setlocale (int cat, char const *locale)
400 {
401 return 0;
402 }
403 #endif
404
405
406 static bool
407 using_utf8 (void)
408 {
409
410
411
412 #if defined HAVE_WCHAR_H && !defined WINDOWSNT
413 wchar_t wc;
414 mbstate_t mbs = { 0 };
415 return mbrtowc (&wc, "\xc4\x80", 2, &mbs) == 2 && wc == 0x100;
416 #else
417 return false;
418 #endif
419 }
420
421
422
423
424 AVOID
425 terminate_due_to_signal (int sig, int backtrace_limit)
426 {
427 signal (sig, SIG_DFL);
428
429 if (attempt_orderly_shutdown_on_fatal_signal)
430 {
431
432 if (! fatal_error_in_progress)
433 {
434 fatal_error_in_progress = 1;
435
436 totally_unblock_input ();
437 if (sig == SIGTERM || sig == SIGHUP || sig == SIGINT)
438 {
439
440
441
442 if (noninteractive)
443 clear_message_stack ();
444 Fkill_emacs (make_fixnum (sig), Qnil);
445 }
446
447 shut_down_emacs (sig, Qnil);
448 emacs_backtrace (backtrace_limit);
449 }
450 }
451
452
453
454
455 #ifndef MSDOS
456 {
457 sigset_t unblocked;
458 sigemptyset (&unblocked);
459 sigaddset (&unblocked, sig);
460 pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
461 }
462 #endif
463
464 emacs_raise (sig);
465
466
467 exit (1);
468 }
469
470
471
472 static void
473 init_cmdargs (int argc, char **argv, int skip_args, char const *original_pwd)
474 {
475 int i;
476 Lisp_Object name, dir, handler;
477 specpdl_ref count = SPECPDL_INDEX ();
478 Lisp_Object raw_name;
479 AUTO_STRING (slash_colon, "/:");
480
481 initial_argv = argv;
482 initial_argc = argc;
483
484 #ifdef WINDOWSNT
485
486
487 {
488 char argv0[MAX_UTF8_PATH];
489
490 if (filename_from_ansi (argv[0], argv0) == 0)
491 raw_name = build_unibyte_string (argv0);
492 else
493 raw_name = build_unibyte_string (argv[0]);
494 }
495 #else
496 raw_name = build_unibyte_string (argv[0]);
497 #endif
498
499
500
501 handler = Ffind_file_name_handler (raw_name, Qt);
502 if (! NILP (handler))
503 raw_name = concat2 (slash_colon, raw_name);
504
505 Vinvocation_name = Ffile_name_nondirectory (raw_name);
506 Vinvocation_directory = Ffile_name_directory (raw_name);
507
508
509
510 if (NILP (Vinvocation_directory))
511 {
512 Lisp_Object found;
513 int yes = openp (Vexec_path, Vinvocation_name, Vexec_suffixes,
514 &found, make_fixnum (X_OK), false, false);
515 if (yes == 1)
516 {
517
518
519 handler = Ffind_file_name_handler (found, Qt);
520 if (! NILP (handler))
521 found = concat2 (slash_colon, found);
522 Vinvocation_directory = Ffile_name_directory (found);
523 }
524 }
525
526 if (!NILP (Vinvocation_directory)
527 && NILP (Ffile_name_absolute_p (Vinvocation_directory)))
528
529
530 {
531 Lisp_Object odir =
532 original_pwd ? build_unibyte_string (original_pwd) : Qnil;
533
534 Vinvocation_directory = Fexpand_file_name (Vinvocation_directory, odir);
535 }
536
537 Vinstallation_directory = Qnil;
538
539 if (!NILP (Vinvocation_directory))
540 {
541 dir = Vinvocation_directory;
542 #ifdef WINDOWSNT
543
544
545
546 if (SBYTES (dir) > sizeof ("/i386/") - 1
547 && 0 == strcmp (SSDATA (dir) + SBYTES (dir) - sizeof ("/i386/") + 1,
548 "/i386/"))
549 {
550 if (NILP (Vpurify_flag))
551 {
552 Lisp_Object file_truename = intern ("file-truename");
553 if (!NILP (Ffboundp (file_truename)))
554 dir = call1 (file_truename, dir);
555 }
556 dir = Fexpand_file_name (build_string ("../.."), dir);
557 }
558 #endif
559 name = Fexpand_file_name (Vinvocation_name, dir);
560 while (1)
561 {
562 Lisp_Object tem, lib_src_exists;
563 Lisp_Object etc_exists, info_exists;
564
565
566
567
568 tem = Fexpand_file_name (build_string ("lib-src"), dir);
569 lib_src_exists = Ffile_exists_p (tem);
570
571 #ifdef MSDOS
572
573
574
575 tem = Fexpand_file_name (build_string ("info"), dir);
576 info_exists = Ffile_exists_p (tem);
577 #else
578 info_exists = Qnil;
579 #endif
580
581 if (!NILP (lib_src_exists) || !NILP (info_exists))
582 {
583 tem = Fexpand_file_name (build_string ("etc"), dir);
584 etc_exists = Ffile_exists_p (tem);
585 if (!NILP (etc_exists))
586 {
587 Vinstallation_directory = Ffile_name_as_directory (dir);
588 break;
589 }
590 }
591
592
593 tem = Fexpand_file_name (build_string ("../lib-src"), dir);
594 lib_src_exists = Ffile_exists_p (tem);
595
596
597 #ifdef MSDOS
598
599 tem = Fexpand_file_name (build_string ("../info"), dir);
600 info_exists = Ffile_exists_p (tem);
601 #else
602 info_exists = Qnil;
603 #endif
604
605 if (!NILP (lib_src_exists) || !NILP (info_exists))
606 {
607 tem = Fexpand_file_name (build_string ("../etc"), dir);
608 etc_exists = Ffile_exists_p (tem);
609 if (!NILP (etc_exists))
610 {
611 tem = Fexpand_file_name (build_string (".."), dir);
612 Vinstallation_directory = Ffile_name_as_directory (tem);
613 break;
614 }
615 }
616
617
618
619 tem = Ffile_symlink_p (name);
620 if (!NILP (tem))
621 {
622 name = Fexpand_file_name (tem, dir);
623 dir = Ffile_name_directory (name);
624 }
625 else
626 break;
627 }
628 }
629
630 Vcommand_line_args = Qnil;
631
632 for (i = argc - 1; i >= 0; i--)
633 {
634 if (i == 0 || i > skip_args)
635
636
637
638 Vcommand_line_args
639 = Fcons (build_unibyte_string (argv[i]), Vcommand_line_args);
640 }
641
642 unbind_to (count, Qnil);
643 }
644
645 DEFUN ("invocation-name", Finvocation_name, Sinvocation_name, 0, 0, 0,
646 doc:
647 )
648 (void)
649 {
650 return Fcopy_sequence (Vinvocation_name);
651 }
652
653 DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory,
654 0, 0, 0,
655 doc: )
656 (void)
657 {
658 return Fcopy_sequence (Vinvocation_directory);
659 }
660
661
662
663
664
665
666
667
668
669
670
671
672 static bool
673 argmatch (char **argv, int argc, const char *sstr, const char *lstr,
674 int minlen, char **valptr, int *skipptr)
675 {
676 char *p = NULL;
677 ptrdiff_t arglen;
678 char *arg;
679
680
681 if (argc <= *skipptr + 1)
682 return 0;
683
684 arg = argv[*skipptr+1];
685 if (arg == NULL)
686 return 0;
687 if (strcmp (arg, sstr) == 0)
688 {
689 if (valptr != NULL)
690 {
691 *valptr = argv[*skipptr+2];
692 *skipptr += 2;
693 }
694 else
695 *skipptr += 1;
696 return 1;
697 }
698 arglen = (valptr != NULL && (p = strchr (arg, '=')) != NULL
699 ? p - arg : strlen (arg));
700 if (!lstr)
701 return 0;
702 if (arglen < minlen || strncmp (arg, lstr, arglen) != 0)
703 return 0;
704 else if (valptr == NULL)
705 {
706 *skipptr += 1;
707 return 1;
708 }
709 else if (p != NULL)
710 {
711 *valptr = p+1;
712 *skipptr += 1;
713 return 1;
714 }
715 else if (argv[*skipptr+2] != NULL)
716 {
717 *valptr = argv[*skipptr+2];
718 *skipptr += 2;
719 return 1;
720 }
721 else
722 {
723 return 0;
724 }
725 }
726
727
728
729
730
731
732
733
734 static char *
735 find_emacs_executable (char const *argv0, ptrdiff_t *candidate_size)
736 {
737 *candidate_size = 0;
738
739
740
741 #ifdef WINDOWSNT
742 char *prog_fname = w32_my_exename ();
743 if (prog_fname)
744 *candidate_size = strlen (prog_fname) + 1;
745 return prog_fname ? xstrdup (prog_fname) : NULL;
746 #else
747 char *candidate = NULL;
748
749
750
751 eassert (argv0);
752 if (strchr (argv0, DIRECTORY_SEP))
753 {
754 char *real_name = realpath (argv0, NULL);
755
756 if (real_name)
757 {
758 *candidate_size = strlen (real_name) + 1;
759 return real_name;
760 }
761
762 char *val = xstrdup (argv0);
763 *candidate_size = strlen (val) + 1;
764 return val;
765 }
766 ptrdiff_t argv0_length = strlen (argv0);
767
768 const char *path = getenv ("PATH");
769 if (!path)
770 {
771
772
773 return NULL;
774 }
775
776
777
778 do
779 {
780 static char const path_sep[] = { SEPCHAR, '\0' };
781 ptrdiff_t path_part_length = strcspn (path, path_sep);
782 const char *path_part = path;
783 path += path_part_length;
784 if (path_part_length == 0)
785 {
786 path_part = ".";
787 path_part_length = 1;
788 }
789 ptrdiff_t needed = path_part_length + 1 + argv0_length + 1;
790 if (*candidate_size <= needed)
791 {
792 xfree (candidate);
793 candidate = xpalloc (NULL, candidate_size,
794 needed - *candidate_size + 1, -1, 1);
795 }
796 memcpy (candidate + 0, path_part, path_part_length);
797 candidate[path_part_length] = DIRECTORY_SEP;
798 memcpy (candidate + path_part_length + 1, argv0, argv0_length + 1);
799 struct stat st;
800 if (file_access_p (candidate, X_OK)
801 && stat (candidate, &st) == 0 && S_ISREG (st.st_mode))
802 {
803
804
805
806 if (lstat (candidate, &st) == 0 && S_ISLNK (st.st_mode))
807 {
808 char *real_name = realpath (candidate, NULL);
809
810 if (real_name)
811 {
812 *candidate_size = strlen (real_name) + 1;
813 return real_name;
814 }
815 }
816 return candidate;
817 }
818 *candidate = '\0';
819 }
820 while (*path++ != '\0');
821
822 return candidate;
823 #endif
824 }
825
826 #ifdef HAVE_PDUMPER
827
828 static const char *
829 dump_error_to_string (int result)
830 {
831 switch (result)
832 {
833 case PDUMPER_LOAD_SUCCESS:
834 return "success";
835 case PDUMPER_LOAD_OOM:
836 return "out of memory";
837 case PDUMPER_NOT_LOADED:
838 return "not loaded";
839 case PDUMPER_LOAD_FILE_NOT_FOUND:
840 return "could not open file";
841 case PDUMPER_LOAD_BAD_FILE_TYPE:
842 return "not a dump file";
843 case PDUMPER_LOAD_FAILED_DUMP:
844 return "dump file is result of failed dump attempt";
845 case PDUMPER_LOAD_VERSION_MISMATCH:
846 return "not built for this Emacs executable";
847 default:
848 return (result <= PDUMPER_LOAD_ERROR
849 ? "generic error"
850 : strerror (result - PDUMPER_LOAD_ERROR));
851 }
852 }
853
854
855 static char *
856 load_pdump (int argc, char **argv)
857 {
858 const char *const suffix = ".pdmp";
859 int result;
860 char *emacs_executable = argv[0];
861 ptrdiff_t hexbuf_size;
862 char *hexbuf;
863 const char *strip_suffix =
864 #if defined DOS_NT || defined CYGWIN
865 ".exe"
866 #else
867 NULL
868 #endif
869 ;
870 const char *argv0_base =
871 #ifdef NS_SELF_CONTAINED
872 "Emacs"
873 #else
874 "emacs"
875 #endif
876 ;
877
878
879
880
881
882
883 if (initialized)
884 fatal ("cannot load dump file in unexeced Emacs");
885
886
887 const char *path_exec = PATH_EXEC;
888 char *dump_file = NULL;
889 int skip_args = 0;
890 while (skip_args < argc - 1)
891 {
892 if (argmatch (argv, argc, "-dump-file", "--dump-file", 6,
893 &dump_file, &skip_args)
894 || argmatch (argv, argc, "--", NULL, 2, NULL, &skip_args))
895 break;
896 skip_args++;
897 }
898
899
900 ptrdiff_t exec_bufsize, bufsize, needed;
901 emacs_executable = find_emacs_executable (argv[0], &exec_bufsize);
902
903
904
905 if (!(emacs_executable && *emacs_executable))
906 {
907 bufsize = 0;
908 dump_file = NULL;
909 goto hardcoded;
910 }
911
912 if (dump_file)
913 {
914 result = pdumper_load (dump_file, emacs_executable);
915
916 if (result != PDUMPER_LOAD_SUCCESS)
917 fatal ("could not load dump file \"%s\": %s",
918 dump_file, dump_error_to_string (result));
919 return emacs_executable;
920 }
921
922
923
924
925
926
927
928 ptrdiff_t exenamelen = strlen (emacs_executable);
929 if (strip_suffix)
930 {
931 ptrdiff_t strip_suffix_length = strlen (strip_suffix);
932 ptrdiff_t prefix_length = exenamelen - strip_suffix_length;
933 if (0 <= prefix_length
934 && !memcmp (&emacs_executable[prefix_length], strip_suffix,
935 strip_suffix_length))
936 exenamelen = prefix_length;
937 }
938 bufsize = exenamelen + strlen (suffix) + 1;
939 dump_file = xpalloc (NULL, &bufsize, 1, -1, 1);
940 memcpy (dump_file, emacs_executable, exenamelen);
941 strcpy (dump_file + exenamelen, suffix);
942 result = pdumper_load (dump_file, emacs_executable);
943 if (result == PDUMPER_LOAD_SUCCESS)
944 goto out;
945
946 if (result != PDUMPER_LOAD_FILE_NOT_FOUND)
947 fatal ("could not load dump file \"%s\": %s",
948 dump_file, dump_error_to_string (result));
949
950 hardcoded:
951
952 #ifdef WINDOWSNT
953
954
955 path_exec = w32_relocate (path_exec);
956 #elif defined (HAVE_NS)
957 path_exec = ns_relocate (path_exec);
958 #endif
959
960
961
962
963 hexbuf_size = 2 * sizeof fingerprint;
964 hexbuf = xmalloc (hexbuf_size + 1);
965 hexbuf_digest (hexbuf, (char *) fingerprint, sizeof fingerprint);
966 hexbuf[hexbuf_size] = '\0';
967 needed = (strlen (path_exec)
968 + 1
969 + strlen (argv0_base)
970 + 1
971 + strlen (hexbuf)
972 + strlen (suffix)
973 + 1);
974 if (bufsize < needed)
975 {
976 xfree (dump_file);
977 dump_file = xpalloc (NULL, &bufsize, needed - bufsize, -1, 1);
978 }
979 sprintf (dump_file, "%s%c%s-%s%s",
980 path_exec, DIRECTORY_SEP, argv0_base, hexbuf, suffix);
981 #if !defined (NS_SELF_CONTAINED)
982 if (!(emacs_executable && *emacs_executable))
983 {
984
985
986
987 const char *go_up = "../../../../bin/";
988 needed += (strip_suffix ? strlen (strip_suffix) : 0)
989 - strlen (suffix) + strlen (go_up);
990 if (exec_bufsize < needed)
991 {
992 xfree (emacs_executable);
993 emacs_executable = xpalloc (NULL, &exec_bufsize,
994 needed - exec_bufsize, -1, 1);
995 }
996 sprintf (emacs_executable, "%s%c%s%s%s",
997 path_exec, DIRECTORY_SEP, go_up, argv0_base,
998 strip_suffix ? strip_suffix : "");
999 }
1000 #endif
1001 result = pdumper_load (dump_file, emacs_executable);
1002
1003 if (result == PDUMPER_LOAD_FILE_NOT_FOUND)
1004 {
1005
1006
1007
1008
1009 char *p, *last_sep = NULL;
1010 for (p = argv[0]; *p; p++)
1011 {
1012 if (IS_DIRECTORY_SEP (*p))
1013 last_sep = p;
1014 }
1015 argv0_base = last_sep ? last_sep + 1 : argv[0];
1016 ptrdiff_t needed = (strlen (path_exec)
1017 + 1
1018 + strlen (argv0_base)
1019 + strlen (suffix)
1020 + 1);
1021 if (bufsize < needed)
1022 {
1023 xfree (dump_file);
1024 dump_file = xmalloc (needed);
1025 }
1026 #ifdef DOS_NT
1027 ptrdiff_t argv0_len = strlen (argv0_base);
1028 if (argv0_len >= 4
1029 && c_strcasecmp (argv0_base + argv0_len - 4, ".exe") == 0)
1030 sprintf (dump_file, "%s%c%.*s%s", path_exec, DIRECTORY_SEP,
1031 (int)(argv0_len - 4), argv0_base, suffix);
1032 else
1033 #endif
1034 sprintf (dump_file, "%s%c%s%s",
1035 path_exec, DIRECTORY_SEP, argv0_base, suffix);
1036 result = pdumper_load (dump_file, emacs_executable);
1037 }
1038
1039 if (result != PDUMPER_LOAD_SUCCESS)
1040 {
1041 if (result != PDUMPER_LOAD_FILE_NOT_FOUND)
1042 fatal ("could not load dump file \"%s\": %s",
1043 dump_file, dump_error_to_string (result));
1044 }
1045
1046 out:
1047 xfree (dump_file);
1048
1049 return emacs_executable;
1050 }
1051 #endif
1052
1053 #if SECCOMP_USABLE
1054
1055
1056
1057
1058
1059 static int
1060 emacs_seccomp (unsigned int operation, unsigned int flags, void *args)
1061 {
1062 #ifdef SYS_seccomp
1063 return syscall (SYS_seccomp, operation, flags, args);
1064 #else
1065 errno = ENOSYS;
1066 return -1;
1067 #endif
1068 }
1069
1070
1071
1072
1073 static ptrdiff_t
1074 read_full (int fd, void *buffer, ptrdiff_t size)
1075 {
1076 eassert (0 <= fd);
1077 eassert (buffer != NULL);
1078 eassert (0 <= size);
1079 enum
1080 {
1081
1082 #ifdef MAX_RW_COUNT
1083 max_size = MAX_RW_COUNT
1084 #else
1085 max_size = INT_MAX >> 18 << 18
1086 #endif
1087 };
1088 if (PTRDIFF_MAX < size || max_size < size)
1089 {
1090 errno = EFBIG;
1091 return -1;
1092 }
1093 char *ptr = buffer;
1094 ptrdiff_t read = 0;
1095 while (size != 0)
1096 {
1097 ptrdiff_t n = emacs_read (fd, ptr, size);
1098 if (n < 0)
1099 return -1;
1100 if (n == 0)
1101 break;
1102 eassert (n <= size);
1103 size -= n;
1104 ptr += n;
1105 read += n;
1106 }
1107 return read;
1108 }
1109
1110
1111
1112
1113 static bool
1114 load_seccomp (const char *file)
1115 {
1116 bool success = false;
1117 void *buffer = NULL;
1118 int fd
1119 = emacs_open_noquit (file, O_RDONLY | O_CLOEXEC | O_BINARY, 0);
1120 if (fd < 0)
1121 {
1122 emacs_perror ("open");
1123 goto out;
1124 }
1125 struct stat stat;
1126 if (fstat (fd, &stat) != 0)
1127 {
1128 emacs_perror ("fstat");
1129 goto out;
1130 }
1131 if (! S_ISREG (stat.st_mode))
1132 {
1133 fprintf (stderr, "seccomp file %s is not regular\n", file);
1134 goto out;
1135 }
1136 struct sock_fprog program;
1137 if (stat.st_size <= 0 || SIZE_MAX <= stat.st_size
1138 || PTRDIFF_MAX <= stat.st_size
1139 || stat.st_size % sizeof *program.filter != 0)
1140 {
1141 fprintf (stderr, "seccomp filter %s has invalid size %ld\n",
1142 file, (long) stat.st_size);
1143 goto out;
1144 }
1145 size_t size = stat.st_size;
1146 size_t count = size / sizeof *program.filter;
1147 eassert (0 < count && count < SIZE_MAX);
1148 if (USHRT_MAX < count)
1149 {
1150 fprintf (stderr, "seccomp filter %s is too big\n", file);
1151 goto out;
1152 }
1153
1154 buffer = malloc (size + 1);
1155 if (buffer == NULL)
1156 {
1157 emacs_perror ("malloc");
1158 goto out;
1159 }
1160 ptrdiff_t read = read_full (fd, buffer, size + 1);
1161 if (read < 0)
1162 {
1163 emacs_perror ("read");
1164 goto out;
1165 }
1166 eassert (read <= SIZE_MAX);
1167 if (read != size)
1168 {
1169 fprintf (stderr,
1170 "seccomp filter %s changed size while reading\n",
1171 file);
1172 goto out;
1173 }
1174 if (emacs_close (fd) != 0)
1175 emacs_perror ("close");
1176 fd = -1;
1177 program.len = count;
1178 program.filter = buffer;
1179
1180
1181
1182
1183
1184
1185 prctl (PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1186
1187
1188 if (emacs_seccomp (SECCOMP_SET_MODE_FILTER,
1189 SECCOMP_FILTER_FLAG_TSYNC, &program)
1190 != 0)
1191 {
1192 emacs_perror ("seccomp");
1193 goto out;
1194 }
1195 success = true;
1196
1197 out:
1198 if (0 <= fd)
1199 emacs_close (fd);
1200 free (buffer);
1201 return success;
1202 }
1203
1204
1205
1206
1207 static void
1208 maybe_load_seccomp (int argc, char **argv)
1209 {
1210 int skip_args = 0;
1211 char *file = NULL;
1212 while (skip_args < argc - 1)
1213 {
1214 if (argmatch (argv, argc, "-seccomp", "--seccomp", 9, &file,
1215 &skip_args)
1216 || argmatch (argv, argc, "--", NULL, 2, NULL, &skip_args))
1217 break;
1218 ++skip_args;
1219 }
1220 if (file == NULL)
1221 return;
1222 if (! load_seccomp (file))
1223 fatal ("cannot enable seccomp filter from %s", file);
1224 }
1225
1226 #endif
1227
1228 int
1229 main (int argc, char **argv)
1230 {
1231
1232
1233 void *stack_bottom_variable;
1234
1235
1236
1237
1238 #if SECCOMP_USABLE
1239 maybe_load_seccomp (argc, argv);
1240 #endif
1241
1242 bool no_loadup = false;
1243 char *junk = 0;
1244 char *dname_arg = 0;
1245 #ifdef DAEMON_MUST_EXEC
1246 char dname_arg2[80];
1247 #endif
1248 char *ch_to_dir = 0;
1249
1250
1251 char const *original_pwd = 0;
1252
1253
1254 stack_bottom = (char *) &stack_bottom_variable;
1255
1256 const char *dump_mode = NULL;
1257 int skip_args = 0;
1258 char *temacs = NULL;
1259 while (skip_args < argc - 1)
1260 {
1261 if (argmatch (argv, argc, "-temacs", "--temacs", 8, &temacs, &skip_args)
1262 || argmatch (argv, argc, "--", NULL, 2, NULL, &skip_args))
1263 break;
1264 skip_args++;
1265 }
1266 #ifdef HAVE_PDUMPER
1267 bool attempt_load_pdump = false;
1268 #endif
1269
1270
1271
1272 if (!initialized && temacs)
1273 {
1274 #ifdef HAVE_UNEXEC
1275 if (strcmp (temacs, "dump") == 0 ||
1276 strcmp (temacs, "bootstrap") == 0)
1277 gflags.will_dump_with_unexec_ = true;
1278 #endif
1279 #ifdef HAVE_PDUMPER
1280 if (strcmp (temacs, "pdump") == 0 ||
1281 strcmp (temacs, "pbootstrap") == 0)
1282 gflags.will_dump_with_pdumper_ = true;
1283 #endif
1284 #if defined HAVE_PDUMPER || defined HAVE_UNEXEC
1285 if (strcmp (temacs, "bootstrap") == 0 ||
1286 strcmp (temacs, "pbootstrap") == 0)
1287 gflags.will_bootstrap_ = true;
1288 gflags.will_dump_ =
1289 will_dump_with_pdumper_p () ||
1290 will_dump_with_unexec_p ();
1291 if (will_dump_p ())
1292 dump_mode = temacs;
1293 #endif
1294 if (!dump_mode)
1295 fatal ("Invalid temacs mode '%s'", temacs);
1296 }
1297 else if (temacs)
1298 {
1299 fatal ("--temacs not supported for unexeced emacs");
1300 }
1301 else
1302 {
1303 eassert (!temacs);
1304 #ifndef HAVE_UNEXEC
1305 eassert (!initialized);
1306 #endif
1307 #ifdef HAVE_PDUMPER
1308 if (!initialized)
1309 attempt_load_pdump = true;
1310 #endif
1311 }
1312
1313 #ifdef HAVE_UNEXEC
1314 if (!will_dump_with_unexec_p ())
1315 gflags.will_not_unexec_ = true;
1316 #endif
1317
1318 #ifdef WINDOWSNT
1319
1320
1321
1322 bool use_dynamic_heap = true;
1323 if (temacs)
1324 {
1325 char *temacs_str = NULL, *p;
1326 for (p = argv[0]; (p = strstr (p, "temacs")) != NULL; p++)
1327 temacs_str = p;
1328 if (temacs_str != NULL
1329 && (temacs_str == argv[0] || IS_DIRECTORY_SEP (temacs_str[-1])))
1330 {
1331
1332
1333
1334
1335
1336 use_dynamic_heap = will_dump_with_pdumper_p ();
1337 }
1338 }
1339 init_heap (use_dynamic_heap);
1340 initial_cmdline = GetCommandLine ();
1341 #endif
1342 #if defined WINDOWSNT || defined HAVE_NTGUI
1343
1344
1345
1346 cache_system_info ();
1347 #ifdef WINDOWSNT
1348
1349
1350
1351 maybe_load_unicows_dll ();
1352
1353
1354 w32_init_file_name_codepage ();
1355
1356 w32_init_current_directory ();
1357 #endif
1358 w32_init_main_thread ();
1359 #endif
1360
1361 #ifdef HAVE_PDUMPER
1362 if (attempt_load_pdump)
1363 initial_emacs_executable = load_pdump (argc, argv);
1364 #else
1365 ptrdiff_t bufsize;
1366 initial_emacs_executable = find_emacs_executable (argv[0], &bufsize);
1367 #endif
1368
1369 argc = maybe_disable_address_randomization (argc, argv);
1370
1371 #if defined GNU_LINUX && defined HAVE_UNEXEC
1372 if (!initialized)
1373 {
1374 char *heap_start = my_heap_start ();
1375 heap_bss_diff = heap_start - max (my_endbss, my_endbss_static);
1376 }
1377 #endif
1378
1379 #ifdef RUN_TIME_REMAP
1380 if (initialized)
1381 run_time_remap (argv[0]);
1382 #endif
1383
1384
1385 #if defined DARWIN_OS && defined HAVE_UNEXEC
1386 if (!initialized)
1387 unexec_init_emacs_zone ();
1388 #endif
1389
1390 init_standard_fds ();
1391 atexit (close_output_streams);
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426 bool only_version = false;
1427 sort_args (argc, argv);
1428 argc = 0;
1429 while (argv[argc]) argc++;
1430
1431 skip_args = 0;
1432 if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args))
1433 only_version = true;
1434
1435 #ifdef HAVE_PDUMPER
1436 if (argmatch (argv, argc, "-fingerprint", "--fingerprint", 4,
1437 NULL, &skip_args)
1438 && !only_version)
1439 {
1440 if (initialized)
1441 {
1442 dump_fingerprint (stdout, "",
1443 (unsigned char *) fingerprint);
1444 exit (0);
1445 }
1446 else
1447 {
1448 fputs ("Not initialized\n", stderr);
1449 exit (1);
1450 }
1451 }
1452 #endif
1453
1454 emacs_wd = emacs_get_current_dir_name ();
1455 #ifdef WINDOWSNT
1456 initial_wd = emacs_wd;
1457 #endif
1458 #ifdef HAVE_PDUMPER
1459 if (dumped_with_pdumper_p ())
1460 pdumper_record_wd (emacs_wd);
1461 #endif
1462
1463 if (argmatch (argv, argc, "-chdir", "--chdir", 4, &ch_to_dir, &skip_args)
1464 && !only_version)
1465 {
1466 #ifdef WINDOWSNT
1467
1468
1469 char newdir[MAX_UTF8_PATH];
1470
1471 filename_from_ansi (ch_to_dir, newdir);
1472 ch_to_dir = newdir;
1473 #endif
1474 if (chdir (ch_to_dir) != 0)
1475 {
1476 fprintf (stderr, "%s: Can't chdir to %s: %s\n",
1477 argv[0], ch_to_dir, strerror (errno));
1478 exit (1);
1479 }
1480 original_pwd = emacs_wd;
1481 #ifdef WINDOWSNT
1482
1483 w32_init_current_directory ();
1484 #endif
1485 emacs_wd = emacs_get_current_dir_name ();
1486 }
1487
1488 #if defined (HAVE_SETRLIMIT) && defined (RLIMIT_STACK) && !defined (CYGWIN)
1489
1490
1491
1492
1493
1494
1495 struct rlimit rlim;
1496 if (getrlimit (RLIMIT_STACK, &rlim) == 0
1497 && 0 <= rlim.rlim_cur && rlim.rlim_cur <= LONG_MAX)
1498 {
1499 rlim_t lim = rlim.rlim_cur;
1500
1501
1502
1503
1504
1505 int min_ratio = 20 * sizeof (char *);
1506 int ratio = min_ratio + min_ratio / 3;
1507
1508
1509
1510
1511 int extra = (30 * 1000) * 50;
1512
1513 bool try_to_grow_stack = !noninteractive || initialized;
1514
1515 if (try_to_grow_stack)
1516 {
1517 rlim_t newlim = emacs_re_max_failures * ratio + extra;
1518
1519
1520
1521
1522
1523
1524
1525
1526 long pagesize = getpagesize ();
1527 newlim += pagesize - 1;
1528 if (0 <= rlim.rlim_max && rlim.rlim_max < newlim)
1529 newlim = rlim.rlim_max;
1530 newlim -= newlim % pagesize;
1531
1532 if (newlim > lim
1533 && pagesize <= newlim - lim)
1534 {
1535 rlim.rlim_cur = newlim;
1536 if (setrlimit (RLIMIT_STACK, &rlim) == 0)
1537 lim = newlim;
1538 }
1539 }
1540
1541
1542 if (lim < extra)
1543 lim = extra;
1544 ptrdiff_t max_failures
1545 = min (lim - extra, min (PTRDIFF_MAX, SIZE_MAX)) / ratio;
1546 emacs_re_safe_alloca = max (max_failures * min_ratio, MAX_ALLOCA);
1547 }
1548 #endif
1549
1550 clearerr (stdin);
1551
1552 emacs_backtrace (-1);
1553
1554 #if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
1555
1556 memory_warnings (0, malloc_warning);
1557
1558
1559
1560 free (realloc (malloc (4), 4));
1561
1562 #endif
1563
1564 #ifdef MSDOS
1565 set_binary_mode (STDIN_FILENO, O_BINARY);
1566 fflush (stdout);
1567 set_binary_mode (STDOUT_FILENO, O_BINARY);
1568 #endif
1569
1570
1571
1572
1573
1574
1575 char *lc_all = getenv ("LC_ALL");
1576 if (! (lc_all && strcmp (lc_all, "C") == 0))
1577 {
1578 #ifdef HAVE_NS
1579 ns_pool = ns_alloc_autorelease_pool ();
1580 ns_init_locale ();
1581 #endif
1582 setlocale (LC_ALL, "");
1583 fixup_locale ();
1584 }
1585 text_quoting_flag = using_utf8 ();
1586
1587 inhibit_window_system = 0;
1588
1589
1590 while (!only_version)
1591 {
1592 char *term;
1593 if (argmatch (argv, argc, "-t", "--terminal", 4, &term, &skip_args))
1594 {
1595 emacs_close (STDIN_FILENO);
1596 emacs_close (STDOUT_FILENO);
1597 int result = emacs_open_noquit (term, O_RDWR, 0);
1598 if (result != STDIN_FILENO
1599 || (fcntl (STDIN_FILENO, F_DUPFD_CLOEXEC, STDOUT_FILENO)
1600 != STDOUT_FILENO))
1601 {
1602 const char *errstring = strerror (errno);
1603 fprintf (stderr, "%s: %s: %s\n", argv[0], term, errstring);
1604 exit (EXIT_FAILURE);
1605 }
1606 if (! isatty (STDIN_FILENO))
1607 {
1608 fprintf (stderr, "%s: %s: not a tty\n", argv[0], term);
1609 exit (EXIT_FAILURE);
1610 }
1611 fprintf (stderr, "Using %s\n", term);
1612 #ifdef HAVE_WINDOW_SYSTEM
1613 inhibit_window_system = true;
1614 #endif
1615 }
1616 else
1617 break;
1618 }
1619
1620
1621
1622 if (argmatch (argv, argc, "-nw", "--no-window-system", 6, NULL, &skip_args)
1623 || argmatch (argv, argc, "-nw", "--no-windows", 6, NULL, &skip_args))
1624 inhibit_window_system = 1;
1625
1626
1627 noninteractive = 0;
1628 if (argmatch (argv, argc, "-batch", "--batch", 5, NULL, &skip_args)
1629 || only_version)
1630 {
1631 noninteractive = 1;
1632 Vundo_outer_limit = Qnil;
1633 }
1634 if (argmatch (argv, argc, "-script", "--script", 3, &junk, &skip_args))
1635 {
1636 noninteractive = 1;
1637
1638
1639
1640 argv[skip_args - 1] = (char *) "-scriptload";
1641 skip_args -= 2;
1642 sort_args (argc, argv);
1643 }
1644
1645
1646 if (argmatch (argv, argc, "-help", "--help", 3, NULL, &skip_args)
1647 && !only_version)
1648 {
1649 int i;
1650 printf ("Usage: %s [OPTION-OR-FILENAME]...\n", argv[0]);
1651 for (i = 0; i < ARRAYELTS (usage_message); i++)
1652 fputs (usage_message[i], stdout);
1653 exit (0);
1654 }
1655
1656 daemon_type = 0;
1657
1658 #ifndef WINDOWSNT
1659
1660 daemon_pipe[1] = 0;
1661 #else
1662 w32_daemon_event = NULL;
1663 #endif
1664
1665
1666 int sockfd = -1;
1667
1668 if (!only_version)
1669 {
1670 if (argmatch (argv, argc, "-fg-daemon", "--fg-daemon", 10, NULL,
1671 &skip_args)
1672 || argmatch (argv, argc, "-fg-daemon", "--fg-daemon", 10, &dname_arg,
1673 &skip_args))
1674 {
1675 daemon_type = 1;
1676 }
1677 else if (argmatch (argv, argc, "-daemon", "--daemon", 5, NULL, &skip_args)
1678 || argmatch (argv, argc, "-daemon", "--daemon", 5, &dname_arg,
1679 &skip_args)
1680 || argmatch (argv, argc, "-bg-daemon", "--bg-daemon", 10, NULL,
1681 &skip_args)
1682 || argmatch (argv, argc, "-bg-daemon", "--bg-daemon", 10,
1683 &dname_arg, &skip_args))
1684 {
1685 daemon_type = 2;
1686 }
1687 }
1688
1689 if (daemon_type > 0)
1690 {
1691 #ifndef DOS_NT
1692 if (daemon_type == 2)
1693 {
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715 if (emacs_pipe (daemon_pipe) != 0)
1716 {
1717 fputs ("Cannot pipe!\n", stderr);
1718 exit (1);
1719 }
1720 }
1721
1722 #ifdef HAVE_LIBSYSTEMD
1723
1724 int systemd_socket = sd_listen_fds (1);
1725
1726 if (systemd_socket > 1)
1727 fputs (("\n"
1728 "Warning: systemd passed more than one socket to Emacs.\n"
1729 "Try 'Accept=false' in the Emacs socket unit file.\n"),
1730 stderr);
1731 else if (systemd_socket == 1
1732 && (0 < sd_is_socket (SD_LISTEN_FDS_START,
1733 AF_UNSPEC, SOCK_STREAM, 1)))
1734 sockfd = SD_LISTEN_FDS_START;
1735 #endif
1736
1737
1738
1739
1740
1741
1742
1743
1744 #ifdef HAVE_PGTK
1745 fputs ("Due to a limitation in GTK 3, Emacs built with PGTK will simply exit when a\n"
1746 "display connection is closed. The problem is especially difficult to fix,\n"
1747 "such that Emacs on Wayland with multiple displays is unlikely ever to be able\n"
1748 "to survive disconnects.\n",
1749 stderr);
1750 #elif defined USE_GTK
1751 fputs ("\nWarning: due to a long standing Gtk+ bug\nhttps://gitlab.gnome.org/GNOME/gtk/issues/221\n\
1752 Emacs might crash when run in daemon mode and the X11 connection is unexpectedly lost.\n\
1753 Using an Emacs configured with --with-x-toolkit=lucid does not have this problem.\n",
1754 stderr);
1755 #endif
1756
1757 if (daemon_type == 2)
1758 {
1759 pid_t f;
1760 #ifndef DAEMON_MUST_EXEC
1761
1762 f = fork ();
1763 #else
1764 if (!dname_arg || !strchr (dname_arg, '\n'))
1765 f = fork ();
1766 else
1767 f = 0;
1768 #endif
1769 if (f > 0)
1770 {
1771 int retval;
1772 char buf[1];
1773
1774
1775 emacs_close (daemon_pipe[1]);
1776
1777
1778 do
1779 {
1780 retval = read (daemon_pipe[0], &buf, 1);
1781 }
1782 while (retval == -1 && errno == EINTR);
1783
1784 if (retval < 0)
1785 {
1786 fputs ("Error reading status from child\n", stderr);
1787 exit (1);
1788 }
1789 else if (retval == 0)
1790 {
1791 fputs ("Error: server did not start correctly\n", stderr);
1792 exit (1);
1793 }
1794
1795 emacs_close (daemon_pipe[0]);
1796 exit (0);
1797 }
1798 if (f < 0)
1799 {
1800 emacs_perror ("fork");
1801 exit (EXIT_CANCELED);
1802 }
1803
1804 #ifdef DAEMON_MUST_EXEC
1805 {
1806
1807 if (!dname_arg || !strchr (dname_arg, '\n'))
1808 {
1809 char fdStr[80];
1810 int fdStrlen =
1811 snprintf (fdStr, sizeof fdStr,
1812 "--bg-daemon=\n%d,%d\n%s", daemon_pipe[0],
1813 daemon_pipe[1], dname_arg ? dname_arg : "");
1814
1815 if (! (0 <= fdStrlen && fdStrlen < sizeof fdStr))
1816 {
1817 fputs ("daemon: child name too long\n", stderr);
1818 exit (EXIT_CANNOT_INVOKE);
1819 }
1820
1821 argv[skip_args] = fdStr;
1822
1823 fcntl (daemon_pipe[0], F_SETFD, 0);
1824 fcntl (daemon_pipe[1], F_SETFD, 0);
1825 execvp (argv[0], argv);
1826 emacs_perror (argv[0]);
1827 exit (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
1828 }
1829
1830
1831 if (!dname_arg || !*dname_arg || strnlen (dname_arg, 71) == 71
1832 || !strchr (dname_arg, '\n'))
1833 {
1834 fputs ("emacs daemon: daemon name absent or too long\n",
1835 stderr);
1836 exit (EXIT_CANNOT_INVOKE);
1837 }
1838 dname_arg2[0] = '\0';
1839 sscanf (dname_arg, "\n%d,%d\n%s", &(daemon_pipe[0]), &(daemon_pipe[1]),
1840 dname_arg2);
1841 dname_arg = *dname_arg2 ? dname_arg2 : NULL;
1842 fcntl (daemon_pipe[1], F_SETFD, FD_CLOEXEC);
1843 }
1844 #endif
1845
1846
1847 emacs_close (daemon_pipe[0]);
1848
1849 setsid ();
1850 }
1851 #elif defined(WINDOWSNT)
1852
1853 w32_daemon_event = CreateEvent (NULL, TRUE, FALSE, W32_DAEMON_EVENT);
1854 if (w32_daemon_event == NULL)
1855 {
1856 fprintf (stderr, "Couldn't create MS-Windows event for daemon: %s\n",
1857 w32_strerror (0));
1858 exit (1);
1859 }
1860 #else
1861 fputs ("This platform does not support daemon mode.\n", stderr);
1862 exit (1);
1863 #endif
1864 if (dname_arg)
1865 daemon_name = xstrdup (dname_arg);
1866 }
1867
1868 #if defined HAVE_PTHREAD && !defined SYSTEM_MALLOC \
1869 && !defined DOUG_LEA_MALLOC && !defined HYBRID_MALLOC
1870
1871
1872
1873
1874 if (!noninteractive || !will_dump_p ())
1875 malloc_enable_thread ();
1876 #endif
1877
1878 init_signals ();
1879
1880 noninteractive1 = noninteractive;
1881
1882
1883
1884 if (!initialized)
1885 {
1886 init_alloc_once ();
1887 init_pdumper_once ();
1888 init_obarray_once ();
1889 init_eval_once ();
1890 init_charset_once ();
1891 init_coding_once ();
1892 init_syntax_once ();
1893 init_category_once ();
1894 init_casetab_once ();
1895 init_buffer_once ();
1896 init_minibuf_once ();
1897
1898
1899
1900
1901
1902
1903 syms_of_xfaces ();
1904
1905
1906 syms_of_keymap ();
1907
1908
1909
1910
1911 syms_of_keyboard ();
1912
1913
1914 syms_of_data ();
1915 syms_of_fns ();
1916 syms_of_fileio ();
1917
1918 syms_of_alloc ();
1919
1920 init_print_once ();
1921
1922 syms_of_charset ();
1923
1924
1925 syms_of_coding ();
1926 init_frame_once ();
1927
1928
1929
1930
1931
1932 init_bignum ();
1933 init_window_once ();
1934 #ifdef HAVE_WINDOW_SYSTEM
1935 init_fringe_once ();
1936 #endif
1937 }
1938
1939 init_alloc ();
1940 init_bignum ();
1941 init_threads ();
1942 init_eval ();
1943 running_asynch_code = 0;
1944 init_random ();
1945 init_xfaces ();
1946
1947 #if defined HAVE_JSON && !defined WINDOWSNT
1948 init_json ();
1949 #endif
1950
1951 if (!initialized)
1952 syms_of_comp ();
1953
1954
1955
1956
1957 Vgc_cons_percentage = make_float (noninteractive && initialized ? 1.0 : 0.1);
1958
1959 no_loadup
1960 = argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args);
1961
1962 no_site_lisp
1963 = argmatch (argv, argc, "-nsl", "--no-site-lisp", 11, NULL, &skip_args);
1964
1965 build_details = ! argmatch (argv, argc, "-no-build-details",
1966 "--no-build-details", 7, NULL, &skip_args);
1967
1968 #ifdef HAVE_MODULES
1969 bool module_assertions
1970 = argmatch (argv, argc, "-module-assertions", "--module-assertions", 15,
1971 NULL, &skip_args);
1972 if (will_dump_p () && module_assertions && !only_version)
1973 {
1974 fputs ("Module assertions are not supported during dumping\n", stderr);
1975 exit (1);
1976 }
1977 init_module_assertions (module_assertions);
1978 #endif
1979
1980 #ifdef HAVE_NS
1981 if (!noninteractive)
1982 {
1983 #ifdef NS_IMPL_COCOA
1984
1985 bool go_home = (!ch_to_dir && !inhibit_window_system
1986 && !isatty (STDIN_FILENO));
1987 if (skip_args < argc)
1988 {
1989 if (!strncmp (argv[skip_args], "-psn", 4))
1990 {
1991 skip_args += 1;
1992 go_home |= !ch_to_dir;
1993 }
1994 else if (skip_args+1 < argc && !strncmp (argv[skip_args+1], "-psn", 4))
1995 {
1996 skip_args += 2;
1997 go_home |= !ch_to_dir;
1998 }
1999 }
2000 if (go_home)
2001 {
2002 char const *home = get_homedir ();
2003 if (*home && chdir (home) == 0)
2004 emacs_wd = emacs_get_current_dir_name ();
2005 }
2006 #endif
2007 }
2008 #endif
2009
2010
2011
2012
2013
2014 {
2015 int count_before = skip_args;
2016
2017 #ifdef HAVE_X_WINDOWS
2018 char *displayname = 0;
2019
2020
2021 while (!only_version)
2022 {
2023 int count_before_this = skip_args;
2024
2025 if (argmatch (argv, argc, "-d", "--display", 3, &displayname, &skip_args))
2026 display_arg = 1;
2027 else if (argmatch (argv, argc, "-display", 0, 3, &displayname, &skip_args))
2028 display_arg = 1;
2029 else
2030 break;
2031
2032 count_before = count_before_this;
2033 }
2034
2035
2036
2037
2038 if (displayname && count_before < skip_args)
2039 {
2040 if (skip_args == count_before + 1)
2041 {
2042 memmove (argv + count_before + 3, argv + count_before + 2,
2043 (argc - (count_before + 2)) * sizeof *argv);
2044 argv[count_before + 2] = displayname;
2045 argc++;
2046 }
2047 argv[count_before + 1] = (char *) "-d";
2048 }
2049 #endif
2050
2051 if (! no_site_lisp)
2052 {
2053
2054 if (argmatch (argv, argc, "-Q", "--quick", 3, NULL, &skip_args)
2055 || argmatch (argv, argc, "-quick", 0, 2, NULL, &skip_args))
2056 no_site_lisp = 1;
2057
2058 }
2059
2060 if (argmatch (argv, argc, "-x", 0, 1, &junk, &skip_args))
2061 {
2062 noninteractive = 1;
2063 no_site_lisp = 1;
2064
2065 argv[skip_args - 1] = (char *) "-scripteval";
2066 skip_args -= 1;
2067 sort_args (argc, argv);
2068 }
2069
2070
2071 skip_args = count_before;
2072 }
2073
2074
2075
2076
2077
2078 #ifdef MSDOS
2079
2080 init_dosfns ();
2081
2082 if (initialized)
2083 init_environment (argc, argv, skip_args);
2084 else
2085 tzset ();
2086 #endif
2087
2088 #ifdef HAVE_KQUEUE
2089 globals_of_kqueue ();
2090 #endif
2091
2092 #ifdef HAVE_GFILENOTIFY
2093 globals_of_gfilenotify ();
2094 #endif
2095
2096
2097
2098
2099 if (!initialized)
2100 syms_of_callproc ();
2101
2102
2103
2104 if (!will_dump_p ())
2105 set_initial_environment ();
2106
2107
2108 init_atimer ();
2109
2110 #ifdef WINDOWSNT
2111 globals_of_w32 ();
2112 #ifdef HAVE_W32NOTIFY
2113 globals_of_w32notify ();
2114 #endif
2115
2116
2117
2118
2119
2120 init_environment (argv);
2121 init_ntproc (will_dump_p ());
2122 #endif
2123
2124
2125
2126
2127
2128 #ifdef AIX
2129 xputenv ("LANG=C");
2130 #endif
2131
2132
2133 init_buffer ();
2134
2135
2136 init_callproc_1 ();
2137
2138
2139 init_cmdargs (argc, argv, skip_args, original_pwd);
2140
2141 if (initialized)
2142 {
2143
2144 Lisp_Object old_log_max;
2145 old_log_max = Vmessage_log_max;
2146 XSETFASTINT (Vmessage_log_max, 0);
2147 message_dolog ("", 0, 1, 0);
2148 Vmessage_log_max = old_log_max;
2149 }
2150
2151 init_callproc ();
2152 init_fileio ();
2153 init_lread ();
2154
2155
2156
2157
2158
2159 if (only_version)
2160 {
2161 const char *version, *copyright;
2162
2163 if (initialized)
2164 {
2165 Lisp_Object tem = Fsymbol_value (intern_c_string ("emacs-version"));
2166 Lisp_Object tem2 = Fsymbol_value (intern_c_string ("emacs-copyright"));
2167 if (!STRINGP (tem))
2168 {
2169 fputs ("Invalid value of 'emacs-version'\n", stderr);
2170 exit (1);
2171 }
2172 if (!STRINGP (tem2))
2173 {
2174 fputs ("Invalid value of 'emacs-copyright'\n", stderr);
2175 exit (1);
2176 }
2177 else
2178 {
2179 version = SSDATA (tem);
2180 copyright = SSDATA (tem2);
2181 }
2182 }
2183 else
2184 {
2185 version = emacs_version;
2186 copyright = emacs_copyright;
2187 }
2188 printf ("%s %s\n", PACKAGE_NAME, version);
2189
2190 if (initialized)
2191 {
2192 Lisp_Object rversion, rbranch, rtime;
2193
2194 rversion
2195 = Fsymbol_value (intern_c_string ("emacs-repository-version"));
2196 rbranch
2197 = Fsymbol_value (intern_c_string ("emacs-repository-branch"));
2198 rtime
2199 = Fsymbol_value (intern_c_string ("emacs-build-time"));
2200
2201 if (!NILP (rversion) && !NILP (rbranch) && !NILP (rtime))
2202 printf ("Development version %s on %s branch; build date %s.\n",
2203 SSDATA (Fsubstring (rversion, make_fixnum (0),
2204 make_fixnum (12))),
2205 SSDATA (rbranch),
2206 SSDATA (Fformat_time_string (build_string ("%Y-%m-%d"),
2207 rtime, Qnil)));
2208 }
2209
2210 printf (("%s\n"
2211 "%s comes with ABSOLUTELY NO WARRANTY.\n"
2212 "You may redistribute copies of %s\n"
2213 "under the terms of the GNU General Public License.\n"
2214 "For more information about these matters, "
2215 "see the file named COPYING.\n"),
2216 copyright, PACKAGE_NAME, PACKAGE_NAME);
2217 exit (0);
2218 }
2219
2220 #ifdef WINDOWSNT
2221
2222 check_windows_init_file ();
2223 #endif
2224
2225
2226
2227
2228 if (!initialized)
2229 {
2230
2231
2232 syms_of_chartab ();
2233 syms_of_lread ();
2234 syms_of_print ();
2235 syms_of_eval ();
2236 syms_of_floatfns ();
2237
2238 syms_of_buffer ();
2239 syms_of_bytecode ();
2240 syms_of_callint ();
2241 syms_of_casefiddle ();
2242 syms_of_casetab ();
2243 syms_of_category ();
2244 syms_of_ccl ();
2245 syms_of_character ();
2246 syms_of_cmds ();
2247 syms_of_dired ();
2248 syms_of_display ();
2249 syms_of_doc ();
2250 syms_of_editfns ();
2251 syms_of_emacs ();
2252 syms_of_filelock ();
2253 syms_of_indent ();
2254 syms_of_insdel ();
2255
2256 syms_of_macros ();
2257 syms_of_marker ();
2258 syms_of_minibuf ();
2259 syms_of_process ();
2260 syms_of_search ();
2261 syms_of_sysdep ();
2262 syms_of_timefns ();
2263 syms_of_frame ();
2264 syms_of_syntax ();
2265 syms_of_terminal ();
2266 syms_of_term ();
2267 syms_of_undo ();
2268
2269 #ifdef HAVE_MODULES
2270 syms_of_module ();
2271 #endif
2272
2273
2274 syms_of_treesit ();
2275 #ifdef HAVE_SOUND
2276 syms_of_sound ();
2277 #endif
2278 syms_of_textprop ();
2279 syms_of_composite ();
2280 #ifdef WINDOWSNT
2281 syms_of_ntproc ();
2282 #endif
2283 #if defined CYGWIN
2284 syms_of_cygw32 ();
2285 #endif
2286 syms_of_window ();
2287 syms_of_xdisp ();
2288 syms_of_sqlite ();
2289 syms_of_font ();
2290 #ifdef HAVE_WINDOW_SYSTEM
2291 syms_of_fringe ();
2292 syms_of_image ();
2293 #endif
2294 #ifdef HAVE_X_WINDOWS
2295 syms_of_xterm ();
2296 syms_of_xfns ();
2297 syms_of_xmenu ();
2298 syms_of_fontset ();
2299 syms_of_xsettings ();
2300 #ifdef HAVE_X_SM
2301 syms_of_xsmfns ();
2302 #endif
2303 #ifdef HAVE_X11
2304 syms_of_xselect ();
2305 #endif
2306 #endif
2307
2308 syms_of_xml ();
2309
2310 #ifdef HAVE_LCMS2
2311 syms_of_lcms2 ();
2312 #endif
2313
2314 #ifdef HAVE_ZLIB
2315 syms_of_decompress ();
2316 #endif
2317
2318 syms_of_menu ();
2319
2320 #ifdef HAVE_NTGUI
2321 syms_of_w32term ();
2322 syms_of_w32fns ();
2323 syms_of_w32menu ();
2324 syms_of_fontset ();
2325 #endif
2326
2327 #if defined HAVE_NTGUI || defined CYGWIN
2328 syms_of_w32cygwinx ();
2329 #endif
2330
2331 #if defined WINDOWSNT || defined HAVE_NTGUI
2332 syms_of_w32select ();
2333 #endif
2334
2335 #ifdef MSDOS
2336 syms_of_xmenu ();
2337 syms_of_dosfns ();
2338 syms_of_msdos ();
2339 syms_of_win16select ();
2340 #endif
2341
2342 #ifdef HAVE_NS
2343 syms_of_nsterm ();
2344 syms_of_nsfns ();
2345 syms_of_nsmenu ();
2346 syms_of_nsselect ();
2347 syms_of_fontset ();
2348 #endif
2349
2350 #ifdef HAVE_PGTK
2351 syms_of_pgtkterm ();
2352 syms_of_pgtkfns ();
2353 syms_of_pgtkselect ();
2354 syms_of_pgtkmenu ();
2355 syms_of_pgtkim ();
2356 syms_of_fontset ();
2357 syms_of_xsettings ();
2358 #endif
2359 #ifdef HAVE_HAIKU
2360 syms_of_haikuterm ();
2361 syms_of_haikufns ();
2362 syms_of_haikumenu ();
2363 syms_of_haikufont ();
2364 syms_of_haikuselect ();
2365 #ifdef HAVE_NATIVE_IMAGE_API
2366 syms_of_haikuimage ();
2367 #endif
2368 syms_of_fontset ();
2369 #endif
2370
2371 syms_of_gnutls ();
2372
2373 #ifdef HAVE_INOTIFY
2374 syms_of_inotify ();
2375 #endif
2376
2377 #ifdef HAVE_KQUEUE
2378 syms_of_kqueue ();
2379 #endif
2380
2381 #ifdef HAVE_GFILENOTIFY
2382 syms_of_gfilenotify ();
2383 #endif
2384
2385 #ifdef HAVE_DBUS
2386 syms_of_dbusbind ();
2387 #endif
2388
2389 #ifdef WINDOWSNT
2390 syms_of_ntterm ();
2391 #ifdef HAVE_W32NOTIFY
2392 syms_of_w32notify ();
2393 #endif
2394 #endif
2395
2396 syms_of_xwidget ();
2397 syms_of_threads ();
2398 syms_of_profiler ();
2399 syms_of_pdumper ();
2400
2401 #ifdef HAVE_JSON
2402 syms_of_json ();
2403 #endif
2404
2405 keys_of_keyboard ();
2406
2407 #ifdef HAVE_NATIVE_COMP
2408
2409 hash_native_abi ();
2410 #endif
2411 }
2412 else
2413 {
2414
2415
2416 #ifdef HAVE_NTGUI
2417 globals_of_w32font ();
2418 globals_of_w32fns ();
2419 globals_of_w32menu ();
2420 #endif
2421
2422 #if defined WINDOWSNT || defined HAVE_NTGUI
2423 globals_of_w32select ();
2424 #endif
2425 }
2426
2427 #ifdef HAVE_HAIKU
2428 init_haiku_select ();
2429 #endif
2430
2431 init_charset ();
2432
2433
2434 init_timefns ();
2435
2436 init_editfns ();
2437
2438
2439 #ifdef HAVE_DBUS
2440 init_dbusbind ();
2441 #endif
2442 #if defined(USE_GTK) && !defined(HAVE_PGTK)
2443 init_xterm ();
2444 #endif
2445
2446
2447
2448
2449 init_process_emacs (sockfd);
2450
2451 init_keyboard ();
2452 init_display ();
2453 #if HAVE_W32NOTIFY
2454 if (noninteractive)
2455 init_crit ();
2456 #endif
2457 init_xdisp ();
2458 #ifdef HAVE_WINDOW_SYSTEM
2459 init_fringe ();
2460 #endif
2461 init_macros ();
2462 init_window ();
2463 init_font ();
2464
2465 if (!initialized)
2466 {
2467 char *file;
2468
2469 if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args))
2470 {
2471 #ifdef WINDOWSNT
2472 char file_utf8[MAX_UTF8_PATH];
2473
2474 if (filename_from_ansi (file, file_utf8) == 0)
2475 file = file_utf8;
2476 #endif
2477 Vtop_level = list2 (Qload, build_unibyte_string (file));
2478 }
2479
2480 if (! no_loadup)
2481 Vtop_level = list2 (Qload, build_string ("loadup.el"));
2482
2483 #ifdef HAVE_NATIVE_COMP
2484
2485
2486
2487 if (!NILP (Vtop_level) && !temacs)
2488 Vnative_comp_eln_load_path =
2489 Fcons (Fexpand_file_name (XCAR (Vnative_comp_eln_load_path),
2490 Vinvocation_directory),
2491 Qnil);
2492 #endif
2493 }
2494
2495
2496
2497
2498
2499 #ifdef PROFILING
2500 if (initialized)
2501 {
2502 atexit (_mcleanup);
2503 monstartup ((uintptr_t) __executable_start, (uintptr_t) &etext);
2504 }
2505 else
2506 moncontrol (0);
2507 #endif
2508
2509 initialized = true;
2510
2511 if (dump_mode)
2512 Vdump_mode = build_string (dump_mode);
2513
2514 #ifdef HAVE_PDUMPER
2515
2516 safe_run_hooks (Qafter_pdump_load_hook);
2517 #endif
2518
2519
2520 set_initial_minibuffer_mode ();
2521 Frecursive_edit ();
2522 eassume (false);
2523 }
2524
2525
2526
2527
2528
2529
2530 struct standard_args
2531 {
2532 const char *name;
2533 const char *longname;
2534 int priority;
2535 int nargs;
2536 };
2537
2538 static const struct standard_args standard_args[] =
2539 {
2540 { "-version", "--version", 150, 0 },
2541 #ifdef HAVE_PDUMPER
2542 { "-fingerprint", "--fingerprint", 140, 0 },
2543 #endif
2544 { "-chdir", "--chdir", 130, 1 },
2545 { "-t", "--terminal", 120, 1 },
2546 { "-nw", "--no-window-system", 110, 0 },
2547 { "-nw", "--no-windows", 110, 0 },
2548 { "-batch", "--batch", 100, 0 },
2549 { "-script", "--script", 100, 1 },
2550 { "-daemon", "--daemon", 99, 0 },
2551 { "-bg-daemon", "--bg-daemon", 99, 0 },
2552 { "-fg-daemon", "--fg-daemon", 99, 0 },
2553 { "-help", "--help", 90, 0 },
2554 { "-nl", "--no-loadup", 70, 0 },
2555 { "-nsl", "--no-site-lisp", 65, 0 },
2556 { "-no-build-details", "--no-build-details", 63, 0 },
2557 #ifdef HAVE_MODULES
2558 { "-module-assertions", "--module-assertions", 62, 0 },
2559 #endif
2560
2561 { "-d", "--display", 60, 1 },
2562 { "-display", 0, 60, 1 },
2563
2564
2565 { "-Q", "--quick", 55, 0 },
2566 { "-quick", 0, 55, 0 },
2567 { "-x", 0, 55, 0 },
2568 { "-q", "--no-init-file", 50, 0 },
2569 { "-no-init-file", 0, 50, 0 },
2570 { "-init-directory", "--init-directory", 30, 1 },
2571 { "-no-x-resources", "--no-x-resources", 40, 0 },
2572 { "-no-site-file", "--no-site-file", 40, 0 },
2573 { "-no-comp-spawn", "--no-comp-spawn", 60, 0 },
2574 { "-u", "--user", 30, 1 },
2575 { "-user", 0, 30, 1 },
2576 { "-debug-init", "--debug-init", 20, 0 },
2577 { "-iconic", "--iconic", 15, 0 },
2578 { "-D", "--basic-display", 12, 0},
2579 { "-basic-display", 0, 12, 0},
2580 { "-nbc", "--no-blinking-cursor", 12, 0 },
2581
2582 { "-nbi", "--no-bitmap-icon", 10, 0 },
2583 { "-bg", "--background-color", 10, 1 },
2584 { "-background", 0, 10, 1 },
2585 { "-fg", "--foreground-color", 10, 1 },
2586 { "-foreground", 0, 10, 1 },
2587 { "-bd", "--border-color", 10, 1 },
2588 { "-bw", "--border-width", 10, 1 },
2589 { "-ib", "--internal-border", 10, 1 },
2590 { "-ms", "--mouse-color", 10, 1 },
2591 { "-cr", "--cursor-color", 10, 1 },
2592 { "-fn", "--font", 10, 1 },
2593 { "-font", 0, 10, 1 },
2594 { "-fs", "--fullscreen", 10, 0 },
2595 { "-fw", "--fullwidth", 10, 0 },
2596 { "-fh", "--fullheight", 10, 0 },
2597 { "-mm", "--maximized", 10, 0 },
2598 { "-g", "--geometry", 10, 1 },
2599 { "-geometry", 0, 10, 1 },
2600 { "-T", "--title", 10, 1 },
2601 { "-title", 0, 10, 1 },
2602 { "-name", "--name", 10, 1 },
2603 { "-xrm", "--xrm", 10, 1 },
2604 { "-parent-id", "--parent-id", 10, 1 },
2605 { "-r", "--reverse-video", 5, 0 },
2606 { "-rv", 0, 5, 0 },
2607 { "-reverse", 0, 5, 0 },
2608 { "-hb", "--horizontal-scroll-bars", 5, 0 },
2609 { "-vb", "--vertical-scroll-bars", 5, 0 },
2610 { "-color", "--color", 5, 0},
2611 { "-no-splash", "--no-splash", 3, 0 },
2612 { "-no-desktop", "--no-desktop", 3, 0 },
2613
2614
2615 { "-temacs", "--temacs", 1, 1 },
2616 #ifdef HAVE_PDUMPER
2617 { "-dump-file", "--dump-file", 1, 1 },
2618 #endif
2619 #if SECCOMP_USABLE
2620 { "-seccomp", "--seccomp", 1, 1 },
2621 #endif
2622 #ifdef HAVE_NS
2623 { "-NSAutoLaunch", 0, 5, 1 },
2624 { "-NXAutoLaunch", 0, 5, 1 },
2625 { "-_NSMachLaunch", 0, 85, 1 },
2626 { "-MachLaunch", 0, 85, 1 },
2627 { "-macosx", 0, 85, 0 },
2628 { "-NSHost", 0, 85, 1 },
2629 #endif
2630
2631
2632 { "-L", "--directory", 0, 1 },
2633 { "-directory", 0, 0, 1 },
2634 { "-l", "--load", 0, 1 },
2635 { "-load", 0, 0, 1 },
2636
2637
2638
2639
2640 { "-scriptload", NULL, 0, 1 },
2641 { "-f", "--funcall", 0, 1 },
2642 { "-funcall", 0, 0, 1 },
2643 { "-eval", "--eval", 0, 1 },
2644 { "-execute", "--execute", 0, 1 },
2645 { "-find-file", "--find-file", 0, 1 },
2646 { "-visit", "--visit", 0, 1 },
2647 { "-file", "--file", 0, 1 },
2648 { "-insert", "--insert", 0, 1 },
2649 #ifdef HAVE_NS
2650 { "-NXOpen", 0, 0, 1 },
2651 { "-NXOpenTemp", 0, 0, 1 },
2652 { "-NSOpen", 0, 0, 1 },
2653 { "-NSOpenTemp", 0, 0, 1 },
2654 { "-GSFilePath", 0, 0, 1 },
2655 #endif
2656
2657 { "-kill", "--kill", -10, 0 },
2658 };
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668 static void
2669 sort_args (int argc, char **argv)
2670 {
2671 char **new = xmalloc (argc * sizeof *new);
2672
2673
2674
2675
2676
2677 int *options = xnmalloc (argc, sizeof *options);
2678 int *priority = xnmalloc (argc, sizeof *priority);
2679 int to = 1;
2680 int incoming_used = 1;
2681 int from;
2682 int i;
2683
2684
2685
2686 for (from = 1; from < argc; from++)
2687 {
2688 options[from] = -1;
2689 priority[from] = 0;
2690 if (argv[from][0] == '-')
2691 {
2692 int match;
2693
2694
2695
2696 if (argv[from][1] == '-' && argv[from][2] == 0)
2697 {
2698
2699 for (; from < argc; from++)
2700 {
2701 priority[from] = -100;
2702 options[from] = -1;
2703 }
2704 break;
2705 }
2706
2707
2708 for (i = 0; i < ARRAYELTS (standard_args); i++)
2709 if (!strcmp (argv[from], standard_args[i].name))
2710 {
2711 options[from] = standard_args[i].nargs;
2712 priority[from] = standard_args[i].priority;
2713 if (from + standard_args[i].nargs >= argc)
2714 fatal ("Option '%s' requires an argument\n", argv[from]);
2715 from += standard_args[i].nargs;
2716 goto done;
2717 }
2718
2719
2720
2721
2722 if (argv[from][1] == '-')
2723 {
2724 char const *equals = strchr (argv[from], '=');
2725 ptrdiff_t thislen =
2726 equals ? equals - argv[from] : strlen (argv[from]);
2727
2728 match = -1;
2729
2730 for (i = 0; i < ARRAYELTS (standard_args); i++)
2731 if (standard_args[i].longname
2732 && !strncmp (argv[from], standard_args[i].longname,
2733 thislen))
2734 {
2735 if (match == -1)
2736 match = i;
2737 else
2738 match = -2;
2739 }
2740
2741
2742 if (match >= 0)
2743 {
2744 options[from] = standard_args[match].nargs;
2745 priority[from] = standard_args[match].priority;
2746
2747
2748 if (equals != 0)
2749 options[from] = 0;
2750 if (from + options[from] >= argc)
2751 fatal ("Option '%s' requires an argument\n", argv[from]);
2752 from += options[from];
2753 }
2754 else if (match == -2)
2755 {
2756
2757
2758 fprintf (stderr, "Option '%s' matched multiple standard arguments\n", argv[from]);
2759 }
2760
2761 }
2762 done: ;
2763 }
2764 }
2765
2766
2767 new[0] = argv[0];
2768 while (incoming_used < argc)
2769 {
2770 int best = -1;
2771 int best_priority = -9999;
2772
2773
2774
2775 for (from = 1; from < argc; from++)
2776 {
2777 if (argv[from] != 0 && priority[from] > best_priority)
2778 {
2779 best_priority = priority[from];
2780 best = from;
2781 }
2782
2783 if (options[from] > 0)
2784 from += options[from];
2785 }
2786
2787 if (best < 0)
2788 emacs_abort ();
2789
2790
2791
2792 if (! (options[best] == 0
2793 && ! strcmp (new[to - 1], argv[best])))
2794 {
2795 new[to++] = argv[best];
2796 for (i = 0; i < options[best]; i++)
2797 new[to++] = argv[best + i + 1];
2798 }
2799
2800 incoming_used += 1 + (options[best] > 0 ? options[best] : 0);
2801
2802
2803 argv[best] = 0;
2804 for (i = 0; i < options[best]; i++)
2805 argv[best + i + 1] = 0;
2806 }
2807
2808
2809 while (to < argc)
2810 new[to++] = 0;
2811
2812 memcpy (argv, new, sizeof (char *) * argc);
2813
2814 xfree (options);
2815 xfree (new);
2816 xfree (priority);
2817 }
2818
2819 DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 2, "P",
2820 doc:
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836 attributes: noreturn)
2837 (Lisp_Object arg, Lisp_Object restart)
2838 {
2839 int exit_code;
2840
2841 #ifndef WINDOWSNT
2842
2843
2844 if (!NILP (restart))
2845 {
2846
2847
2848 if (initial_argc < 1)
2849 error ("No command line arguments known; unable to re-execute Emacs");
2850
2851
2852 if (!initial_emacs_executable)
2853 error ("Unknown Emacs executable");
2854
2855 if (!file_access_p (initial_emacs_executable, F_OK))
2856 error ("Emacs executable \"%s\" can't be found", initial_argv[0]);
2857 }
2858 #endif
2859
2860 #ifdef HAVE_LIBSYSTEMD
2861
2862
2863 if (daemon_type == -1)
2864 sd_notify(0, "STOPPING=1");
2865 #endif
2866
2867
2868
2869 waiting_for_input = 0;
2870 if (!NILP (find_symbol_value (Qkill_emacs_hook)))
2871 {
2872 if (noninteractive)
2873 safe_run_hooks (Qkill_emacs_hook);
2874 else
2875 call1 (Qrun_hook_query_error_with_timeout, Qkill_emacs_hook);
2876 }
2877
2878 #ifdef HAVE_X_WINDOWS
2879
2880 x_clipboard_manager_save_all ();
2881 #endif
2882
2883 shut_down_emacs (0, (STRINGP (arg) && !feof (stdin)) ? arg : Qnil);
2884
2885 #ifdef HAVE_NS
2886 ns_release_autorelease_pool (ns_pool);
2887 #endif
2888
2889
2890
2891
2892 if (STRINGP (Vauto_save_list_file_name))
2893 {
2894 Lisp_Object listfile;
2895 listfile = Fexpand_file_name (Vauto_save_list_file_name, Qnil);
2896 unlink (SSDATA (listfile));
2897 }
2898
2899 #ifdef HAVE_NATIVE_COMP
2900 eln_load_path_final_clean_up ();
2901 #endif
2902
2903 if (!NILP (restart))
2904 {
2905 turn_on_atimers (false);
2906 #ifdef WINDOWSNT
2907 if (w32_reexec_emacs (initial_cmdline, initial_wd) < 0)
2908 #else
2909 initial_argv[0] = initial_emacs_executable;
2910 if (execvp (*initial_argv, initial_argv) < 1)
2911 #endif
2912 emacs_perror ("Unable to re-execute Emacs");
2913 }
2914
2915 if (FIXNUMP (arg))
2916 exit_code = (XFIXNUM (arg) < 0
2917 ? XFIXNUM (arg) | INT_MIN
2918 : XFIXNUM (arg) & INT_MAX);
2919 else
2920 exit_code = EXIT_SUCCESS;
2921 exit (exit_code);
2922 }
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936 void
2937 shut_down_emacs (int sig, Lisp_Object stuff)
2938 {
2939
2940 Vrun_hooks = Qnil;
2941
2942
2943 Vinhibit_redisplay = Qt;
2944
2945
2946 #ifndef DOS_NT
2947 pid_t tpgrp = tcgetpgrp (STDIN_FILENO);
2948 if (tpgrp != -1 && tpgrp == getpgrp ())
2949 {
2950 reset_all_sys_modes ();
2951 if (sig && sig != SIGTERM)
2952 {
2953 static char const fmt[] = "Fatal error %d: %n%s\n";
2954 #ifdef HAVE_HAIKU
2955 if (haiku_debug_on_fatal_error)
2956 debugger ("Fatal error in Emacs");
2957 #endif
2958 char buf[max ((sizeof fmt - sizeof "%d%n%s\n"
2959 + INT_STRLEN_BOUND (int) + 1),
2960 min (PIPE_BUF, MAX_ALLOCA))];
2961 char const *sig_desc = safe_strsignal (sig);
2962 int nlen;
2963 int buflen = snprintf (buf, sizeof buf, fmt, sig, &nlen, sig_desc);
2964 if (0 <= buflen && buflen < sizeof buf)
2965 emacs_write (STDERR_FILENO, buf, buflen);
2966 else
2967 {
2968 emacs_write (STDERR_FILENO, buf, nlen);
2969 emacs_write (STDERR_FILENO, sig_desc, strlen (sig_desc));
2970 emacs_write (STDERR_FILENO, fmt + sizeof fmt - 2, 1);
2971 }
2972 }
2973 }
2974 #else
2975 fflush (stdout);
2976 reset_all_sys_modes ();
2977 #endif
2978
2979 stuff_buffered_input (stuff);
2980
2981 inhibit_sentinels = 1;
2982 kill_buffer_processes (Qnil);
2983 Fdo_auto_save (Qt, Qnil);
2984
2985 unlock_all_files ();
2986
2987
2988
2989 unrequest_sigio ();
2990
2991
2992
2993 if (sig == 0 || sig == SIGTERM)
2994 {
2995 check_glyph_memory ();
2996 check_message_stack ();
2997 }
2998
2999 #ifdef HAVE_NATIVE_COMP
3000 eln_load_path_final_clean_up ();
3001 #endif
3002
3003 #ifdef MSDOS
3004 dos_cleanup ();
3005 #endif
3006
3007 #ifdef HAVE_NS
3008 ns_term_shutdown (sig);
3009 #endif
3010
3011 #ifdef HAVE_LIBXML2
3012 xml_cleanup_parser ();
3013 #endif
3014
3015 #ifdef WINDOWSNT
3016 term_ntproc (0);
3017 #endif
3018 }
3019
3020
3021
3022 #ifdef HAVE_UNEXEC
3023
3024 #include "unexec.h"
3025
3026 DEFUN ("dump-emacs", Fdump_emacs, Sdump_emacs, 2, 2, 0,
3027 doc:
3028
3029
3030
3031 )
3032 (Lisp_Object filename, Lisp_Object symfile)
3033 {
3034 Lisp_Object tem;
3035 Lisp_Object symbol;
3036 specpdl_ref count = SPECPDL_INDEX ();
3037
3038 check_pure_size ();
3039
3040 if (! noninteractive)
3041 error ("Dumping Emacs works only in batch mode");
3042
3043 if (dumped_with_unexec_p ())
3044 error ("Emacs can be dumped using unexec only once");
3045
3046 if (definitely_will_not_unexec_p ())
3047 error ("This Emacs instance was not started in temacs mode");
3048
3049 # if defined GNU_LINUX && defined HAVE_UNEXEC
3050
3051
3052 # define MAX_HEAP_BSS_DIFF (1024 * 1024)
3053
3054 if (heap_bss_diff > MAX_HEAP_BSS_DIFF)
3055 fprintf (stderr,
3056 ("**************************************************\n"
3057 "Warning: Your system has a gap between BSS and the\n"
3058 "heap (%"PRIuMAX" bytes). This usually means that exec-shield\n"
3059 "or something similar is in effect. The dump may\n"
3060 "fail because of this. See the section about\n"
3061 "exec-shield in etc/PROBLEMS for more information.\n"
3062 "**************************************************\n"),
3063 heap_bss_diff);
3064 # endif
3065
3066
3067
3068
3069 symbol = intern ("command-line-processed");
3070 specbind (symbol, Qnil);
3071
3072 CHECK_STRING (filename);
3073 filename = Fexpand_file_name (filename, Qnil);
3074 filename = ENCODE_FILE (filename);
3075 if (!NILP (symfile))
3076 {
3077 CHECK_STRING (symfile);
3078 if (SCHARS (symfile))
3079 {
3080 symfile = Fexpand_file_name (symfile, Qnil);
3081 symfile = ENCODE_FILE (symfile);
3082 }
3083 }
3084
3085 tem = Vpurify_flag;
3086 Vpurify_flag = Qnil;
3087
3088 # ifdef HYBRID_MALLOC
3089 {
3090 static char const fmt[] = "%d of %d static heap bytes used";
3091 char buf[sizeof fmt + 2 * (INT_STRLEN_BOUND (int) - 2)];
3092 int max_usage = max_bss_sbrk_ptr - bss_sbrk_buffer;
3093 sprintf (buf, fmt, max_usage, STATIC_HEAP_SIZE);
3094
3095 message1_nolog (buf);
3096 }
3097 # endif
3098
3099 fflush (stdout);
3100
3101
3102 # if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC && !defined WINDOWSNT
3103
3104
3105 memory_warnings (my_edata, malloc_warning);
3106 # endif
3107
3108 struct gflags old_gflags = gflags;
3109 gflags.will_dump_ = false;
3110 gflags.will_dump_with_unexec_ = false;
3111 gflags.dumped_with_unexec_ = true;
3112
3113 alloc_unexec_pre ();
3114
3115 unexec (SSDATA (filename), !NILP (symfile) ? SSDATA (symfile) : 0);
3116
3117 alloc_unexec_post ();
3118
3119 gflags = old_gflags;
3120
3121 # ifdef WINDOWSNT
3122 Vlibrary_cache = Qnil;
3123 # endif
3124
3125 Vpurify_flag = tem;
3126
3127 return unbind_to (count, Qnil);
3128 }
3129
3130 #endif
3131
3132
3133 #if HAVE_SETLOCALE
3134
3135 void
3136 fixup_locale (void)
3137 {
3138
3139
3140 setlocale (LC_NUMERIC, "C");
3141 }
3142
3143
3144
3145 static void
3146 synchronize_locale (int category, Lisp_Object *plocale, Lisp_Object desired_locale)
3147 {
3148 if (! EQ (*plocale, desired_locale))
3149 {
3150 *plocale = desired_locale;
3151 char const *locale_string
3152 = STRINGP (desired_locale) ? SSDATA (desired_locale) : "";
3153 # ifdef WINDOWSNT
3154
3155
3156
3157
3158
3159
3160 setlocale (LC_ALL, locale_string);
3161 fixup_locale ();
3162 # else
3163 setlocale (category, locale_string);
3164 # endif
3165 }
3166 }
3167
3168 static Lisp_Object Vprevious_system_time_locale;
3169
3170
3171 void
3172 synchronize_system_time_locale (void)
3173 {
3174 synchronize_locale (LC_TIME, &Vprevious_system_time_locale,
3175 Vsystem_time_locale);
3176 }
3177
3178 # ifdef LC_MESSAGES
3179 static Lisp_Object Vprevious_system_messages_locale;
3180 # endif
3181
3182
3183
3184 void
3185 synchronize_system_messages_locale (void)
3186 {
3187 # ifdef LC_MESSAGES
3188 synchronize_locale (LC_MESSAGES, &Vprevious_system_messages_locale,
3189 Vsystem_messages_locale);
3190 # endif
3191 }
3192 #endif
3193
3194
3195
3196 char *
3197 emacs_strerror (int error_number)
3198 {
3199 synchronize_system_messages_locale ();
3200 return strerror (error_number);
3201 }
3202
3203
3204 Lisp_Object
3205 decode_env_path (const char *evarname, const char *defalt, bool empty)
3206 {
3207 const char *path, *p;
3208 Lisp_Object lpath, element, tem;
3209 #ifdef NS_SELF_CONTAINED
3210 void *autorelease = NULL;
3211 #endif
3212
3213
3214 Lisp_Object empty_element = empty ? Qnil : build_string (".");
3215 #ifdef WINDOWSNT
3216 bool defaulted = 0;
3217 static const char *emacs_dir_env = "%emacs_dir%/";
3218 const size_t emacs_dir_len = strlen (emacs_dir_env);
3219 const char *edir = egetenv ("emacs_dir");
3220 char emacs_dir[MAX_UTF8_PATH];
3221
3222
3223
3224
3225 if (edir)
3226 filename_from_ansi (edir, emacs_dir);
3227 #endif
3228
3229
3230
3231
3232 if (evarname != 0)
3233 path = getenv (evarname);
3234 else
3235 path = 0;
3236 if (!path)
3237 {
3238 #ifdef NS_SELF_CONTAINED
3239
3240 autorelease = ns_alloc_autorelease_pool ();
3241 path = ns_relocate (defalt);
3242 #else
3243 path = defalt;
3244 #endif
3245 #ifdef WINDOWSNT
3246 defaulted = 1;
3247 #endif
3248 }
3249 #ifdef DOS_NT
3250
3251 if (path)
3252 {
3253 char *path_copy;
3254
3255 #ifdef WINDOWSNT
3256 char *path_utf8, *q, *d;
3257 int cnv_result;
3258
3259
3260 p = path_copy = alloca (strlen (path) + 1);
3261 strcpy (path_copy, path);
3262 d = path_utf8 = alloca (4 * strlen (path) + 1);
3263 *d = '\0';
3264 do {
3265 q = _mbschr (p, SEPCHAR);
3266 if (q)
3267 *q = '\0';
3268 cnv_result = filename_from_ansi (p, d);
3269 if (q)
3270 {
3271 *q++ = SEPCHAR;
3272 p = q;
3273
3274
3275
3276 if (cnv_result == 0)
3277 {
3278 d += strlen (d);
3279 *d++ = SEPCHAR;
3280 }
3281 }
3282 else if (cnv_result != 0 && d > path_utf8)
3283 d[-1] = '\0';
3284 } while (q);
3285 path_copy = path_utf8;
3286 #else
3287 path_copy = alloca (strlen (path) + 1);
3288 strcpy (path_copy, path);
3289 #endif
3290 dostounix_filename (path_copy);
3291 path = path_copy;
3292 }
3293 #endif
3294 lpath = Qnil;
3295 while (1)
3296 {
3297 p = strchr (path, SEPCHAR);
3298 if (!p)
3299 p = path + strlen (path);
3300 element = ((p - path) ? make_unibyte_string (path, p - path)
3301 : empty_element);
3302 if (! NILP (element))
3303 {
3304 #ifdef WINDOWSNT
3305
3306
3307 if (edir && defaulted
3308 && strncmp (path, emacs_dir_env, emacs_dir_len) == 0)
3309 element = Fexpand_file_name (Fsubstring
3310 (element,
3311 make_fixnum (emacs_dir_len),
3312 Qnil),
3313 build_unibyte_string (emacs_dir));
3314 #endif
3315
3316
3317
3318 tem = Ffind_file_name_handler (element, Qt);
3319
3320
3321
3322 if (SYMBOLP (tem))
3323 {
3324 Lisp_Object prop;
3325 prop = Fget (tem, intern ("safe-magic"));
3326 if (! NILP (prop))
3327 tem = Qnil;
3328 }
3329
3330 if (! NILP (tem))
3331 {
3332 AUTO_STRING (slash_colon, "/:");
3333 element = concat2 (slash_colon, element);
3334 }
3335 }
3336
3337 lpath = Fcons (element, lpath);
3338 if (*p)
3339 path = p + 1;
3340 else
3341 break;
3342 }
3343
3344 #ifdef NS_SELF_CONTAINED
3345 if (autorelease)
3346 ns_release_autorelease_pool (autorelease);
3347 #endif
3348 return Fnreverse (lpath);
3349 }
3350
3351 DEFUN ("daemonp", Fdaemonp, Sdaemonp, 0, 0, 0,
3352 doc:
3353 )
3354 (void)
3355 {
3356 if (IS_DAEMON)
3357 if (daemon_name)
3358 return build_string (daemon_name);
3359 else
3360 return Qt;
3361 else
3362 return Qnil;
3363 }
3364
3365 DEFUN ("daemon-initialized", Fdaemon_initialized, Sdaemon_initialized, 0, 0, 0,
3366 doc:
3367
3368 )
3369 (void)
3370 {
3371 bool err = 0;
3372
3373 if (!IS_DAEMON)
3374 error ("This function can only be called if emacs is run as a daemon");
3375
3376 if (!DAEMON_RUNNING)
3377 error ("The daemon has already been initialized");
3378
3379 if (NILP (Vafter_init_time))
3380 error ("This function can only be called after loading the init files");
3381 #ifndef WINDOWSNT
3382
3383 if (daemon_type == 1)
3384 {
3385 #ifdef HAVE_LIBSYSTEMD
3386 sd_notify(0, "READY=1");
3387 #endif
3388 }
3389
3390 if (daemon_type == 2)
3391 {
3392 int nfd;
3393
3394
3395 nfd = emacs_open_noquit ("/dev/null", O_RDWR, 0);
3396 err |= nfd < 0;
3397 err |= dup2 (nfd, STDIN_FILENO) < 0;
3398 err |= dup2 (nfd, STDOUT_FILENO) < 0;
3399 err |= dup2 (nfd, STDERR_FILENO) < 0;
3400 err |= emacs_close (nfd) != 0;
3401
3402
3403
3404
3405
3406
3407
3408
3409 err |= write (daemon_pipe[1], "\n", 1) < 0;
3410 err |= emacs_close (daemon_pipe[1]) != 0;
3411 }
3412
3413
3414 daemon_type = -daemon_type;
3415
3416 #else
3417
3418 err |= SetEvent (w32_daemon_event) == 0;
3419 err |= CloseHandle (w32_daemon_event) == 0;
3420
3421 w32_daemon_event = INVALID_HANDLE_VALUE;
3422 #endif
3423
3424 if (err)
3425 error ("I/O error during daemon initialization");
3426 return Qt;
3427 }
3428
3429 void
3430 syms_of_emacs (void)
3431 {
3432 DEFSYM (Qfile_name_handler_alist, "file-name-handler-alist");
3433 DEFSYM (Qrisky_local_variable, "risky-local-variable");
3434 DEFSYM (Qkill_emacs, "kill-emacs");
3435 DEFSYM (Qkill_emacs_hook, "kill-emacs-hook");
3436 DEFSYM (Qrun_hook_query_error_with_timeout,
3437 "run-hook-query-error-with-timeout");
3438
3439 #ifdef HAVE_UNEXEC
3440 defsubr (&Sdump_emacs);
3441 #endif
3442
3443 defsubr (&Skill_emacs);
3444
3445 defsubr (&Sinvocation_name);
3446 defsubr (&Sinvocation_directory);
3447 defsubr (&Sdaemonp);
3448 defsubr (&Sdaemon_initialized);
3449
3450 DEFVAR_LISP ("command-line-args", Vcommand_line_args,
3451 doc:
3452 );
3453
3454 DEFVAR_LISP ("system-type", Vsystem_type,
3455 doc:
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466 );
3467 Vsystem_type = intern_c_string (SYSTEM_TYPE);
3468
3469
3470 DEFVAR_LISP ("system-configuration", Vsystem_configuration,
3471 doc: );
3472 Vsystem_configuration = build_string (EMACS_CONFIGURATION);
3473
3474 DEFVAR_LISP ("system-configuration-options", Vsystem_configuration_options,
3475 doc: );
3476 Vsystem_configuration_options = build_string (EMACS_CONFIG_OPTIONS);
3477
3478 DEFVAR_LISP ("system-configuration-features", Vsystem_configuration_features,
3479 doc:
3480
3481
3482
3483
3484 );
3485 Vsystem_configuration_features = build_string (EMACS_CONFIG_FEATURES);
3486
3487 DEFVAR_BOOL ("noninteractive", noninteractive1,
3488 doc: );
3489
3490 DEFVAR_LISP ("kill-emacs-hook", Vkill_emacs_hook,
3491 doc:
3492
3493
3494
3495
3496
3497
3498 );
3499 Vkill_emacs_hook = Qnil;
3500
3501 DEFVAR_LISP ("path-separator", Vpath_separator,
3502 doc:
3503 );
3504 {
3505 char c = SEPCHAR;
3506 Vpath_separator = make_string (&c, 1);
3507 }
3508
3509 DEFVAR_LISP ("invocation-name", Vinvocation_name,
3510 doc:
3511 );
3512
3513 DEFVAR_LISP ("invocation-directory", Vinvocation_directory,
3514 doc:
3515 );
3516
3517 DEFVAR_LISP ("installation-directory", Vinstallation_directory,
3518 doc:
3519
3520
3521
3522
3523 );
3524 Vinstallation_directory = Qnil;
3525
3526 DEFVAR_LISP ("system-messages-locale", Vsystem_messages_locale,
3527 doc: );
3528 Vsystem_messages_locale = Qnil;
3529 #ifdef LC_MESSAGES
3530 Vprevious_system_messages_locale = Qnil;
3531 staticpro (&Vprevious_system_messages_locale);
3532 #endif
3533
3534 DEFVAR_LISP ("system-time-locale", Vsystem_time_locale,
3535 doc: );
3536 Vsystem_time_locale = Qnil;
3537 Vprevious_system_time_locale = Qnil;
3538 staticpro (&Vprevious_system_time_locale);
3539
3540 DEFVAR_LISP ("before-init-time", Vbefore_init_time,
3541 doc: );
3542 Vbefore_init_time = Qnil;
3543
3544 DEFVAR_LISP ("after-init-time", Vafter_init_time,
3545 doc:
3546 );
3547 Vafter_init_time = Qnil;
3548
3549 DEFVAR_BOOL ("inhibit-x-resources", inhibit_x_resources,
3550 doc: );
3551 inhibit_x_resources = 0;
3552
3553 DEFVAR_LISP ("emacs-copyright", Vemacs_copyright,
3554 doc: );
3555 Vemacs_copyright = build_string (emacs_copyright);
3556
3557 DEFVAR_LISP ("emacs-version", Vemacs_version,
3558 doc:
3559
3560
3561
3562
3563 );
3564 Vemacs_version = build_string (emacs_version);
3565
3566 DEFVAR_LISP ("report-emacs-bug-address", Vreport_emacs_bug_address,
3567 doc: );
3568 Vreport_emacs_bug_address = build_string (emacs_bugreport);
3569
3570 DEFVAR_LISP ("dump-mode", Vdump_mode,
3571 doc: );
3572
3573 DEFVAR_LISP ("dynamic-library-alist", Vdynamic_library_alist,
3574 doc:
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587 );
3588 #ifdef WINDOWSNT
3589
3590
3591
3592 if (will_dump_p ())
3593 Vdynamic_library_alist = list1 (list2 (Qgccjit,
3594 build_string ("libgccjit-0.dll")));
3595 else
3596 Vdynamic_library_alist = Qnil;
3597 #else
3598 Vdynamic_library_alist = Qnil;
3599 #endif
3600 Fput (intern_c_string ("dynamic-library-alist"), Qrisky_local_variable, Qt);
3601
3602 #ifdef WINDOWSNT
3603 Vlibrary_cache = Qnil;
3604 staticpro (&Vlibrary_cache);
3605 #endif
3606 }