This source file includes following definitions.
- get_current_directory
- record_kill_process
- delete_temp_file
- call_process_kill
- call_process_cleanup
- call_process
- create_temp_file
- add_env
- exec_failed
- child_setup
- emacs_posix_spawn_init_actions
- emacs_posix_spawn_init_attributes
- emacs_spawn
- getenv_internal_1
- getenv_internal
- egetenv_internal
- make_environment_block
- init_callproc_1
- init_callproc
- set_initial_environment
- syms_of_callproc
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 <errno.h>
24 #include <stdlib.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27
28 #ifdef MSDOS
29 extern char **environ;
30 #endif
31
32 #include <sys/file.h>
33 #include <fcntl.h>
34
35
36
37 #if defined HAVE_SPAWN_H && defined HAVE_POSIX_SPAWN \
38 && defined HAVE_POSIX_SPAWNATTR_SETFLAGS \
39 && (defined HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR \
40 || defined HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP) \
41 && defined HAVE_DECL_POSIX_SPAWN_SETSID \
42 && HAVE_DECL_POSIX_SPAWN_SETSID == 1 \
43
44 \
45 && !defined HAIKU
46 # include <spawn.h>
47 # define USABLE_POSIX_SPAWN 1
48 #else
49 # define USABLE_POSIX_SPAWN 0
50 #endif
51
52 #include "lisp.h"
53
54 #ifdef SETUP_SLAVE_PTY
55 # include <sys/stream.h>
56 # include <sys/stropts.h>
57 #endif
58
59 #ifdef WINDOWSNT
60 #include <sys/socket.h>
61 #include <windows.h>
62 #include "w32.h"
63 #define _P_NOWAIT 1
64 #endif
65
66 #ifdef MSDOS
67 #include <sys/stat.h>
68 #include <sys/param.h>
69 #endif
70
71 #include "commands.h"
72 #include "buffer.h"
73 #include "coding.h"
74 #include <epaths.h>
75 #include "process.h"
76 #include "syssignal.h"
77 #include "syswait.h"
78 #include "blockinput.h"
79 #include "frame.h"
80 #include "systty.h"
81 #include "keyboard.h"
82
83 #ifdef MSDOS
84 #include "msdos.h"
85 #endif
86
87 #ifdef HAVE_NS
88 #include "nsterm.h"
89 #endif
90
91 #ifdef HAVE_PGTK
92 #include "pgtkterm.h"
93 #endif
94
95 #ifdef HAVE_ANDROID
96 #include "android.h"
97 #endif
98
99
100 static Lisp_Object Vtemp_file_name_pattern;
101
102
103
104
105
106
107
108
109
110
111
112
113 static pid_t synch_process_pid;
114
115
116 #ifdef MSDOS
117 static Lisp_Object synch_process_tempfile;
118 #else
119 # define synch_process_tempfile make_fixnum (0)
120 #endif
121
122
123 enum
124 {
125
126
127 CALLPROC_STDOUT, CALLPROC_STDERR,
128
129
130 CALLPROC_PIPEREAD,
131
132
133 CALLPROC_FDS
134 };
135
136 static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int, specpdl_ref);
137
138 #ifdef DOS_NT
139 # define CHILD_SETUP_TYPE int
140 #else
141 # define CHILD_SETUP_TYPE _Noreturn void
142 #endif
143
144 static CHILD_SETUP_TYPE child_setup (int, int, int, char **, char **,
145 const char *);
146
147
148
149
150
151
152
153
154
155
156
157 Lisp_Object
158 get_current_directory (bool encode)
159 {
160 Lisp_Object curdir = BVAR (current_buffer, directory);
161 Lisp_Object dir = Funhandled_file_name_directory (curdir);
162
163
164
165 if (NILP (dir))
166 dir = build_string ("~");
167
168 #if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
169
170
171
172
173 if (encode && (!strcmp (SSDATA (dir), "/assets")
174 || !strncmp (SSDATA (dir), "/assets/", 8)
175 || !strcmp (SSDATA (dir), "/content")
176 || !strncmp (SSDATA (dir), "/content/", 9)))
177 dir = build_string ("~");
178
179 #endif
180
181 dir = expand_and_dir_to_file (dir);
182 Lisp_Object encoded_dir = ENCODE_FILE (remove_slash_colon (dir));
183
184 if (! file_accessible_directory_p (encoded_dir))
185 report_file_error ("Setting current directory", curdir);
186
187 return encode ? encoded_dir : dir;
188 }
189
190
191
192
193
194 void
195 record_kill_process (struct Lisp_Process *p, Lisp_Object tempfile)
196 {
197 #ifndef MSDOS
198 sigset_t oldset;
199 block_child_signal (&oldset);
200
201 if (p->alive)
202 {
203 record_deleted_pid (p->pid, tempfile);
204 p->alive = 0;
205 kill (- p->pid, SIGKILL);
206 }
207
208 unblock_child_signal (&oldset);
209 #endif
210 }
211
212
213
214 static void
215 delete_temp_file (Lisp_Object name)
216 {
217 emacs_unlink (SSDATA (name));
218 }
219
220 static void
221 call_process_kill (void *ptr)
222 {
223 int *callproc_fd = ptr;
224 int i;
225 for (i = 0; i < CALLPROC_FDS; i++)
226 if (0 <= callproc_fd[i])
227 emacs_close (callproc_fd[i]);
228
229 if (synch_process_pid)
230 {
231 struct Lisp_Process proc;
232 proc.alive = 1;
233 proc.pid = synch_process_pid;
234 record_kill_process (&proc, synch_process_tempfile);
235 synch_process_pid = 0;
236 }
237 else if (STRINGP (synch_process_tempfile))
238 delete_temp_file (synch_process_tempfile);
239 }
240
241
242
243
244 static void
245 call_process_cleanup (Lisp_Object buffer)
246 {
247 Fset_buffer (buffer);
248
249 #ifndef MSDOS
250 if (synch_process_pid)
251 {
252 kill (-synch_process_pid, SIGINT);
253 message1 ("Waiting for process to die...(type C-g again to kill it instantly)");
254
255
256 bool wait_ok = wait_for_termination (synch_process_pid, NULL, true);
257 synch_process_pid = 0;
258 message1 (wait_ok
259 ? "Waiting for process to die...done"
260 : "Waiting for process to die...internal error");
261 }
262 #endif
263 }
264
265 #ifdef DOS_NT
266 static mode_t const default_output_mode = S_IREAD | S_IWRITE;
267 #else
268 static mode_t const default_output_mode = 0666;
269 #endif
270
271 DEFUN ("call-process", Fcall_process, Scall_process, 1, MANY, 0,
272 doc:
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315 )
316 (ptrdiff_t nargs, Lisp_Object *args)
317 {
318 Lisp_Object infile, encoded_infile;
319 int filefd;
320 specpdl_ref count = SPECPDL_INDEX ();
321
322 if (nargs >= 2 && ! NILP (args[1]))
323 {
324
325
326 infile = Fexpand_file_name (args[1], get_current_directory (false));
327 CHECK_STRING (infile);
328 }
329 else
330 infile = build_string (NULL_DEVICE);
331
332
333 infile = remove_slash_colon (infile);
334
335 encoded_infile = ENCODE_FILE (infile);
336
337 filefd = emacs_open (SSDATA (encoded_infile), O_RDONLY, 0);
338 if (filefd < 0)
339 report_file_error ("Opening process input file", infile);
340 record_unwind_protect_int (close_file_unwind, filefd);
341 return unbind_to (count, call_process (nargs, args, filefd,
342 make_invalid_specpdl_ref ()));
343 }
344
345
346
347
348
349
350
351
352
353 static Lisp_Object
354 call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
355 specpdl_ref tempfile_index)
356 {
357 Lisp_Object buffer, current_dir, path;
358 bool display_p;
359 int fd0;
360 int callproc_fd[CALLPROC_FDS];
361 int status;
362 ptrdiff_t i;
363 specpdl_ref count = SPECPDL_INDEX ();
364 USE_SAFE_ALLOCA;
365
366 char **new_argv;
367
368
369 Lisp_Object error_file;
370 Lisp_Object output_file = Qnil;
371 #ifdef MSDOS
372 char *tempfile = NULL;
373 #else
374 sigset_t oldset;
375 pid_t pid = -1;
376 #endif
377 int child_errno;
378 int fd_output, fd_error;
379 struct coding_system process_coding;
380 struct coding_system argument_coding;
381
382 Lisp_Object coding_systems;
383 bool discard_output;
384
385 if (synch_process_pid)
386 error ("call-process invoked recursively");
387
388
389 coding_systems = Qt;
390
391 CHECK_STRING (args[0]);
392
393 error_file = Qt;
394
395 #ifndef subprocesses
396
397 if (nargs >= 3
398 && (FIXNUMP (CONSP (args[2]) ? XCAR (args[2]) : args[2])))
399 error ("Operating system cannot handle asynchronous subprocesses");
400 #endif
401
402
403 {
404 Lisp_Object val, *args2;
405
406
407 if (nargs >= 5)
408 {
409 bool must_encode = 0;
410 Lisp_Object coding_attrs;
411
412 for (i = 4; i < nargs; i++)
413 CHECK_STRING (args[i]);
414
415 for (i = 4; i < nargs; i++)
416 if (STRING_MULTIBYTE (args[i]))
417 must_encode = 1;
418
419 if (!NILP (Vcoding_system_for_write))
420 val = Vcoding_system_for_write;
421 else if (! must_encode)
422 val = Qraw_text;
423 else
424 {
425 SAFE_NALLOCA (args2, 1, nargs + 1);
426 args2[0] = Qcall_process;
427 for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
428 coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
429 val = CONSP (coding_systems) ? XCDR (coding_systems) : Qnil;
430 }
431 val = complement_process_encoding_system (val);
432 setup_coding_system (Fcheck_coding_system (val), &argument_coding);
433 coding_attrs = CODING_ID_ATTRS (argument_coding.id);
434 if (NILP (CODING_ATTR_ASCII_COMPAT (coding_attrs)))
435 {
436
437 val = raw_text_coding_system (val);
438 setup_coding_system (val, &argument_coding);
439 }
440 }
441 }
442
443 if (nargs < 3)
444 buffer = Qnil;
445 else
446 {
447 buffer = args[2];
448
449
450
451
452 if (CONSP (buffer) && !EQ (XCAR (buffer), QCfile))
453 {
454 if (CONSP (XCDR (buffer)))
455 {
456 Lisp_Object stderr_file;
457 stderr_file = XCAR (XCDR (buffer));
458
459 if (NILP (stderr_file) || EQ (Qt, stderr_file))
460 error_file = stderr_file;
461 else
462 error_file = Fexpand_file_name (stderr_file, Qnil);
463 }
464
465 buffer = XCAR (buffer);
466 }
467
468
469 if (CONSP (buffer) && EQ (XCAR (buffer), QCfile))
470 {
471 Lisp_Object ofile = XCDR (buffer);
472 if (CONSP (ofile))
473 ofile = XCAR (ofile);
474 CHECK_STRING (ofile);
475 output_file = Fexpand_file_name (ofile,
476 BVAR (current_buffer, directory));
477 CHECK_STRING (output_file);
478 buffer = Qnil;
479 }
480
481 if (! (NILP (buffer) || EQ (buffer, Qt) || FIXNUMP (buffer)))
482 {
483 Lisp_Object spec_buffer = buffer;
484 buffer = Fget_buffer_create (buffer, Qnil);
485
486 if (NILP (buffer))
487 CHECK_BUFFER (spec_buffer);
488 CHECK_BUFFER (buffer);
489 }
490 }
491
492
493
494
495
496 current_dir = get_current_directory (true);
497
498 if (STRINGP (error_file))
499 {
500 error_file = remove_slash_colon (error_file);
501 error_file = ENCODE_FILE (error_file);
502 }
503 if (STRINGP (output_file))
504 {
505 output_file = remove_slash_colon (output_file);
506 output_file = ENCODE_FILE (output_file);
507 }
508
509 display_p = INTERACTIVE && nargs >= 4 && !NILP (args[3]);
510
511 for (i = 0; i < CALLPROC_FDS; i++)
512 callproc_fd[i] = -1;
513 #ifdef MSDOS
514 synch_process_tempfile = make_fixnum (0);
515 #endif
516 record_unwind_protect_ptr (call_process_kill, callproc_fd);
517
518
519 {
520 int ok;
521
522 ok = openp (Vexec_path, args[0], Vexec_suffixes, &path,
523 make_fixnum (X_OK), false, false, NULL);
524 if (ok < 0)
525 report_file_error ("Searching for program", args[0]);
526 }
527
528
529 path = remove_slash_colon (path);
530
531 SAFE_NALLOCA (new_argv, 1, nargs < 4 ? 2 : nargs - 2);
532
533 if (nargs > 4)
534 {
535 ptrdiff_t i;
536
537 argument_coding.dst_multibyte = 0;
538 for (i = 4; i < nargs; i++)
539 {
540 argument_coding.src_multibyte = STRING_MULTIBYTE (args[i]);
541 if (CODING_REQUIRE_ENCODING (&argument_coding))
542
543 args[i] = encode_coding_string (&argument_coding, args[i], 1);
544 }
545 for (i = 4; i < nargs; i++)
546 new_argv[i - 3] = SSDATA (args[i]);
547 new_argv[i - 3] = 0;
548 }
549 else
550 new_argv[1] = 0;
551 path = ENCODE_FILE (path);
552 new_argv[0] = SSDATA (path);
553
554 discard_output = FIXNUMP (buffer) || (NILP (buffer) && NILP (output_file));
555
556 #ifdef MSDOS
557 if (! discard_output && ! STRINGP (output_file))
558 {
559 char const *tmpdir = egetenv ("TMPDIR");
560 char const *outf = tmpdir ? tmpdir : "";
561 tempfile = alloca (strlen (outf) + 20);
562 strcpy (tempfile, outf);
563 dostounix_filename (tempfile);
564 if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/')
565 strcat (tempfile, "/");
566 strcat (tempfile, "emXXXXXX");
567 mktemp (tempfile);
568 if (!*tempfile)
569 report_file_error ("Opening process output file", Qnil);
570 output_file = build_string (tempfile);
571 synch_process_tempfile = output_file;
572 }
573 #endif
574
575 if (discard_output)
576 {
577 fd_output = emacs_open (NULL_DEVICE, O_WRONLY, 0);
578 if (fd_output < 0)
579 report_file_error ("Opening null device", Qnil);
580 }
581 else if (STRINGP (output_file))
582 {
583 fd_output = emacs_open (SSDATA (output_file),
584 O_WRONLY | O_CREAT | O_TRUNC | O_TEXT,
585 default_output_mode);
586 if (fd_output < 0)
587 {
588 int open_errno = errno;
589 output_file = DECODE_FILE (output_file);
590 report_file_errno ("Opening process output file",
591 output_file, open_errno);
592 }
593 }
594 else
595 {
596 int fd[2];
597 if (emacs_pipe (fd) != 0)
598 report_file_error ("Creating process pipe", Qnil);
599 callproc_fd[CALLPROC_PIPEREAD] = fd[0];
600 fd_output = fd[1];
601 }
602 callproc_fd[CALLPROC_STDOUT] = fd_output;
603
604 fd_error = fd_output;
605
606 if (STRINGP (error_file) || (NILP (error_file) && !discard_output))
607 {
608 fd_error = emacs_open ((STRINGP (error_file)
609 ? SSDATA (error_file)
610 : NULL_DEVICE),
611 O_WRONLY | O_CREAT | O_TRUNC | O_TEXT,
612 default_output_mode);
613 if (fd_error < 0)
614 {
615 int open_errno = errno;
616 report_file_errno ("Cannot redirect stderr",
617 (STRINGP (error_file)
618 ? DECODE_FILE (error_file)
619 : build_string (NULL_DEVICE)),
620 open_errno);
621 }
622 callproc_fd[CALLPROC_STDERR] = fd_error;
623 }
624
625 char **env = make_environment_block (current_dir);
626
627 #ifdef MSDOS
628 status = child_setup (filefd, fd_output, fd_error, new_argv, env,
629 SSDATA (current_dir));
630
631 if (status < 0)
632 {
633 child_errno = errno;
634 unbind_to (count, Qnil);
635 synchronize_system_messages_locale ();
636 return
637 code_convert_string_norecord (build_string (strerror (child_errno)),
638 Vlocale_coding_system, 0);
639 }
640
641 for (i = 0; i < CALLPROC_FDS; i++)
642 if (0 <= callproc_fd[i])
643 {
644 emacs_close (callproc_fd[i]);
645 callproc_fd[i] = -1;
646 }
647 emacs_close (filefd);
648 clear_unwind_protect (specpdl_ref_add (count, -1));
649
650 if (tempfile)
651 {
652
653
654 callproc_fd[CALLPROC_PIPEREAD] = emacs_open (tempfile, O_RDONLY, 0);
655 if (callproc_fd[CALLPROC_PIPEREAD] < 0)
656 {
657 int open_errno = errno;
658 report_file_errno ("Cannot re-open temporary file",
659 build_string (tempfile), open_errno);
660 }
661 }
662
663 #endif
664
665
666
667
668 record_unwind_protect (call_process_cleanup, Fcurrent_buffer ());
669
670 #ifndef MSDOS
671
672 child_signal_init ();
673 block_input ();
674 block_child_signal (&oldset);
675
676 child_errno
677 = emacs_spawn (&pid, filefd, fd_output, fd_error, new_argv, env,
678 SSDATA (current_dir), NULL, false, false, &oldset);
679 eassert ((child_errno == 0) == (0 < pid));
680
681 if (pid > 0)
682 {
683 synch_process_pid = pid;
684
685 if (FIXNUMP (buffer))
686 {
687 if (!specpdl_ref_valid_p (tempfile_index))
688 record_deleted_pid (pid, Qnil);
689 else
690 {
691 eassert (1 < nargs);
692 record_deleted_pid (pid, args[1]);
693 clear_unwind_protect (tempfile_index);
694 }
695 synch_process_pid = 0;
696 }
697 }
698
699 unblock_child_signal (&oldset);
700 unblock_input ();
701
702 if (pid < 0)
703 report_file_errno (CHILD_SETUP_ERROR_DESC, Qnil, child_errno);
704
705
706
707 for (i = 0; i < CALLPROC_FDS; i++)
708 if (i != CALLPROC_PIPEREAD && 0 <= callproc_fd[i])
709 {
710 emacs_close (callproc_fd[i]);
711 callproc_fd[i] = -1;
712 }
713 emacs_close (filefd);
714 clear_unwind_protect (specpdl_ref_add (count, -1));
715
716 #endif
717
718 if (FIXNUMP (buffer))
719 return unbind_to (count, Qnil);
720
721 if (BUFFERP (buffer))
722 Fset_buffer (buffer);
723
724 fd0 = callproc_fd[CALLPROC_PIPEREAD];
725
726 if (0 <= fd0)
727 {
728 Lisp_Object val, *args2;
729
730 val = Qnil;
731 if (!NILP (Vcoding_system_for_read))
732 val = Vcoding_system_for_read;
733 else
734 {
735 if (EQ (coding_systems, Qt))
736 {
737 ptrdiff_t i;
738
739 SAFE_NALLOCA (args2, 1, nargs + 1);
740 args2[0] = Qcall_process;
741 for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
742 coding_systems
743 = Ffind_operation_coding_system (nargs + 1, args2);
744 }
745 if (CONSP (coding_systems))
746 val = XCAR (coding_systems);
747 else if (CONSP (Vdefault_process_coding_system))
748 val = XCAR (Vdefault_process_coding_system);
749 else
750 val = Qnil;
751 }
752 Fcheck_coding_system (val);
753
754
755
756 if (NILP (BVAR (current_buffer, enable_multibyte_characters))
757 && !NILP (val))
758 val = raw_text_coding_system (val);
759 setup_coding_system (val, &process_coding);
760 process_coding.dst_multibyte
761 = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
762 process_coding.src_multibyte = 0;
763 }
764
765 if (0 <= fd0)
766 {
767 enum { CALLPROC_BUFFER_SIZE_MIN = 16 * 1024 };
768 enum { CALLPROC_BUFFER_SIZE_MAX = 4 * CALLPROC_BUFFER_SIZE_MIN };
769 char buf[CALLPROC_BUFFER_SIZE_MAX];
770 int bufsize = CALLPROC_BUFFER_SIZE_MIN;
771 int nread;
772 EMACS_INT total_read = 0;
773 int carryover = 0;
774 bool display_on_the_fly = display_p;
775 struct coding_system saved_coding = process_coding;
776 ptrdiff_t prepared_pos = 0;
777
778
779 while (1)
780 {
781
782
783
784 nread = carryover;
785 while (nread < bufsize - 1024)
786 {
787 int this_read = emacs_read_quit (fd0, buf + nread,
788 bufsize - nread);
789
790 if (this_read < 0)
791 goto give_up;
792
793 if (this_read == 0)
794 {
795 process_coding.mode |= CODING_MODE_LAST_BLOCK;
796 break;
797 }
798
799 nread += this_read;
800 total_read += this_read;
801
802 if (display_on_the_fly)
803 break;
804 }
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827 if ((prepared_pos < PT) && nread)
828 {
829 prepare_to_modify_buffer (PT, PT, NULL);
830 prepared_pos = PT;
831 }
832
833
834
835 if (!nread)
836 ;
837 else if (NILP (BVAR (current_buffer, enable_multibyte_characters))
838 && ! CODING_MAY_REQUIRE_DECODING (&process_coding))
839 {
840 insert_1_both (buf, nread, nread, 0, 0, 0);
841 signal_after_change (PT - nread, 0, nread);
842 }
843 else
844 {
845 Lisp_Object curbuf;
846 specpdl_ref count1 = SPECPDL_INDEX ();
847
848 XSETBUFFER (curbuf, current_buffer);
849
850
851
852
853
854 specbind (Qinhibit_modification_hooks, Qt);
855 decode_coding_c_string (&process_coding,
856 (unsigned char *) buf, nread, curbuf);
857 unbind_to (count1, Qnil);
858 if (display_on_the_fly
859 && CODING_REQUIRE_DETECTION (&saved_coding)
860 && ! CODING_REQUIRE_DETECTION (&process_coding))
861 {
862
863
864
865 if (process_coding.produced > 0)
866 del_range_2 (process_coding.dst_pos,
867 process_coding.dst_pos_byte,
868 (process_coding.dst_pos
869 + process_coding.produced_char),
870 (process_coding.dst_pos_byte
871 + process_coding.produced),
872 0);
873 display_on_the_fly = false;
874 process_coding = saved_coding;
875 carryover = nread;
876
877 saved_coding.common_flags
878 &= ~CODING_REQUIRE_DETECTION_MASK;
879 continue;
880 }
881
882 TEMP_SET_PT_BOTH (PT + process_coding.produced_char,
883 PT_BYTE + process_coding.produced);
884 signal_after_change (PT - process_coding.produced_char,
885 0, process_coding.produced_char);
886 carryover = process_coding.carryover_bytes;
887 if (carryover > 0)
888 memcpy (buf, process_coding.carryover,
889 process_coding.carryover_bytes);
890 }
891
892 if (process_coding.mode & CODING_MODE_LAST_BLOCK)
893 break;
894
895
896
897 if (bufsize < CALLPROC_BUFFER_SIZE_MAX && total_read > 32 * bufsize)
898 if ((bufsize *= 2) > CALLPROC_BUFFER_SIZE_MAX)
899 bufsize = CALLPROC_BUFFER_SIZE_MAX;
900
901 if (display_p)
902 {
903 redisplay_preserve_echo_area (1);
904
905
906
907 display_on_the_fly = true;
908 }
909 }
910 give_up: ;
911
912 Vlast_coding_system_used = CODING_ID_NAME (process_coding.id);
913
914
915 if (inherit_process_coding_system)
916 call1 (intern ("after-insert-file-set-buffer-file-coding-system"),
917 make_fixnum (total_read));
918 }
919
920 bool wait_ok = true;
921 #ifndef MSDOS
922
923 wait_ok = wait_for_termination (pid, &status, fd0 < 0);
924 #endif
925
926
927
928 synch_process_pid = 0;
929
930 SAFE_FREE_UNBIND_TO (count, Qnil);
931
932 if (!wait_ok)
933 return build_unibyte_string ("internal error");
934
935 if (WIFSIGNALED (status))
936 {
937 const char *signame;
938
939 synchronize_system_messages_locale ();
940 signame = strsignal (WTERMSIG (status));
941
942 if (signame == 0)
943 signame = "unknown";
944
945 return code_convert_string_norecord (build_string (signame),
946 Vlocale_coding_system, 0);
947 }
948
949 eassert (WIFEXITED (status));
950 return make_fixnum (WEXITSTATUS (status));
951 }
952
953
954
955
956
957
958
959
960 static int
961 create_temp_file (ptrdiff_t nargs, Lisp_Object *args,
962 Lisp_Object *filename_string_ptr)
963 {
964 int fd;
965 Lisp_Object filename_string;
966 Lisp_Object val, start, end;
967 Lisp_Object tmpdir;
968
969 if (STRINGP (Vtemporary_file_directory))
970 tmpdir = Vtemporary_file_directory;
971 else
972 {
973 char *outf;
974 #ifndef DOS_NT
975 outf = getenv ("TMPDIR");
976 tmpdir = build_string (outf ? outf : "/tmp/");
977 #else
978 if ((outf = egetenv ("TMPDIR"))
979 || (outf = egetenv ("TMP"))
980 || (outf = egetenv ("TEMP")))
981 tmpdir = build_string (outf);
982 else
983 tmpdir = Ffile_name_as_directory (build_string ("c:/temp"));
984 #endif
985 }
986
987 {
988 Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir);
989 char *tempfile;
990
991 #ifdef WINDOWSNT
992
993
994
995 if (!NILP (Vw32_downcase_file_names))
996 {
997 Lisp_Object dirname = Ffile_name_directory (pattern);
998
999 if (NILP (dirname))
1000 pattern = Vtemp_file_name_pattern;
1001 else
1002 pattern = concat2 (dirname, Vtemp_file_name_pattern);
1003 }
1004 #endif
1005
1006 filename_string = Fcopy_sequence (ENCODE_FILE (pattern));
1007 tempfile = SSDATA (filename_string);
1008
1009 specpdl_ref count = SPECPDL_INDEX ();
1010 record_unwind_protect_nothing ();
1011 fd = mkostemp (tempfile, O_BINARY | O_CLOEXEC);
1012 if (fd < 0)
1013 report_file_error ("Failed to open temporary file using pattern",
1014 pattern);
1015 set_unwind_protect (count, delete_temp_file, filename_string);
1016 record_unwind_protect_int (close_file_unwind, fd);
1017 }
1018
1019 start = args[0];
1020 end = args[1];
1021
1022 if (!NILP (Vcoding_system_for_write))
1023 val = Vcoding_system_for_write;
1024 else if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
1025 val = Qraw_text;
1026 else
1027 {
1028 Lisp_Object coding_systems;
1029 Lisp_Object *args2;
1030 USE_SAFE_ALLOCA;
1031 SAFE_NALLOCA (args2, 1, nargs + 1);
1032 args2[0] = Qcall_process_region;
1033 memcpy (args2 + 1, args, nargs * sizeof *args);
1034 coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
1035 val = CONSP (coding_systems) ? XCDR (coding_systems) : Qnil;
1036 SAFE_FREE ();
1037 }
1038 val = complement_process_encoding_system (val);
1039
1040 {
1041 specpdl_ref count1 = SPECPDL_INDEX ();
1042
1043 specbind (intern ("coding-system-for-write"), val);
1044
1045
1046 specbind (Qfile_name_handler_alist, Qnil);
1047 write_region (start, end, filename_string, Qnil, Qlambda, Qnil, Qnil, fd);
1048
1049 unbind_to (count1, Qnil);
1050 }
1051
1052 if (lseek (fd, 0, SEEK_SET) < 0)
1053 report_file_error ("Setting file position", filename_string);
1054
1055
1056
1057
1058 *filename_string_ptr = filename_string;
1059 return fd;
1060 }
1061
1062 DEFUN ("call-process-region", Fcall_process_region, Scall_process_region,
1063 3, MANY, 0,
1064 doc:
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098 )
1099 (ptrdiff_t nargs, Lisp_Object *args)
1100 {
1101 Lisp_Object infile, val;
1102 specpdl_ref count = SPECPDL_INDEX ();
1103 Lisp_Object start = args[0];
1104 Lisp_Object end = args[1];
1105 bool empty_input;
1106 int fd;
1107
1108 if (STRINGP (start))
1109 empty_input = SCHARS (start) == 0;
1110 else if (NILP (start))
1111 empty_input = BEG == Z;
1112 else
1113 {
1114 validate_region (&args[0], &args[1]);
1115 start = args[0];
1116 end = args[1];
1117 empty_input = XFIXNUM (start) == XFIXNUM (end);
1118 }
1119
1120 if (!empty_input)
1121 fd = create_temp_file (nargs, args, &infile);
1122 else
1123 {
1124 infile = Qnil;
1125 fd = emacs_open (NULL_DEVICE, O_RDONLY, 0);
1126 if (fd < 0)
1127 report_file_error ("Opening null device", Qnil);
1128 record_unwind_protect_int (close_file_unwind, fd);
1129 }
1130
1131 if (nargs > 3 && !NILP (args[3]))
1132 {
1133 if (NILP (start))
1134 {
1135
1136
1137 labeled_restrictions_remove_in_current_buffer ();
1138 Fwiden ();
1139 del_range (BEG, Z);
1140 }
1141 else
1142 Fdelete_region (start, end);
1143 }
1144
1145 if (nargs > 3)
1146 {
1147 args += 2;
1148 nargs -= 2;
1149 }
1150 else
1151 {
1152 args[0] = args[2];
1153 nargs = 2;
1154 }
1155 args[1] = infile;
1156
1157 val = call_process (nargs, args, fd,
1158 empty_input ? make_invalid_specpdl_ref () : count);
1159 return unbind_to (count, val);
1160 }
1161
1162 static char **
1163 add_env (char **env, char **new_env, char *string)
1164 {
1165 char **ep;
1166 bool ok = 1;
1167 if (string == NULL)
1168 return new_env;
1169
1170
1171
1172
1173
1174 for (ep = env; ok && ep != new_env; ep++)
1175 {
1176 char *p = *ep, *q = string;
1177 while (ok)
1178 {
1179 if (*p && *q != *p)
1180 break;
1181 if (*q == 0)
1182
1183
1184
1185 break;
1186 if (*q == '=')
1187 ok = 0;
1188 p++, q++;
1189 }
1190 }
1191 if (ok)
1192 *new_env++ = string;
1193 return new_env;
1194 }
1195
1196 #ifndef DOS_NT
1197
1198
1199
1200
1201
1202
1203
1204 static AVOID
1205 exec_failed (char const *name, int err)
1206 {
1207
1208
1209
1210 fcntl (STDERR_FILENO, F_SETFL, O_NONBLOCK);
1211
1212 errno = err;
1213 emacs_perror (name);
1214 _exit (err == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
1215 }
1216
1217 #endif
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234 static CHILD_SETUP_TYPE
1235 child_setup (int in, int out, int err, char **new_argv, char **env,
1236 const char *current_dir)
1237 {
1238 #ifdef MSDOS
1239 char *pwd_var;
1240 char *temp;
1241 ptrdiff_t i;
1242 #endif
1243 #ifdef WINDOWSNT
1244 int cpid;
1245 HANDLE handles[3];
1246 #else
1247 pid_t pid = getpid ();
1248 #endif
1249
1250
1251
1252
1253
1254
1255
1256
1257 #ifndef DOS_NT
1258
1259
1260
1261
1262
1263 if (chdir (current_dir) < 0)
1264 _exit (EXIT_CANCELED);
1265 #endif
1266
1267 #ifdef WINDOWSNT
1268 prepare_standard_handles (in, out, err, handles);
1269 set_process_dir (current_dir);
1270
1271 cpid = spawnve (_P_NOWAIT, new_argv[0], new_argv, env);
1272 reset_standard_handles (in, out, err, handles);
1273 return cpid;
1274
1275 #else
1276
1277 #ifndef MSDOS
1278
1279 restore_nofile_limit ();
1280
1281
1282
1283
1284 dup2 (in, STDIN_FILENO);
1285 dup2 (out, STDOUT_FILENO);
1286 dup2 (err, STDERR_FILENO);
1287
1288 setpgid (0, 0);
1289 tcsetpgrp (0, pid);
1290
1291 int errnum = emacs_exec_file (new_argv[0], new_argv, env);
1292 exec_failed (new_argv[0], errnum);
1293
1294 #else
1295 i = strlen (current_dir);
1296 pwd_var = xmalloc (i + 5);
1297 temp = pwd_var + 4;
1298 memcpy (pwd_var, "PWD=", 4);
1299 stpcpy (temp, current_dir);
1300
1301 if (i > 2 && IS_DEVICE_SEP (temp[1]) && IS_DIRECTORY_SEP (temp[2]))
1302 {
1303 temp += 2;
1304 i -= 2;
1305 }
1306
1307
1308 while (i > 2 && IS_DIRECTORY_SEP (temp[i - 1]))
1309 temp[--i] = 0;
1310
1311 pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env);
1312 xfree (pwd_var);
1313 if (pid == -1)
1314
1315 report_file_error ("Spawning child process", Qnil);
1316 return pid;
1317 #endif
1318 #endif
1319 }
1320
1321 #if USABLE_POSIX_SPAWN
1322
1323
1324
1325
1326 static int
1327 emacs_posix_spawn_init_actions (posix_spawn_file_actions_t *actions,
1328 int std_in, int std_out, int std_err,
1329 const char *cwd)
1330 {
1331 int error = posix_spawn_file_actions_init (actions);
1332 if (error != 0)
1333 return error;
1334
1335 error = posix_spawn_file_actions_adddup2 (actions, std_in,
1336 STDIN_FILENO);
1337 if (error != 0)
1338 goto out;
1339
1340 error = posix_spawn_file_actions_adddup2 (actions, std_out,
1341 STDOUT_FILENO);
1342 if (error != 0)
1343 goto out;
1344
1345 error = posix_spawn_file_actions_adddup2 (actions,
1346 std_err < 0 ? std_out
1347 : std_err,
1348 STDERR_FILENO);
1349 if (error != 0)
1350 goto out;
1351
1352
1353
1354 #if defined HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR && !defined HAIKU
1355 error = posix_spawn_file_actions_addchdir (actions, cwd);
1356 #else
1357 error = posix_spawn_file_actions_addchdir_np (actions, cwd);
1358 #endif
1359 if (error != 0)
1360 goto out;
1361
1362 out:
1363 if (error != 0)
1364 posix_spawn_file_actions_destroy (actions);
1365 return error;
1366 }
1367
1368 static int
1369 emacs_posix_spawn_init_attributes (posix_spawnattr_t *attributes,
1370 const sigset_t *oldset)
1371 {
1372 int error = posix_spawnattr_init (attributes);
1373 if (error != 0)
1374 return error;
1375
1376 error = posix_spawnattr_setflags (attributes,
1377 POSIX_SPAWN_SETSID
1378 | POSIX_SPAWN_SETSIGDEF
1379 | POSIX_SPAWN_SETSIGMASK);
1380 if (error != 0)
1381 goto out;
1382
1383 sigset_t sigdefault;
1384 sigemptyset (&sigdefault);
1385
1386 #ifdef DARWIN_OS
1387
1388
1389
1390
1391 sigaddset (&sigdefault, SIGCHLD);
1392 #endif
1393
1394 sigaddset (&sigdefault, SIGINT);
1395 sigaddset (&sigdefault, SIGQUIT);
1396 #ifdef SIGPROF
1397 sigaddset (&sigdefault, SIGPROF);
1398 #endif
1399
1400
1401 sigaddset (&sigdefault, SIGPIPE);
1402
1403 #ifdef SIGPROF
1404 sigaddset (&sigdefault, SIGPROF);
1405 #endif
1406
1407 error = posix_spawnattr_setsigdefault (attributes, &sigdefault);
1408 if (error != 0)
1409 goto out;
1410
1411
1412 error = posix_spawnattr_setsigmask (attributes, oldset);
1413 if (error != 0)
1414 goto out;
1415
1416 out:
1417 if (error != 0)
1418 posix_spawnattr_destroy (attributes);
1419
1420 return error;
1421 }
1422
1423 #endif
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439 int
1440 emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err,
1441 char **argv, char **envp, const char *cwd,
1442 const char *pty_name, bool pty_in, bool pty_out,
1443 const sigset_t *oldset)
1444 {
1445 #if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
1446
1447
1448
1449
1450
1451
1452 if (android_rewrite_spawn_argv ((const char ***) &argv))
1453 return 1;
1454 #endif
1455
1456
1457 #if USABLE_POSIX_SPAWN
1458
1459
1460
1461
1462 bool use_posix_spawn = pty_name == NULL;
1463
1464 posix_spawn_file_actions_t actions;
1465 posix_spawnattr_t attributes;
1466
1467 if (use_posix_spawn)
1468 {
1469
1470 int error = emacs_posix_spawn_init_actions (&actions, std_in,
1471 std_out, std_err, cwd);
1472 if (error != 0)
1473 return error;
1474
1475 error = emacs_posix_spawn_init_attributes (&attributes, oldset);
1476 if (error != 0)
1477 return error;
1478 }
1479 #endif
1480
1481 int pid;
1482 int vfork_error;
1483
1484 eassert (input_blocked_p ());
1485
1486 #if USABLE_POSIX_SPAWN
1487 if (use_posix_spawn)
1488 {
1489 vfork_error = posix_spawn (&pid, argv[0], &actions, &attributes,
1490 argv, envp);
1491 if (vfork_error != 0)
1492 pid = -1;
1493
1494 int error = posix_spawn_file_actions_destroy (&actions);
1495 if (error != 0)
1496 {
1497 errno = error;
1498 emacs_perror ("posix_spawn_file_actions_destroy");
1499 }
1500
1501 error = posix_spawnattr_destroy (&attributes);
1502 if (error != 0)
1503 {
1504 errno = error;
1505 emacs_perror ("posix_spawnattr_destroy");
1506 }
1507
1508 goto fork_done;
1509 }
1510 #endif
1511
1512 #ifndef WINDOWSNT
1513
1514 pid_t *volatile newpid_volatile = newpid;
1515 const char *volatile cwd_volatile = cwd;
1516 const char *volatile ptyname_volatile = pty_name;
1517 bool volatile ptyin_volatile = pty_in;
1518 bool volatile ptyout_volatile = pty_out;
1519 char **volatile argv_volatile = argv;
1520 int volatile stdin_volatile = std_in;
1521 int volatile stdout_volatile = std_out;
1522 int volatile stderr_volatile = std_err;
1523 char **volatile envp_volatile = envp;
1524 const sigset_t *volatile oldset_volatile = oldset;
1525
1526 #ifdef DARWIN_OS
1527
1528
1529
1530 if (pty_in || pty_out)
1531 pid = fork ();
1532 else
1533 pid = VFORK ();
1534 #else
1535 pid = vfork ();
1536 #endif
1537
1538 newpid = newpid_volatile;
1539 cwd = cwd_volatile;
1540 pty_name = ptyname_volatile;
1541 pty_in = ptyin_volatile;
1542 pty_out = ptyout_volatile;
1543 argv = argv_volatile;
1544 std_in = stdin_volatile;
1545 std_out = stdout_volatile;
1546 std_err = stderr_volatile;
1547 envp = envp_volatile;
1548 oldset = oldset_volatile;
1549
1550 if (pid == 0)
1551 #endif
1552 {
1553
1554 #ifdef HAVE_PTYS
1555 dissociate_controlling_tty ();
1556
1557
1558 if (pty_in && std_in >= 0)
1559 {
1560 #ifdef TIOCSCTTY
1561
1562
1563 ioctl (std_in, TIOCSCTTY, 0);
1564 #endif
1565 }
1566 #if defined (LDISC1)
1567 if (pty_in && std_in >= 0)
1568 {
1569 struct termios t;
1570 tcgetattr (std_in, &t);
1571 t.c_lflag = LDISC1;
1572 if (tcsetattr (std_in, TCSANOW, &t) < 0)
1573 emacs_perror ("create_process/tcsetattr LDISC1");
1574 }
1575 #else
1576 #if defined (NTTYDISC) && defined (TIOCSETD)
1577 if (pty_in && std_in >= 0)
1578 {
1579
1580 int ldisc = NTTYDISC;
1581 ioctl (std_in, TIOCSETD, &ldisc);
1582 }
1583 #endif
1584 #endif
1585
1586 #if !defined (DONT_REOPEN_PTY)
1587
1588
1589
1590
1591
1592
1593
1594 if (pty_name)
1595 {
1596
1597
1598
1599 if (pty_in && std_in >= 0)
1600 emacs_close (std_in);
1601 int ptyfd = emacs_open_noquit (pty_name, O_RDWR, 0);
1602 if (pty_in)
1603 std_in = ptyfd;
1604 if (pty_out)
1605 std_out = ptyfd;
1606 if (std_in < 0)
1607 {
1608 emacs_perror (pty_name);
1609 _exit (EXIT_CANCELED);
1610 }
1611
1612 }
1613 #endif
1614
1615 #ifdef SETUP_SLAVE_PTY
1616 if (pty_in && std_in >= 0)
1617 {
1618 SETUP_SLAVE_PTY;
1619 }
1620 #endif
1621 #endif
1622
1623 #ifdef DARWIN_OS
1624
1625
1626
1627
1628 signal (SIGCHLD, SIG_DFL);
1629 #endif
1630
1631 signal (SIGINT, SIG_DFL);
1632 signal (SIGQUIT, SIG_DFL);
1633 #ifdef SIGPROF
1634 signal (SIGPROF, SIG_DFL);
1635 #endif
1636
1637
1638 signal (SIGPIPE, SIG_DFL);
1639
1640 #ifdef SIGPROF
1641 signal (SIGPROF, SIG_DFL);
1642 #endif
1643
1644 #ifdef subprocesses
1645
1646 unblock_child_signal (oldset);
1647
1648 if (pty_out)
1649 child_setup_tty (std_out);
1650 #endif
1651
1652 if (std_err < 0)
1653 std_err = std_out;
1654 #ifdef WINDOWSNT
1655 pid = child_setup (std_in, std_out, std_err, argv, envp, cwd);
1656 #else
1657 child_setup (std_in, std_out, std_err, argv, envp, cwd);
1658 #endif
1659 }
1660
1661
1662
1663 vfork_error = pid < 0 ? errno : 0;
1664
1665 #if USABLE_POSIX_SPAWN
1666 fork_done:
1667 #endif
1668 if (pid < 0)
1669 {
1670 eassert (0 < vfork_error);
1671 return vfork_error;
1672 }
1673
1674 eassert (0 < pid);
1675 *newpid = pid;
1676 return 0;
1677 }
1678
1679 static bool
1680 getenv_internal_1 (const char *var, ptrdiff_t varlen, char **value,
1681 ptrdiff_t *valuelen, Lisp_Object env)
1682 {
1683 for (; CONSP (env); env = XCDR (env))
1684 {
1685 Lisp_Object entry = XCAR (env);
1686 if (STRINGP (entry)
1687 && SBYTES (entry) >= varlen
1688 #ifdef WINDOWSNT
1689
1690 && ! strnicmp (SSDATA (entry), var, varlen)
1691 #else
1692 && ! memcmp (SDATA (entry), var, varlen)
1693 #endif
1694 )
1695 {
1696 if (SBYTES (entry) > varlen && SREF (entry, varlen) == '=')
1697 {
1698 *value = SSDATA (entry) + (varlen + 1);
1699 *valuelen = SBYTES (entry) - (varlen + 1);
1700 return 1;
1701 }
1702 else if (SBYTES (entry) == varlen)
1703 {
1704
1705
1706 *value = NULL;
1707 return 1;
1708 }
1709 }
1710 }
1711 return 0;
1712 }
1713
1714 static bool
1715 getenv_internal (const char *var, ptrdiff_t varlen, char **value,
1716 ptrdiff_t *valuelen, Lisp_Object frame)
1717 {
1718
1719 if (getenv_internal_1 (var, varlen, value, valuelen,
1720 Vprocess_environment))
1721 return *value ? 1 : 0;
1722
1723
1724
1725 #ifdef WINDOWSNT
1726 {
1727 char *tmpval = getenv (var);
1728 if (tmpval)
1729 {
1730 *value = tmpval;
1731 *valuelen = strlen (tmpval);
1732 return 1;
1733 }
1734 }
1735 #endif
1736
1737
1738 if (strcmp (var, "DISPLAY") == 0)
1739 {
1740 #ifndef HAVE_PGTK
1741 Lisp_Object display
1742 = Fframe_parameter (NILP (frame) ? selected_frame : frame, Qdisplay);
1743 if (STRINGP (display))
1744 {
1745 *value = SSDATA (display);
1746 *valuelen = SBYTES (display);
1747 return 1;
1748 }
1749 #endif
1750
1751 if (getenv_internal_1 (var, varlen, value, valuelen,
1752 Vinitial_environment))
1753 return *value ? 1 : 0;
1754 }
1755
1756 return 0;
1757 }
1758
1759 DEFUN ("getenv-internal", Fgetenv_internal, Sgetenv_internal, 1, 2, 0,
1760 doc:
1761
1762
1763
1764
1765
1766
1767
1768 )
1769 (Lisp_Object variable, Lisp_Object env)
1770 {
1771 char *value;
1772 ptrdiff_t valuelen;
1773
1774 CHECK_STRING (variable);
1775 if (CONSP (env))
1776 {
1777 if (getenv_internal_1 (SSDATA (variable), SBYTES (variable),
1778 &value, &valuelen, env))
1779 return value ? make_string (value, valuelen) : Qt;
1780 else
1781 return Qnil;
1782 }
1783 else if (getenv_internal (SSDATA (variable), SBYTES (variable),
1784 &value, &valuelen, env))
1785 return make_string (value, valuelen);
1786 else
1787 return Qnil;
1788 }
1789
1790
1791
1792 char *
1793 egetenv_internal (const char *var, ptrdiff_t len)
1794 {
1795 char *value;
1796 ptrdiff_t valuelen;
1797
1798 if (getenv_internal (var, len, &value, &valuelen, Qnil))
1799 return value;
1800 else
1801 return 0;
1802 }
1803
1804
1805
1806
1807
1808
1809 char **
1810 make_environment_block (Lisp_Object current_dir)
1811 {
1812 char **env;
1813 char *pwd_var;
1814
1815 {
1816 char *temp;
1817 ptrdiff_t i;
1818
1819 i = SBYTES (current_dir);
1820 pwd_var = xmalloc (i + 5);
1821 record_unwind_protect_ptr (xfree, pwd_var);
1822 temp = pwd_var + 4;
1823 memcpy (pwd_var, "PWD=", 4);
1824 lispstpcpy (temp, current_dir);
1825
1826 #ifdef DOS_NT
1827
1828 if (i > 2 && IS_DEVICE_SEP (temp[1]) && IS_DIRECTORY_SEP (temp[2]))
1829 {
1830 temp += 2;
1831 i -= 2;
1832 }
1833 #endif
1834
1835
1836 while (i > 2 && IS_DIRECTORY_SEP (temp[i - 1]))
1837 temp[--i] = 0;
1838 }
1839
1840
1841
1842 {
1843 register Lisp_Object tem;
1844 register char **new_env;
1845 char **p, **q;
1846 register int new_length;
1847 Lisp_Object display = Qnil;
1848
1849 new_length = 0;
1850
1851 for (tem = Vprocess_environment;
1852 CONSP (tem) && STRINGP (XCAR (tem));
1853 tem = XCDR (tem))
1854 {
1855 if (strncmp (SSDATA (XCAR (tem)), "DISPLAY", 7) == 0
1856 && (SDATA (XCAR (tem)) [7] == '\0'
1857 || SDATA (XCAR (tem)) [7] == '='))
1858
1859 display = Qt;
1860 new_length++;
1861 }
1862
1863
1864 if (NILP (display))
1865 {
1866 Lisp_Object tmp = Fframe_parameter (selected_frame, Qdisplay);
1867
1868 #ifdef HAVE_PGTK
1869
1870
1871
1872
1873 if (FRAME_WINDOW_P (SELECTED_FRAME ())
1874 && strcmp (G_OBJECT_TYPE_NAME (FRAME_X_DISPLAY (SELECTED_FRAME ())),
1875 "GdkX11Display"))
1876 tmp = Qnil;
1877 #endif
1878
1879 if (!STRINGP (tmp) && CONSP (Vinitial_environment))
1880
1881 tmp = Fgetenv_internal (build_string ("DISPLAY"),
1882 Vinitial_environment);
1883 if (STRINGP (tmp))
1884 {
1885 display = tmp;
1886 new_length++;
1887 }
1888 }
1889
1890
1891 env = new_env = xnmalloc (new_length + 2, sizeof *env);
1892 record_unwind_protect_ptr (xfree, env);
1893
1894
1895 if (egetenv ("PWD"))
1896 *new_env++ = pwd_var;
1897
1898 if (STRINGP (display))
1899 {
1900 char *vdata = xmalloc (sizeof "DISPLAY=" + SBYTES (display));
1901 record_unwind_protect_ptr (xfree, vdata);
1902 lispstpcpy (stpcpy (vdata, "DISPLAY="), display);
1903 new_env = add_env (env, new_env, vdata);
1904 }
1905
1906
1907 for (tem = Vprocess_environment;
1908 CONSP (tem) && STRINGP (XCAR (tem));
1909 tem = XCDR (tem))
1910 new_env = add_env (env, new_env, SSDATA (XCAR (tem)));
1911
1912 *new_env = 0;
1913
1914
1915 p = q = env;
1916 while (*p != 0)
1917 {
1918 while (*q != 0 && strchr (*q, '=') == NULL)
1919 q++;
1920 *p = *q++;
1921 if (*p != 0)
1922 p++;
1923 }
1924 }
1925
1926 return env;
1927 }
1928
1929
1930
1931
1932 void
1933 init_callproc_1 (void)
1934 {
1935 Vdata_directory = decode_env_path ("EMACSDATA", PATH_DATA, 0);
1936 Vdata_directory = Ffile_name_as_directory (Fcar (Vdata_directory));
1937
1938 Vdoc_directory = decode_env_path ("EMACSDOC", PATH_DOC, 0);
1939 Vdoc_directory = Ffile_name_as_directory (Fcar (Vdoc_directory));
1940
1941
1942
1943 Vexec_path = decode_env_path ("EMACSPATH", PATH_EXEC, 0);
1944 Vexec_directory = Ffile_name_as_directory (Fcar (Vexec_path));
1945
1946 Vexec_path = nconc2 (decode_env_path ("PATH", "", 0), Vexec_path);
1947 }
1948
1949
1950
1951 void
1952 init_callproc (void)
1953 {
1954 bool data_dir = egetenv ("EMACSDATA") != 0;
1955
1956 char *sh;
1957 Lisp_Object tempdir;
1958
1959 if (!NILP (Vinstallation_directory))
1960 {
1961
1962 Lisp_Object tem;
1963 tem = Fexpand_file_name (build_string ("lib-src"),
1964 Vinstallation_directory);
1965 #ifndef MSDOS
1966
1967 if (NILP (Fmember (tem, Vexec_path)))
1968 {
1969
1970 Vexec_path = decode_env_path ("EMACSPATH", SSDATA (tem), 0);
1971 Vexec_path = nconc2 (decode_env_path ("PATH", "", 0), Vexec_path);
1972 }
1973
1974 Vexec_directory = Ffile_name_as_directory (tem);
1975 #endif
1976
1977
1978 if (data_dir == 0)
1979 {
1980 tem = Fexpand_file_name (build_string ("etc"),
1981 Vinstallation_directory);
1982 Vdoc_directory = Ffile_name_as_directory (tem);
1983 }
1984 }
1985
1986
1987
1988
1989
1990
1991
1992
1993 if (data_dir == 0)
1994 {
1995 Lisp_Object tem, srcdir;
1996 Lisp_Object lispdir = Fcar (decode_env_path (0, PATH_DUMPLOADSEARCH, 0));
1997
1998 srcdir = Fexpand_file_name (build_string ("../src/"), lispdir);
1999
2000 tem = Fexpand_file_name (build_string ("NEWS"), Vdata_directory);
2001 if (!NILP (Fequal (srcdir, Vinvocation_directory))
2002 || NILP (Ffile_exists_p (tem)) || !NILP (Vinstallation_directory))
2003 {
2004 Lisp_Object newdir;
2005 newdir = Fexpand_file_name (build_string ("../etc/"), lispdir);
2006 tem = Fexpand_file_name (build_string ("NEWS"), newdir);
2007 if (!NILP (Ffile_exists_p (tem)))
2008 Vdata_directory = newdir;
2009 }
2010 }
2011
2012 if (!will_dump_p ())
2013 {
2014 tempdir = Fdirectory_file_name (Vexec_directory);
2015 if (! file_accessible_directory_p (tempdir))
2016 dir_warning ("arch-dependent data dir", Vexec_directory);
2017 }
2018
2019 tempdir = Fdirectory_file_name (Vdata_directory);
2020 if (! file_accessible_directory_p (tempdir))
2021 dir_warning ("arch-independent data dir", Vdata_directory);
2022
2023 sh = getenv ("SHELL");
2024 #if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
2025
2026 Vshell_file_name = build_string (sh ? sh : "/system/bin/sh");
2027 #else
2028 Vshell_file_name = build_string (sh ? sh : "/bin/sh");
2029 #endif
2030
2031 Lisp_Object gamedir = Qnil;
2032 if (PATH_GAME)
2033 {
2034 const char *cpath_game = PATH_GAME;
2035 #ifdef WINDOWSNT
2036
2037
2038 cpath_game = w32_relocate (cpath_game);
2039 #endif
2040 Lisp_Object path_game = build_unibyte_string (cpath_game);
2041 if (file_accessible_directory_p (path_game))
2042 gamedir = path_game;
2043 else if (errno != ENOENT && errno != ENOTDIR
2044 #ifdef DOS_NT
2045
2046 && errno != EACCES
2047 #endif
2048 )
2049 dir_warning ("game dir", path_game);
2050 }
2051 Vshared_game_score_directory = gamedir;
2052 }
2053
2054 void
2055 set_initial_environment (void)
2056 {
2057 char **envp;
2058 for (envp = environ; *envp; envp++)
2059 Vprocess_environment = Fcons (build_string (*envp),
2060 Vprocess_environment);
2061
2062
2063 Vinitial_environment = Fcopy_sequence (Vprocess_environment);
2064 }
2065
2066 void
2067 syms_of_callproc (void)
2068 {
2069 #ifndef DOS_NT
2070 Vtemp_file_name_pattern = build_string ("emacsXXXXXX");
2071 #else
2072 Vtemp_file_name_pattern = build_string ("emXXXXXX");
2073 #endif
2074 staticpro (&Vtemp_file_name_pattern);
2075
2076 #ifdef MSDOS
2077 synch_process_tempfile = make_fixnum (0);
2078 staticpro (&synch_process_tempfile);
2079 #endif
2080
2081 DEFVAR_LISP ("shell-file-name", Vshell_file_name,
2082 doc:
2083
2084 );
2085
2086 DEFVAR_LISP ("exec-path", Vexec_path,
2087 doc:
2088
2089
2090
2091
2092 );
2093
2094 DEFVAR_LISP ("exec-suffixes", Vexec_suffixes,
2095 doc:
2096 );
2097 Vexec_suffixes = Qnil;
2098
2099 DEFVAR_LISP ("exec-directory", Vexec_directory,
2100 doc:
2101
2102 );
2103
2104 DEFVAR_LISP ("data-directory", Vdata_directory,
2105 doc:
2106 );
2107
2108 DEFVAR_LISP ("doc-directory", Vdoc_directory,
2109 doc:
2110 );
2111
2112 DEFVAR_LISP ("configure-info-directory", Vconfigure_info_directory,
2113 doc:
2114
2115
2116 );
2117 Vconfigure_info_directory = build_string (PATH_INFO);
2118
2119 DEFVAR_LISP ("shared-game-score-directory", Vshared_game_score_directory,
2120 doc:
2121 );
2122
2123 DEFVAR_LISP ("initial-environment", Vinitial_environment,
2124 doc:
2125
2126 );
2127 Vinitial_environment = Qnil;
2128
2129 DEFVAR_LISP ("process-environment", Vprocess_environment,
2130 doc:
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149 );
2150 Vprocess_environment = Qnil;
2151
2152 DEFVAR_LISP ("ctags-program-name", Vctags_program_name,
2153 doc:
2154
2155 );
2156 #if !defined HAVE_ANDROID || defined ANDROID_STUBIFY
2157 Vctags_program_name = build_pure_c_string ("ctags");
2158 #else
2159 Vctags_program_name = build_pure_c_string ("libctags.so");
2160 #endif
2161
2162 DEFVAR_LISP ("etags-program-name", Vetags_program_name,
2163 doc:
2164
2165 );
2166 #if !defined HAVE_ANDROID || defined ANDROID_STUBIFY
2167 Vetags_program_name = build_pure_c_string ("etags");
2168 #else
2169 Vetags_program_name = build_pure_c_string ("libetags.so");
2170 #endif
2171
2172 DEFVAR_LISP ("hexl-program-name", Vhexl_program_name,
2173 doc:
2174
2175 );
2176 #if !defined HAVE_ANDROID || defined ANDROID_STUBIFY
2177 Vhexl_program_name = build_pure_c_string ("hexl");
2178 #else
2179 Vhexl_program_name = build_pure_c_string ("libhexl.so");
2180 #endif
2181
2182 DEFVAR_LISP ("emacsclient-program-name", Vemacsclient_program_name,
2183 doc:
2184
2185
2186 );
2187 #if !defined HAVE_ANDROID || defined ANDROID_STUBIFY
2188 Vemacsclient_program_name = build_pure_c_string ("emacsclient");
2189 #else
2190 Vemacsclient_program_name = build_pure_c_string ("libemacsclient.so");
2191 #endif
2192
2193 DEFVAR_LISP ("movemail-program-name", Vmovemail_program_name,
2194 doc:
2195
2196
2197 );
2198
2199
2200 #if !defined HAVE_ANDROID || defined ANDROID_STUBIFY \
2201 || defined HAVE_MAILUTILS
2202 Vmovemail_program_name = build_pure_c_string ("movemail");
2203 #else
2204 Vmovemail_program_name = build_pure_c_string ("libmovemail.so");
2205 #endif
2206
2207 DEFVAR_LISP ("ebrowse-program-name", Vebrowse_program_name,
2208 doc:
2209
2210
2211 );
2212 #if !defined HAVE_ANDROID || defined ANDROID_STUBIFY
2213 Vebrowse_program_name = build_pure_c_string ("ebrowse");
2214 #else
2215 Vebrowse_program_name = build_pure_c_string ("libebrowse.so");
2216 #endif
2217
2218 defsubr (&Scall_process);
2219 defsubr (&Sgetenv_internal);
2220 defsubr (&Scall_process_region);
2221 }