comparison src/callproc.c @ 263:727739f917cb r20-5b30

Import from CVS: tag r20-5b30
author cvs
date Mon, 13 Aug 2007 10:24:41 +0200
parents 11cf20601dec
children 966663fcf606
comparison
equal deleted inserted replaced
262:9d8607af9e13 263:727739f917cb
110 } 110 }
111 111
112 static Lisp_Object 112 static Lisp_Object
113 call_process_cleanup (Lisp_Object fdpid) 113 call_process_cleanup (Lisp_Object fdpid)
114 { 114 {
115 #ifdef MSDOS
116 /* for MSDOS fdpid is really (fd . tempfile) */
117 Lisp_Object file = Fcdr (fdpid);
118 close (XINT (Fcar (fdpid)));
119 if (strcmp (XSTRING_DATA (file), NULL_DEVICE) != 0)
120 unlink (XSTRING_DATA (file));
121 #else /* not MSDOS */
122 int fd = XINT (Fcar (fdpid)); 115 int fd = XINT (Fcar (fdpid));
123 int pid = XINT (Fcdr (fdpid)); 116 int pid = XINT (Fcdr (fdpid));
124 117
125 if (!call_process_exited && 118 if (!call_process_exited &&
126 EMACS_KILLPG (pid, SIGINT) == 0) 119 EMACS_KILLPG (pid, SIGINT) == 0)
140 133
141 message ("Waiting for process to die... done"); 134 message ("Waiting for process to die... done");
142 } 135 }
143 synch_process_alive = 0; 136 synch_process_alive = 0;
144 close (fd); 137 close (fd);
145 #endif /* not MSDOS */
146 return Qnil; 138 return Qnil;
147 } 139 }
148 140
149 static Lisp_Object fork_error; 141 static Lisp_Object fork_error;
150 #if 0 /* UNUSED */ 142 #if 0 /* UNUSED */
197 char **new_argv = alloca_array (char *, max (2, nargs - 2)); 189 char **new_argv = alloca_array (char *, max (2, nargs - 2));
198 190
199 /* File to use for stderr in the child. 191 /* File to use for stderr in the child.
200 t means use same as standard output. */ 192 t means use same as standard output. */
201 Lisp_Object error_file; 193 Lisp_Object error_file;
202 #ifdef MSDOS
203 char *outf, *tempfile;
204 int outfilefd;
205 #endif /* MSDOS */
206 194
207 CHECK_STRING (args[0]); 195 CHECK_STRING (args[0]);
208 196
209 error_file = Qt; 197 error_file = Qt;
210 198
318 306
319 filefd = open ((char *) XSTRING_DATA (infile), O_RDONLY | OPEN_BINARY, 0); 307 filefd = open ((char *) XSTRING_DATA (infile), O_RDONLY | OPEN_BINARY, 0);
320 if (filefd < 0) 308 if (filefd < 0)
321 report_file_error ("Opening process input file", Fcons (infile, Qnil)); 309 report_file_error ("Opening process input file", Fcons (infile, Qnil));
322 310
323 #ifdef MSDOS
324 /* These vars record information from process termination.
325 Clear them now before process can possibly terminate,
326 to avoid timing error if process terminates soon. */
327 synch_process_death = 0;
328 synch_process_retcode = 0;
329
330 if ((outf = egetenv ("TMP")) || (outf = egetenv ("TEMP")))
331 strcpy (tempfile = alloca (strlen (outf) + 20), outf);
332 else
333 {
334 tempfile = alloca (20);
335 *tempfile = '\0';
336 }
337 dostounix_filename (tempfile);
338 if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/')
339 strcat (tempfile, "/");
340 strcat (tempfile, "detmp.XXX");
341 mktemp (tempfile);
342
343 outfilefd = creat (tempfile, S_IREAD | S_IWRITE);
344 if (outfilefd < 0)
345 {
346 close (filefd);
347 report_file_error ("Opening process output file",
348 Fcons (tempfile, Qnil));
349 }
350 #endif /* MSDOS */
351
352 #ifndef MSDOS
353 if (INTP (buffer)) 311 if (INTP (buffer))
354 { 312 {
355 fd[1] = open (NULL_DEVICE, O_WRONLY | OPEN_BINARY, 0); 313 fd[1] = open (NULL_DEVICE, O_WRONLY | OPEN_BINARY, 0);
356 fd[0] = -1; 314 fd[0] = -1;
357 } 315 }
361 #if 0 319 #if 0
362 /* Replaced by close_process_descs */ 320 /* Replaced by close_process_descs */
363 set_exclusive_use (fd[0]); 321 set_exclusive_use (fd[0]);
364 #endif 322 #endif
365 } 323 }
366 #else /* MSDOS */ 324
367 { 325 {
368 char *outf; 326 /* child_setup must clobber environ in systems with true vfork.
369
370 if (INTP (buffer))
371 outf = NULL_DEVICE;
372 else
373 {
374 /* DOS can't create pipe for interprocess communication,
375 so redirect child process's standard output to temporary file
376 and later read the file. */
377
378 if ((outf = egetenv ("TMP")) || (outf = egetenv ("TEMP")))
379 {
380 strcpy (tempfile, outf);
381 dostounix_filename (tempfile);
382 }
383 else
384 *tempfile = '\0';
385 if (strlen (tempfile) == 0 || tempfile[strlen (tempfile) - 1] != '/')
386 strcat (tempfile, "/");
387 strcat (tempfile, "demacs.XXX");
388 mktemp (tempfile);
389 outf = tempfile;
390 }
391
392 if ((fd[1] = creat (outf, S_IREAD | S_IWRITE)) < 0)
393 report_file_error ("Can't open temporary file", Qnil);
394 fd[0] = -1;
395 }
396 #endif /* MSDOS */
397
398 {
399 /* child_setup must clobber environ in systems with true vfork.
400 Protect it from permanent change. */ 327 Protect it from permanent change. */
401 REGISTER char **save_environ = environ; 328 REGISTER char **save_environ = environ;
402 REGISTER int fd1 = fd[1]; 329 REGISTER int fd1 = fd[1];
403 int fd_error = fd1; 330 int fd_error = fd1;
404 char **env; 331 char **env;
420 Clear them now before process can possibly terminate, 347 Clear them now before process can possibly terminate,
421 to avoid timing error if process terminates soon. */ 348 to avoid timing error if process terminates soon. */
422 synch_process_death = 0; 349 synch_process_death = 0;
423 synch_process_retcode = 0; 350 synch_process_retcode = 0;
424 351
425 #ifdef MSDOS
426 /* ??? Someone who knows MSDOG needs to check whether this properly
427 closes all descriptors that it opens. */
428 pid = run_msdos_command (new_argv, current_dir, filefd, outfilefd);
429 close (outfilefd);
430 fd1 = -1; /* No harm in closing that one! */
431 fd[0] = open (tempfile, NILP (Vbinary_process_output) ? O_TEXT :
432 O_BINARY);
433 if (fd[0] < 0)
434 {
435 unlink (tempfile);
436 close (filefd);
437 report_file_error ("Cannot re-open temporary file", Qnil);
438 }
439 #else /* not MSDOS */
440 if (NILP (error_file)) 352 if (NILP (error_file))
441 fd_error = open (NULL_DEVICE, O_WRONLY | OPEN_BINARY); 353 fd_error = open (NULL_DEVICE, O_WRONLY | OPEN_BINARY);
442 else if (STRINGP (error_file)) 354 else if (STRINGP (error_file))
443 { 355 {
444 #ifdef DOS_NT 356 #ifdef DOS_NT
488 cadillac_start_logging (); 400 cadillac_start_logging ();
489 #endif 401 #endif
490 if (fd_error >= 0) 402 if (fd_error >= 0)
491 close (fd_error); 403 close (fd_error);
492 404
493 #endif /* not MSDOS */
494 #endif /* not WINDOWSNT */ 405 #endif /* not WINDOWSNT */
495 406
496 environ = save_environ; 407 environ = save_environ;
497 408
498 /* Close most of our fd's, but not fd[0] 409 /* Close most of our fd's, but not fd[0]
533 struct gcpro ngcpro1; 444 struct gcpro ngcpro1;
534 445
535 /* Enable sending signal if user quits below. */ 446 /* Enable sending signal if user quits below. */
536 call_process_exited = 0; 447 call_process_exited = 0;
537 448
538 #ifdef MSDOS
539 /* MSDOS needs different cleanup information. */
540 record_unwind_protect (call_process_cleanup,
541 Fcons (make_int (fd[0]),
542 build_string (tempfile)));
543 #else /* not MSDOS */
544 record_unwind_protect (call_process_cleanup, 449 record_unwind_protect (call_process_cleanup,
545 Fcons (make_int (fd[0]), make_int (pid))); 450 Fcons (make_int (fd[0]), make_int (pid)));
546 #endif /* not MSDOS */
547 451
548 /* FSFmacs calls Fset_buffer() here. We don't have to because 452 /* FSFmacs calls Fset_buffer() here. We don't have to because
549 we can insert into buffers other than the current one. */ 453 we can insert into buffers other than the current one. */
550 if (EQ (buffer, Qt)) 454 if (EQ (buffer, Qt))
551 XSETBUFFER (buffer, current_buffer); 455 XSETBUFFER (buffer, current_buffer);
622 give_up: 526 give_up:
623 Lstream_close (XLSTREAM (instream)); 527 Lstream_close (XLSTREAM (instream));
624 NUNGCPRO; 528 NUNGCPRO;
625 529
626 QUIT; 530 QUIT;
627 #ifndef MSDOS
628 /* Wait for it to terminate, unless it already has. */ 531 /* Wait for it to terminate, unless it already has. */
629 wait_for_termination (pid); 532 wait_for_termination (pid);
630 #endif
631 533
632 /* Don't kill any children that the subprocess may have left behind 534 /* Don't kill any children that the subprocess may have left behind
633 when exiting. */ 535 when exiting. */
634 call_process_exited = 1; 536 call_process_exited = 1;
635 unbind_to (speccount, Qnil); 537 unbind_to (speccount, Qnil);
670 void 572 void
671 #endif 573 #endif
672 child_setup (int in, int out, int err, char **new_argv, 574 child_setup (int in, int out, int err, char **new_argv,
673 CONST char *current_dir) 575 CONST char *current_dir)
674 { 576 {
675 #ifdef MSDOS
676 /* The MSDOS port of gcc cannot fork, vfork, ... so we must call system
677 instead. */
678 #else /* not MSDOS */
679 char **env; 577 char **env;
680 char *pwd; 578 char *pwd;
681 #ifdef WINDOWSNT 579 #ifdef WINDOWSNT
682 int cpid; 580 int cpid;
683 HANDLE handles[4]; 581 HANDLE handles[4];
686 #ifdef SET_EMACS_PRIORITY 584 #ifdef SET_EMACS_PRIORITY
687 if (emacs_priority != 0) 585 if (emacs_priority != 0)
688 nice (- emacs_priority); 586 nice (- emacs_priority);
689 #endif 587 #endif
690 588
691 #if !defined (NO_SUBPROCESSES) 589 #if !defined (NO_SUBPROCESSES) && !defined (WINDOWSNT)
692 /* Close Emacs's descriptors that this process should not have. */ 590 /* Close Emacs's descriptors that this process should not have. */
693 close_process_descs (); 591 close_process_descs ();
694 #endif /* not NO_SUBPROCESSES */ 592 #endif /* not NO_SUBPROCESSES */
695 close_load_descs (); 593 close_load_descs ();
696 594
858 execvp (new_argv[0], new_argv); 756 execvp (new_argv[0], new_argv);
859 757
860 stdout_out ("Cant't exec program %s\n", new_argv[0]); 758 stdout_out ("Cant't exec program %s\n", new_argv[0]);
861 _exit (1); 759 _exit (1);
862 #endif /* not WINDOWSNT */ 760 #endif /* not WINDOWSNT */
863 #endif /* not MSDOS */
864 } 761 }
865 762
866 /* Move the file descriptor FD so that its number is not less than MIN. 763 /* Move the file descriptor FD so that its number is not less than MIN.
867 If the file descriptor is moved at all, the original is freed. */ 764 If the file descriptor is moved at all, the original is freed. */
868 static int 765 static int