diff options
| author | Joakim Verona | 2013-07-14 11:04:49 +0200 |
|---|---|---|
| committer | Joakim Verona | 2013-07-14 11:04:49 +0200 |
| commit | 0bb9bb0841d89fff09820a57369df4cb01b16b43 (patch) | |
| tree | 832bf9fa8415eef0ce464d22b3ee1300cfa90bb1 /src/callproc.c | |
| parent | 3718127221fbbc31f8ebd027ab7c95403dbe9118 (diff) | |
| parent | 3af1c8684ed6e48fbc21481d129e9aa164752c6e (diff) | |
| download | emacs-0bb9bb0841d89fff09820a57369df4cb01b16b43.tar.gz emacs-0bb9bb0841d89fff09820a57369df4cb01b16b43.zip | |
Merge branch 'trunk' into xwidget
Conflicts:
src/xdisp.c
Diffstat (limited to 'src/callproc.c')
| -rw-r--r-- | src/callproc.c | 159 |
1 files changed, 74 insertions, 85 deletions
diff --git a/src/callproc.c b/src/callproc.c index f0aa8222342..cdf92422b4d 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -31,6 +31,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 31 | 31 | ||
| 32 | #ifdef WINDOWSNT | 32 | #ifdef WINDOWSNT |
| 33 | #define NOMINMAX | 33 | #define NOMINMAX |
| 34 | #include <sys/socket.h> /* for fcntl */ | ||
| 34 | #include <windows.h> | 35 | #include <windows.h> |
| 35 | #include "w32.h" | 36 | #include "w32.h" |
| 36 | #define _P_NOWAIT 1 /* from process.h */ | 37 | #define _P_NOWAIT 1 /* from process.h */ |
| @@ -186,6 +187,12 @@ call_process_cleanup (Lisp_Object arg) | |||
| 186 | return Qnil; | 187 | return Qnil; |
| 187 | } | 188 | } |
| 188 | 189 | ||
| 190 | #ifdef DOS_NT | ||
| 191 | static mode_t const default_output_mode = S_IREAD | S_IWRITE; | ||
| 192 | #else | ||
| 193 | static mode_t const default_output_mode = 0666; | ||
| 194 | #endif | ||
| 195 | |||
| 189 | DEFUN ("call-process", Fcall_process, Scall_process, 1, MANY, 0, | 196 | DEFUN ("call-process", Fcall_process, Scall_process, 1, MANY, 0, |
| 190 | doc: /* Call PROGRAM synchronously in separate process. | 197 | doc: /* Call PROGRAM synchronously in separate process. |
| 191 | The remaining arguments are optional. | 198 | The remaining arguments are optional. |
| @@ -407,18 +414,15 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 407 | 414 | ||
| 408 | if (STRINGP (output_file)) | 415 | if (STRINGP (output_file)) |
| 409 | { | 416 | { |
| 410 | #ifdef DOS_NT | ||
| 411 | fd_output = emacs_open (SSDATA (output_file), | 417 | fd_output = emacs_open (SSDATA (output_file), |
| 412 | O_WRONLY | O_TRUNC | O_CREAT | O_TEXT, | 418 | O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, |
| 413 | S_IREAD | S_IWRITE); | 419 | default_output_mode); |
| 414 | #else /* not DOS_NT */ | ||
| 415 | fd_output = creat (SSDATA (output_file), 0666); | ||
| 416 | #endif /* not DOS_NT */ | ||
| 417 | if (fd_output < 0) | 420 | if (fd_output < 0) |
| 418 | { | 421 | { |
| 422 | int open_errno = errno; | ||
| 419 | output_file = DECODE_FILE (output_file); | 423 | output_file = DECODE_FILE (output_file); |
| 420 | report_file_error ("Opening process output file", | 424 | report_file_errno ("Opening process output file", |
| 421 | Fcons (output_file, Qnil)); | 425 | Fcons (output_file, Qnil), open_errno); |
| 422 | } | 426 | } |
| 423 | if (STRINGP (error_file) || NILP (error_file)) | 427 | if (STRINGP (error_file) || NILP (error_file)) |
| 424 | output_to_buffer = 0; | 428 | output_to_buffer = 0; |
| @@ -427,16 +431,19 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 427 | /* Search for program; barf if not found. */ | 431 | /* Search for program; barf if not found. */ |
| 428 | { | 432 | { |
| 429 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 433 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 434 | int ok; | ||
| 430 | 435 | ||
| 431 | GCPRO4 (infile, buffer, current_dir, error_file); | 436 | GCPRO4 (infile, buffer, current_dir, error_file); |
| 432 | openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK)); | 437 | ok = openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK)); |
| 433 | UNGCPRO; | 438 | UNGCPRO; |
| 439 | if (ok < 0) | ||
| 440 | { | ||
| 441 | int openp_errno = errno; | ||
| 442 | emacs_close (filefd); | ||
| 443 | report_file_errno ("Searching for program", | ||
| 444 | Fcons (args[0], Qnil), openp_errno); | ||
| 445 | } | ||
| 434 | } | 446 | } |
| 435 | if (NILP (path)) | ||
| 436 | { | ||
| 437 | emacs_close (filefd); | ||
| 438 | report_file_error ("Searching for program", Fcons (args[0], Qnil)); | ||
| 439 | } | ||
| 440 | 447 | ||
| 441 | /* If program file name starts with /: for quoting a magic name, | 448 | /* If program file name starts with /: for quoting a magic name, |
| 442 | discard that. */ | 449 | discard that. */ |
| @@ -492,12 +499,15 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 492 | strcat (tempfile, "/"); | 499 | strcat (tempfile, "/"); |
| 493 | strcat (tempfile, "detmp.XXX"); | 500 | strcat (tempfile, "detmp.XXX"); |
| 494 | mktemp (tempfile); | 501 | mktemp (tempfile); |
| 495 | outfilefd = creat (tempfile, S_IREAD | S_IWRITE); | 502 | outfilefd = emacs_open (tempfile, O_WRONLY | O_CREAT | O_TRUNC, |
| 496 | if (outfilefd < 0) { | 503 | S_IREAD | S_IWRITE); |
| 497 | emacs_close (filefd); | 504 | if (outfilefd < 0) |
| 498 | report_file_error ("Opening process output file", | 505 | { |
| 499 | Fcons (build_string (tempfile), Qnil)); | 506 | int open_errno = errno; |
| 500 | } | 507 | emacs_close (filefd); |
| 508 | report_file_errno ("Opening process output file", | ||
| 509 | Fcons (build_string (tempfile), Qnil), open_errno); | ||
| 510 | } | ||
| 501 | } | 511 | } |
| 502 | else | 512 | else |
| 503 | outfilefd = fd_output; | 513 | outfilefd = fd_output; |
| @@ -514,12 +524,11 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 514 | { | 524 | { |
| 515 | #ifndef MSDOS | 525 | #ifndef MSDOS |
| 516 | int fd[2]; | 526 | int fd[2]; |
| 517 | if (pipe (fd) == -1) | 527 | if (pipe2 (fd, O_CLOEXEC) != 0) |
| 518 | { | 528 | { |
| 519 | int pipe_errno = errno; | 529 | int pipe_errno = errno; |
| 520 | emacs_close (filefd); | 530 | emacs_close (filefd); |
| 521 | errno = pipe_errno; | 531 | report_file_errno ("Creating process pipe", Qnil, pipe_errno); |
| 522 | report_file_error ("Creating process pipe", Qnil); | ||
| 523 | } | 532 | } |
| 524 | fd0 = fd[0]; | 533 | fd0 = fd[0]; |
| 525 | fd1 = fd[1]; | 534 | fd1 = fd[1]; |
| @@ -535,18 +544,13 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 535 | if (NILP (error_file)) | 544 | if (NILP (error_file)) |
| 536 | fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0); | 545 | fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0); |
| 537 | else if (STRINGP (error_file)) | 546 | else if (STRINGP (error_file)) |
| 538 | { | 547 | fd_error = emacs_open (SSDATA (error_file), |
| 539 | #ifdef DOS_NT | 548 | O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, |
| 540 | fd_error = emacs_open (SSDATA (error_file), | 549 | default_output_mode); |
| 541 | O_WRONLY | O_TRUNC | O_CREAT | O_TEXT, | ||
| 542 | S_IREAD | S_IWRITE); | ||
| 543 | #else /* not DOS_NT */ | ||
| 544 | fd_error = creat (SSDATA (error_file), 0666); | ||
| 545 | #endif /* not DOS_NT */ | ||
| 546 | } | ||
| 547 | 550 | ||
| 548 | if (fd_error < 0) | 551 | if (fd_error < 0) |
| 549 | { | 552 | { |
| 553 | int open_errno = errno; | ||
| 550 | emacs_close (filefd); | 554 | emacs_close (filefd); |
| 551 | if (fd0 != filefd) | 555 | if (fd0 != filefd) |
| 552 | emacs_close (fd0); | 556 | emacs_close (fd0); |
| @@ -559,7 +563,8 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 559 | error_file = build_string (NULL_DEVICE); | 563 | error_file = build_string (NULL_DEVICE); |
| 560 | else if (STRINGP (error_file)) | 564 | else if (STRINGP (error_file)) |
| 561 | error_file = DECODE_FILE (error_file); | 565 | error_file = DECODE_FILE (error_file); |
| 562 | report_file_error ("Cannot redirect stderr", Fcons (error_file, Qnil)); | 566 | report_file_errno ("Cannot redirect stderr", |
| 567 | Fcons (error_file, Qnil), open_errno); | ||
| 563 | } | 568 | } |
| 564 | 569 | ||
| 565 | #ifdef MSDOS /* MW, July 1993 */ | 570 | #ifdef MSDOS /* MW, July 1993 */ |
| @@ -587,10 +592,12 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 587 | fd0 = emacs_open (tempfile, O_RDONLY | O_BINARY, 0); | 592 | fd0 = emacs_open (tempfile, O_RDONLY | O_BINARY, 0); |
| 588 | if (fd0 < 0) | 593 | if (fd0 < 0) |
| 589 | { | 594 | { |
| 595 | int open_errno = errno; | ||
| 590 | unlink (tempfile); | 596 | unlink (tempfile); |
| 591 | emacs_close (filefd); | 597 | emacs_close (filefd); |
| 592 | report_file_error ("Cannot re-open temporary file", | 598 | report_file_errno ("Cannot re-open temporary file", |
| 593 | Fcons (build_string (tempfile), Qnil)); | 599 | Fcons (build_string (tempfile), Qnil), |
| 600 | open_errno); | ||
| 594 | } | 601 | } |
| 595 | } | 602 | } |
| 596 | else | 603 | else |
| @@ -708,10 +715,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 708 | } | 715 | } |
| 709 | 716 | ||
| 710 | if (pid < 0) | 717 | if (pid < 0) |
| 711 | { | 718 | report_file_errno ("Doing vfork", Qnil, child_errno); |
| 712 | errno = child_errno; | ||
| 713 | report_file_error ("Doing vfork", Qnil); | ||
| 714 | } | ||
| 715 | 719 | ||
| 716 | if (INTEGERP (buffer)) | 720 | if (INTEGERP (buffer)) |
| 717 | return unbind_to (count, Qnil); | 721 | return unbind_to (count, Qnil); |
| @@ -1037,29 +1041,29 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 1037 | memcpy (tempfile, SDATA (encoded_tem), SBYTES (encoded_tem) + 1); | 1041 | memcpy (tempfile, SDATA (encoded_tem), SBYTES (encoded_tem) + 1); |
| 1038 | coding_systems = Qt; | 1042 | coding_systems = Qt; |
| 1039 | 1043 | ||
| 1040 | #ifdef HAVE_MKSTEMP | 1044 | #if defined HAVE_MKOSTEMP || defined HAVE_MKSTEMP |
| 1041 | { | 1045 | { |
| 1042 | int fd; | 1046 | int fd, open_errno; |
| 1043 | 1047 | ||
| 1044 | block_input (); | 1048 | block_input (); |
| 1049 | # ifdef HAVE_MKOSTEMP | ||
| 1050 | fd = mkostemp (tempfile, O_CLOEXEC); | ||
| 1051 | # else | ||
| 1045 | fd = mkstemp (tempfile); | 1052 | fd = mkstemp (tempfile); |
| 1053 | # endif | ||
| 1054 | open_errno = errno; | ||
| 1046 | unblock_input (); | 1055 | unblock_input (); |
| 1047 | if (fd == -1) | 1056 | if (fd < 0) |
| 1048 | report_file_error ("Failed to open temporary file", | 1057 | report_file_errno ("Failed to open temporary file", |
| 1049 | Fcons (build_string (tempfile), Qnil)); | 1058 | Fcons (build_string (tempfile), Qnil), open_errno); |
| 1050 | else | 1059 | emacs_close (fd); |
| 1051 | close (fd); | ||
| 1052 | } | 1060 | } |
| 1053 | #else | 1061 | #else |
| 1054 | errno = 0; | 1062 | errno = EEXIST; |
| 1055 | mktemp (tempfile); | 1063 | mktemp (tempfile); |
| 1056 | if (!*tempfile) | 1064 | if (!*tempfile) |
| 1057 | { | 1065 | report_file_error ("Failed to open temporary file using pattern", |
| 1058 | if (!errno) | 1066 | Fcons (pattern, Qnil)); |
| 1059 | errno = EEXIST; | ||
| 1060 | report_file_error ("Failed to open temporary file using pattern", | ||
| 1061 | Fcons (pattern, Qnil)); | ||
| 1062 | } | ||
| 1063 | #endif | 1067 | #endif |
| 1064 | 1068 | ||
| 1065 | filename_string = build_string (tempfile); | 1069 | filename_string = build_string (tempfile); |
| @@ -1185,15 +1189,6 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1185 | 1189 | ||
| 1186 | pid_t pid = getpid (); | 1190 | pid_t pid = getpid (); |
| 1187 | 1191 | ||
| 1188 | /* Close Emacs's descriptors that this process should not have. */ | ||
| 1189 | close_process_descs (); | ||
| 1190 | |||
| 1191 | /* DOS_NT isn't in a vfork, so if we are in the middle of load-file, | ||
| 1192 | we will lose if we call close_load_descs here. */ | ||
| 1193 | #ifndef DOS_NT | ||
| 1194 | close_load_descs (); | ||
| 1195 | #endif | ||
| 1196 | |||
| 1197 | /* Note that use of alloca is always safe here. It's obvious for systems | 1192 | /* Note that use of alloca is always safe here. It's obvious for systems |
| 1198 | that do not have true vfork or that have true (stack) alloca. | 1193 | that do not have true vfork or that have true (stack) alloca. |
| 1199 | If using vfork and C_ALLOCA (when Emacs used to include | 1194 | If using vfork and C_ALLOCA (when Emacs used to include |
| @@ -1226,7 +1221,7 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1226 | are changed between the check and this chdir, but we should | 1221 | are changed between the check and this chdir, but we should |
| 1227 | at least check. */ | 1222 | at least check. */ |
| 1228 | if (chdir (temp) < 0) | 1223 | if (chdir (temp) < 0) |
| 1229 | _exit (errno); | 1224 | _exit (EXIT_CANCELED); |
| 1230 | #else /* DOS_NT */ | 1225 | #else /* DOS_NT */ |
| 1231 | /* Get past the drive letter, so that d:/ is left alone. */ | 1226 | /* Get past the drive letter, so that d:/ is left alone. */ |
| 1232 | if (i > 2 && IS_DEVICE_SEP (temp[1]) && IS_DIRECTORY_SEP (temp[2])) | 1227 | if (i > 2 && IS_DEVICE_SEP (temp[1]) && IS_DIRECTORY_SEP (temp[2])) |
| @@ -1351,28 +1346,24 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1351 | } | 1346 | } |
| 1352 | 1347 | ||
| 1353 | #ifndef MSDOS | 1348 | #ifndef MSDOS |
| 1354 | emacs_close (0); | 1349 | /* Redirect file descriptors and clear the close-on-exec flag on the |
| 1355 | emacs_close (1); | 1350 | redirected ones. IN, OUT, and ERR are close-on-exec so they |
| 1356 | emacs_close (2); | 1351 | need not be closed explicitly. */ |
| 1357 | |||
| 1358 | dup2 (in, 0); | 1352 | dup2 (in, 0); |
| 1359 | dup2 (out, 1); | 1353 | dup2 (out, 1); |
| 1360 | dup2 (err, 2); | 1354 | dup2 (err, 2); |
| 1361 | emacs_close (in); | ||
| 1362 | if (out != in) | ||
| 1363 | emacs_close (out); | ||
| 1364 | if (err != in && err != out) | ||
| 1365 | emacs_close (err); | ||
| 1366 | 1355 | ||
| 1367 | setpgid (0, 0); | 1356 | setpgid (0, 0); |
| 1368 | tcsetpgrp (0, pid); | 1357 | tcsetpgrp (0, pid); |
| 1369 | 1358 | ||
| 1370 | execve (new_argv[0], new_argv, env); | 1359 | execve (new_argv[0], new_argv, env); |
| 1371 | 1360 | ||
| 1372 | emacs_write (1, "Can't exec program: ", 20); | 1361 | /* Don't output the program name here, as it can be arbitrarily long, |
| 1373 | emacs_write (1, new_argv[0], strlen (new_argv[0])); | 1362 | and a long write from a vforked child to its parent can cause a |
| 1374 | emacs_write (1, "\n", 1); | 1363 | deadlock. */ |
| 1375 | _exit (1); | 1364 | emacs_perror ("child process"); |
| 1365 | |||
| 1366 | _exit (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE); | ||
| 1376 | 1367 | ||
| 1377 | #else /* MSDOS */ | 1368 | #else /* MSDOS */ |
| 1378 | pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env); | 1369 | pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env); |
| @@ -1387,7 +1378,8 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1387 | 1378 | ||
| 1388 | #ifndef WINDOWSNT | 1379 | #ifndef WINDOWSNT |
| 1389 | /* Move the file descriptor FD so that its number is not less than MINFD. | 1380 | /* Move the file descriptor FD so that its number is not less than MINFD. |
| 1390 | If the file descriptor is moved at all, the original is freed. */ | 1381 | If the file descriptor is moved at all, the original is closed on MSDOS, |
| 1382 | but not elsewhere as the caller will close it anyway. */ | ||
| 1391 | static int | 1383 | static int |
| 1392 | relocate_fd (int fd, int minfd) | 1384 | relocate_fd (int fd, int minfd) |
| 1393 | { | 1385 | { |
| @@ -1395,18 +1387,15 @@ relocate_fd (int fd, int minfd) | |||
| 1395 | return fd; | 1387 | return fd; |
| 1396 | else | 1388 | else |
| 1397 | { | 1389 | { |
| 1398 | int new = fcntl (fd, F_DUPFD, minfd); | 1390 | int new = fcntl (fd, F_DUPFD_CLOEXEC, minfd); |
| 1399 | if (new == -1) | 1391 | if (new == -1) |
| 1400 | { | 1392 | { |
| 1401 | const char *message_1 = "Error while setting up child: "; | 1393 | emacs_perror ("while setting up child"); |
| 1402 | const char *errmessage = strerror (errno); | 1394 | _exit (EXIT_CANCELED); |
| 1403 | const char *message_2 = "\n"; | ||
| 1404 | emacs_write (2, message_1, strlen (message_1)); | ||
| 1405 | emacs_write (2, errmessage, strlen (errmessage)); | ||
| 1406 | emacs_write (2, message_2, strlen (message_2)); | ||
| 1407 | _exit (1); | ||
| 1408 | } | 1395 | } |
| 1396 | #ifdef MSDOS | ||
| 1409 | emacs_close (fd); | 1397 | emacs_close (fd); |
| 1398 | #endif | ||
| 1410 | return new; | 1399 | return new; |
| 1411 | } | 1400 | } |
| 1412 | } | 1401 | } |