diff options
| author | Tom Tromey | 2013-08-25 14:25:59 -0600 |
|---|---|---|
| committer | Tom Tromey | 2013-08-25 14:25:59 -0600 |
| commit | 793ea5055aea85ff9227e1bf0c84ab37edba7201 (patch) | |
| tree | c9799eebe2b797a55fcbfcbd3710c9b5aa70051d /src/callproc.c | |
| parent | 1ce4c6398ea453a66f6943552b0ec866a690e9b1 (diff) | |
| parent | e687aa335a21662f67d2d73063272504a171ffab (diff) | |
| download | emacs-793ea5055aea85ff9227e1bf0c84ab37edba7201.tar.gz emacs-793ea5055aea85ff9227e1bf0c84ab37edba7201.zip | |
merge from trunk
Diffstat (limited to 'src/callproc.c')
| -rw-r--r-- | src/callproc.c | 104 |
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 | ||
| 105 | static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int); | 105 | static 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 | |||
| 130 | Lisp_Object | ||
| 131 | encode_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 | ||
| 257 | static Lisp_Object | 293 | static Lisp_Object |
| 258 | call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd) | 294 | call_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. | |||
| 1030 | usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &rest ARGS) */) | 1068 | usage: (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 |