aboutsummaryrefslogtreecommitdiffstats
path: root/src/callproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/callproc.c')
-rw-r--r--src/callproc.c104
1 files changed, 65 insertions, 39 deletions
diff --git a/src/callproc.c b/src/callproc.c
index 2a9162cb5cc..d4b4a26ec3a 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -102,7 +102,7 @@ enum
102 CALLPROC_FDS 102 CALLPROC_FDS
103 }; 103 };
104 104
105static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int); 105static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int, ptrdiff_t);
106 106
107/* Block SIGCHLD. */ 107/* Block SIGCHLD. */
108 108
@@ -123,6 +123,37 @@ unblock_child_signal (void)
123 pthread_sigmask (SIG_SETMASK, &empty_mask, 0); 123 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
124} 124}
125 125
126/* Return the current buffer's working directory, or the home
127 directory if it's unreachable, as a string suitable for a system call.
128 Signal an error if the result would not be an accessible directory. */
129
130Lisp_Object
131encode_current_directory (void)
132{
133 Lisp_Object dir;
134 struct gcpro gcpro1;
135
136 dir = BVAR (current_buffer, directory);
137 GCPRO1 (dir);
138
139 dir = Funhandled_file_name_directory (dir);
140
141 /* If the file name handler says that dir is unreachable, use
142 a sensible default. */
143 if (NILP (dir))
144 dir = build_string ("~");
145
146 dir = expand_and_dir_to_file (dir, Qnil);
147
148 if (STRING_MULTIBYTE (dir))
149 dir = ENCODE_FILE (dir);
150 if (! file_accessible_directory_p (SSDATA (dir)))
151 report_file_error ("Setting current directory",
152 BVAR (current_buffer, directory));
153
154 RETURN_UNGCPRO (dir);
155}
156
126/* If P is reapable, record it as a deleted process and kill it. 157/* If P is reapable, record it as a deleted process and kill it.
127 Do this in a critical section. Unless PID is wedged it will be 158 Do this in a critical section. Unless PID is wedged it will be
128 reaped on receipt of the first SIGCHLD after the critical section. */ 159 reaped on receipt of the first SIGCHLD after the critical section. */
@@ -248,14 +279,20 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
248 report_file_error ("Opening process input file", infile); 279 report_file_error ("Opening process input file", infile);
249 record_unwind_protect_int (close_file_unwind, filefd); 280 record_unwind_protect_int (close_file_unwind, filefd);
250 UNGCPRO; 281 UNGCPRO;
251 return unbind_to (count, call_process (nargs, args, filefd)); 282 return unbind_to (count, call_process (nargs, args, filefd, -1));
252} 283}
253 284
254/* Like Fcall_process (NARGS, ARGS), except use FILEFD as the input file. 285/* Like Fcall_process (NARGS, ARGS), except use FILEFD as the input file.
286
287 If TEMPFILE_INDEX is nonnegative, it is the specpdl index of an
288 unwinder that is intended to remove the input temporary file; in
289 this case NARGS must be at least 2 and ARGS[1] is the file's name.
290
255 At entry, the specpdl stack top entry must be close_file_unwind (FILEFD). */ 291 At entry, the specpdl stack top entry must be close_file_unwind (FILEFD). */
256 292
257static Lisp_Object 293static Lisp_Object
258call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd) 294call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
295 ptrdiff_t tempfile_index)
259{ 296{
260 Lisp_Object buffer, current_dir, path; 297 Lisp_Object buffer, current_dir, path;
261 bool display_p; 298 bool display_p;
@@ -402,24 +439,10 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd)
402 { 439 {
403 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 440 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
404 441
405 current_dir = BVAR (current_buffer, directory); 442 current_dir = encode_current_directory ();
406 443
407 GCPRO4 (buffer, current_dir, error_file, output_file); 444 GCPRO4 (buffer, current_dir, error_file, output_file);
408 445
409 current_dir = Funhandled_file_name_directory (current_dir);
410 if (NILP (current_dir))
411 /* If the file name handler says that current_dir is unreachable, use
412 a sensible default. */
413 current_dir = build_string ("~/");
414 current_dir = expand_and_dir_to_file (current_dir, Qnil);
415 current_dir = Ffile_name_as_directory (current_dir);
416
417 if (NILP (Ffile_accessible_directory_p (current_dir)))
418 report_file_error ("Setting current directory",
419 BVAR (current_buffer, directory));
420
421 if (STRING_MULTIBYTE (current_dir))
422 current_dir = ENCODE_FILE (current_dir);
423 if (STRINGP (error_file) && STRING_MULTIBYTE (error_file)) 446 if (STRINGP (error_file) && STRING_MULTIBYTE (error_file))
424 error_file = ENCODE_FILE (error_file); 447 error_file = ENCODE_FILE (error_file);
425 if (STRINGP (output_file) && STRING_MULTIBYTE (output_file)) 448 if (STRINGP (output_file) && STRING_MULTIBYTE (output_file))
@@ -661,7 +684,22 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd)
661 child_errno = errno; 684 child_errno = errno;
662 685
663 if (pid > 0) 686 if (pid > 0)
664 synch_process_pid = pid; 687 {
688 synch_process_pid = pid;
689
690 if (INTEGERP (buffer))
691 {
692 if (tempfile_index < 0)
693 record_deleted_pid (pid, Qnil);
694 else
695 {
696 eassert (1 < nargs);
697 record_deleted_pid (pid, args[1]);
698 clear_unwind_protect (tempfile_index);
699 }
700 synch_process_pid = 0;
701 }
702 }
665 703
666 unblock_child_signal (); 704 unblock_child_signal ();
667 unblock_input (); 705 unblock_input ();
@@ -1030,7 +1068,7 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.
1030usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &rest ARGS) */) 1068usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &rest ARGS) */)
1031 (ptrdiff_t nargs, Lisp_Object *args) 1069 (ptrdiff_t nargs, Lisp_Object *args)
1032{ 1070{
1033 struct gcpro gcpro1, gcpro2; 1071 struct gcpro gcpro1;
1034 Lisp_Object infile, val; 1072 Lisp_Object infile, val;
1035 ptrdiff_t count = SPECPDL_INDEX (); 1073 ptrdiff_t count = SPECPDL_INDEX ();
1036 Lisp_Object start = args[0]; 1074 Lisp_Object start = args[0];
@@ -1061,8 +1099,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
1061 record_unwind_protect_int (close_file_unwind, fd); 1099 record_unwind_protect_int (close_file_unwind, fd);
1062 } 1100 }
1063 1101
1064 val = infile; 1102 GCPRO1 (infile);
1065 GCPRO2 (infile, val);
1066 1103
1067 if (nargs > 3 && !NILP (args[3])) 1104 if (nargs > 3 && !NILP (args[3]))
1068 Fdelete_region (start, end); 1105 Fdelete_region (start, end);
@@ -1079,16 +1116,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
1079 } 1116 }
1080 args[1] = infile; 1117 args[1] = infile;
1081 1118
1082 val = call_process (nargs, args, fd); 1119 val = call_process (nargs, args, fd, empty_input ? -1 : count);
1083
1084 if (!empty_input && 4 < nargs
1085 && (INTEGERP (CONSP (args[4]) ? XCAR (args[4]) : args[4])))
1086 {
1087 record_deleted_pid (synch_process_pid, infile);
1088 synch_process_pid = 0;
1089 clear_unwind_protect (count);
1090 }
1091
1092 RETURN_UNGCPRO (unbind_to (count, val)); 1120 RETURN_UNGCPRO (unbind_to (count, val));
1093} 1121}
1094 1122
@@ -1165,23 +1193,21 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1165 static variables as if the superior had done alloca and will be 1193 static variables as if the superior had done alloca and will be
1166 cleaned up in the usual way. */ 1194 cleaned up in the usual way. */
1167 { 1195 {
1168 register char *temp; 1196 char *temp;
1169 size_t i; /* size_t, because ptrdiff_t might overflow here! */ 1197 ptrdiff_t i;
1170 1198
1171 i = SBYTES (current_dir); 1199 i = SBYTES (current_dir);
1172#ifdef MSDOS 1200#ifdef MSDOS
1173 /* MSDOS must have all environment variables malloc'ed, because 1201 /* MSDOS must have all environment variables malloc'ed, because
1174 low-level libc functions that launch subsidiary processes rely 1202 low-level libc functions that launch subsidiary processes rely
1175 on that. */ 1203 on that. */
1176 pwd_var = xmalloc (i + 6); 1204 pwd_var = xmalloc (i + 5);
1177#else 1205#else
1178 pwd_var = alloca (i + 6); 1206 pwd_var = alloca (i + 5);
1179#endif 1207#endif
1180 temp = pwd_var + 4; 1208 temp = pwd_var + 4;
1181 memcpy (pwd_var, "PWD=", 4); 1209 memcpy (pwd_var, "PWD=", 4);
1182 memcpy (temp, SDATA (current_dir), i); 1210 strcpy (temp, SSDATA (current_dir));
1183 if (!IS_DIRECTORY_SEP (temp[i - 1])) temp[i++] = DIRECTORY_SEP;
1184 temp[i] = 0;
1185 1211
1186#ifndef DOS_NT 1212#ifndef DOS_NT
1187 /* We can't signal an Elisp error here; we're in a vfork. Since 1213 /* We can't signal an Elisp error here; we're in a vfork. Since