aboutsummaryrefslogtreecommitdiffstats
path: root/src/callproc.c
diff options
context:
space:
mode:
authorJoakim Verona2013-07-14 11:04:49 +0200
committerJoakim Verona2013-07-14 11:04:49 +0200
commit0bb9bb0841d89fff09820a57369df4cb01b16b43 (patch)
tree832bf9fa8415eef0ce464d22b3ee1300cfa90bb1 /src/callproc.c
parent3718127221fbbc31f8ebd027ab7c95403dbe9118 (diff)
parent3af1c8684ed6e48fbc21481d129e9aa164752c6e (diff)
downloademacs-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.c159
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
191static mode_t const default_output_mode = S_IREAD | S_IWRITE;
192#else
193static mode_t const default_output_mode = 0666;
194#endif
195
189DEFUN ("call-process", Fcall_process, Scall_process, 1, MANY, 0, 196DEFUN ("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.
191The remaining arguments are optional. 198The 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. */
1391static int 1383static int
1392relocate_fd (int fd, int minfd) 1384relocate_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}