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