aboutsummaryrefslogtreecommitdiffstats
path: root/src/callproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/callproc.c')
-rw-r--r--src/callproc.c601
1 files changed, 354 insertions, 247 deletions
diff --git a/src/callproc.c b/src/callproc.c
index 09d0ca5b42c..d6bad2a44e7 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -1,6 +1,6 @@
1/* Synchronous subprocess invocation for GNU Emacs. 1/* Synchronous subprocess invocation for GNU Emacs.
2 Copyright (C) 1985-1988, 1993-1995, 1999-2011 2 Copyright (C) 1985-1988, 1993-1995, 1999-2011
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
6 6
@@ -29,6 +29,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
29#include <sys/file.h> 29#include <sys/file.h>
30#include <fcntl.h> 30#include <fcntl.h>
31 31
32#include "lisp.h"
33
32#ifdef WINDOWSNT 34#ifdef WINDOWSNT
33#define NOMINMAX 35#define NOMINMAX
34#include <windows.h> 36#include <windows.h>
@@ -41,7 +43,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
41#include <sys/param.h> 43#include <sys/param.h>
42#endif /* MSDOS */ 44#endif /* MSDOS */
43 45
44#include "lisp.h"
45#include "commands.h" 46#include "commands.h"
46#include "buffer.h" 47#include "buffer.h"
47#include "character.h" 48#include "character.h"
@@ -74,10 +75,6 @@ extern char **environ;
74/* Pattern used by call-process-region to make temp files. */ 75/* Pattern used by call-process-region to make temp files. */
75static Lisp_Object Vtemp_file_name_pattern; 76static Lisp_Object Vtemp_file_name_pattern;
76 77
77#ifdef DOS_NT
78Lisp_Object Qbuffer_file_type;
79#endif /* DOS_NT */
80
81/* True if we are about to fork off a synchronous process or if we 78/* True if we are about to fork off a synchronous process or if we
82 are waiting for it. */ 79 are waiting for it. */
83int synch_process_alive; 80int synch_process_alive;
@@ -100,7 +97,7 @@ int synch_process_retcode;
100/* Nonzero if this is termination due to exit. */ 97/* Nonzero if this is termination due to exit. */
101static int call_process_exited; 98static int call_process_exited;
102 99
103EXFUN (Fgetenv_internal, 2); 100static Lisp_Object Fgetenv_internal (Lisp_Object, Lisp_Object);
104 101
105static Lisp_Object 102static Lisp_Object
106call_process_kill (Lisp_Object fdpid) 103call_process_kill (Lisp_Object fdpid)
@@ -111,12 +108,13 @@ call_process_kill (Lisp_Object fdpid)
111 return Qnil; 108 return Qnil;
112} 109}
113 110
114Lisp_Object 111static Lisp_Object
115call_process_cleanup (Lisp_Object arg) 112call_process_cleanup (Lisp_Object arg)
116{ 113{
117 Lisp_Object fdpid = Fcdr (arg); 114 Lisp_Object fdpid = Fcdr (arg);
118#if defined (MSDOS) 115#if defined (MSDOS)
119 Lisp_Object file; 116 Lisp_Object file;
117 int fd;
120#else 118#else
121 int pid; 119 int pid;
122#endif 120#endif
@@ -125,9 +123,13 @@ call_process_cleanup (Lisp_Object arg)
125 123
126#if defined (MSDOS) 124#if defined (MSDOS)
127 /* for MSDOS fdpid is really (fd . tempfile) */ 125 /* for MSDOS fdpid is really (fd . tempfile) */
126 fd = XFASTINT (Fcar (fdpid));
128 file = Fcdr (fdpid); 127 file = Fcdr (fdpid);
129 emacs_close (XFASTINT (Fcar (fdpid))); 128 /* FD is -1 and FILE is "" when we didn't actually create a
130 if (strcmp (SDATA (file), NULL_DEVICE) != 0) 129 temporary file in call-process. */
130 if (fd >= 0)
131 emacs_close (fd);
132 if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0'))
131 unlink (SDATA (file)); 133 unlink (SDATA (file));
132#else /* not MSDOS */ 134#else /* not MSDOS */
133 pid = XFASTINT (Fcdr (fdpid)); 135 pid = XFASTINT (Fcdr (fdpid));
@@ -160,8 +162,9 @@ DEFUN ("call-process", Fcall_process, Scall_process, 1, MANY, 0,
160 doc: /* Call PROGRAM synchronously in separate process. 162 doc: /* Call PROGRAM synchronously in separate process.
161The remaining arguments are optional. 163The remaining arguments are optional.
162The program's input comes from file INFILE (nil means `/dev/null'). 164The program's input comes from file INFILE (nil means `/dev/null').
163Insert output in BUFFER before point; t means current buffer; 165Insert output in BUFFER before point; t means current buffer; nil for BUFFER
164 nil for BUFFER means discard it; 0 means discard and don't wait. 166 means discard it; 0 means discard and don't wait; and `(:file FILE)', where
167 FILE is a file name string, means that it should be written to that file.
165BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case, 168BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case,
166REAL-BUFFER says what to do with standard output, as above, 169REAL-BUFFER says what to do with standard output, as above,
167while STDERR-FILE says what to do with standard error in the child. 170while STDERR-FILE says what to do with standard error in the child.
@@ -181,10 +184,10 @@ and returns a numeric exit status or a signal description string.
181If you quit, the process is killed with SIGINT, or SIGKILL if you quit again. 184If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.
182 185
183usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) 186usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
184 (int nargs, register Lisp_Object *args) 187 (ptrdiff_t nargs, Lisp_Object *args)
185{ 188{
186 Lisp_Object infile, buffer, current_dir, path; 189 Lisp_Object infile, buffer, current_dir, path;
187 int display_p; 190 volatile int display_p_volatile;
188 int fd[2]; 191 int fd[2];
189 int filefd; 192 int filefd;
190 register int pid; 193 register int pid;
@@ -193,19 +196,23 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
193 char buf[CALLPROC_BUFFER_SIZE_MAX]; 196 char buf[CALLPROC_BUFFER_SIZE_MAX];
194 int bufsize = CALLPROC_BUFFER_SIZE_MIN; 197 int bufsize = CALLPROC_BUFFER_SIZE_MIN;
195 int count = SPECPDL_INDEX (); 198 int count = SPECPDL_INDEX ();
199 volatile USE_SAFE_ALLOCA;
196 200
197 register const unsigned char **new_argv; 201 register const unsigned char **new_argv;
198 /* File to use for stderr in the child. 202 /* File to use for stderr in the child.
199 t means use same as standard output. */ 203 t means use same as standard output. */
200 Lisp_Object error_file; 204 Lisp_Object error_file;
205 Lisp_Object output_file = Qnil;
201#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ 206#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
202 char *outf, *tempfile; 207 char *outf, *tempfile = NULL;
203 int outfilefd; 208 int outfilefd;
204#endif 209#endif
210 int fd_output = -1;
205 struct coding_system process_coding; /* coding-system of process output */ 211 struct coding_system process_coding; /* coding-system of process output */
206 struct coding_system argument_coding; /* coding-system of arguments */ 212 struct coding_system argument_coding; /* coding-system of arguments */
207 /* Set to the return value of Ffind_operation_coding_system. */ 213 /* Set to the return value of Ffind_operation_coding_system. */
208 Lisp_Object coding_systems; 214 Lisp_Object coding_systems;
215 int output_to_buffer = 1;
209 216
210 /* Qt denotes that Ffind_operation_coding_system is not yet called. */ 217 /* Qt denotes that Ffind_operation_coding_system is not yet called. */
211 coding_systems = Qt; 218 coding_systems = Qt;
@@ -224,7 +231,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
224 /* Decide the coding-system for giving arguments. */ 231 /* Decide the coding-system for giving arguments. */
225 { 232 {
226 Lisp_Object val, *args2; 233 Lisp_Object val, *args2;
227 int i; 234 ptrdiff_t i;
228 235
229 /* If arguments are supplied, we may have to encode them. */ 236 /* If arguments are supplied, we may have to encode them. */
230 if (nargs >= 5) 237 if (nargs >= 5)
@@ -245,7 +252,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
245 val = Qraw_text; 252 val = Qraw_text;
246 else 253 else
247 { 254 {
248 args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2); 255 SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2);
249 args2[0] = Qcall_process; 256 args2[0] = Qcall_process;
250 for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; 257 for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
251 coding_systems = Ffind_operation_coding_system (nargs + 1, args2); 258 coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
@@ -265,7 +272,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
265 272
266 if (nargs >= 2 && ! NILP (args[1])) 273 if (nargs >= 2 && ! NILP (args[1]))
267 { 274 {
268 infile = Fexpand_file_name (args[1], current_buffer->directory); 275 infile = Fexpand_file_name (args[1], BVAR (current_buffer, directory));
269 CHECK_STRING (infile); 276 CHECK_STRING (infile);
270 } 277 }
271 else 278 else
@@ -275,9 +282,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
275 { 282 {
276 buffer = args[2]; 283 buffer = args[2];
277 284
278 /* If BUFFER is a list, its meaning is 285 /* If BUFFER is a list, its meaning is (BUFFER-FOR-STDOUT
279 (BUFFER-FOR-STDOUT FILE-FOR-STDERR). */ 286 FILE-FOR-STDERR), unless the first element is :file, in which case see
280 if (CONSP (buffer)) 287 the next paragraph. */
288 if (CONSP (buffer)
289 && (! SYMBOLP (XCAR (buffer))
290 || strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file")))
281 { 291 {
282 if (CONSP (XCDR (buffer))) 292 if (CONSP (XCDR (buffer)))
283 { 293 {
@@ -293,6 +303,17 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
293 buffer = XCAR (buffer); 303 buffer = XCAR (buffer);
294 } 304 }
295 305
306 /* If the buffer is (still) a list, it might be a (:file "file") spec. */
307 if (CONSP (buffer)
308 && SYMBOLP (XCAR (buffer))
309 && ! strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file"))
310 {
311 output_file = Fexpand_file_name (XCAR (XCDR (buffer)),
312 BVAR (current_buffer, directory));
313 CHECK_STRING (output_file);
314 buffer = Qnil;
315 }
316
296 if (!(EQ (buffer, Qnil) 317 if (!(EQ (buffer, Qnil)
297 || EQ (buffer, Qt) 318 || EQ (buffer, Qt)
298 || INTEGERP (buffer))) 319 || INTEGERP (buffer)))
@@ -320,11 +341,11 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
320 protected by the caller, so all we really have to worry about is 341 protected by the caller, so all we really have to worry about is
321 buffer. */ 342 buffer. */
322 { 343 {
323 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 344 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
324 345
325 current_dir = current_buffer->directory; 346 current_dir = BVAR (current_buffer, directory);
326 347
327 GCPRO4 (infile, buffer, current_dir, error_file); 348 GCPRO5 (infile, buffer, current_dir, error_file, output_file);
328 349
329 current_dir = Funhandled_file_name_directory (current_dir); 350 current_dir = Funhandled_file_name_directory (current_dir);
330 if (NILP (current_dir)) 351 if (NILP (current_dir))
@@ -336,7 +357,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
336 357
337 if (NILP (Ffile_accessible_directory_p (current_dir))) 358 if (NILP (Ffile_accessible_directory_p (current_dir)))
338 report_file_error ("Setting current directory", 359 report_file_error ("Setting current directory",
339 Fcons (current_buffer->directory, Qnil)); 360 Fcons (BVAR (current_buffer, directory), Qnil));
340 361
341 if (STRING_MULTIBYTE (infile)) 362 if (STRING_MULTIBYTE (infile))
342 infile = ENCODE_FILE (infile); 363 infile = ENCODE_FILE (infile);
@@ -344,10 +365,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
344 current_dir = ENCODE_FILE (current_dir); 365 current_dir = ENCODE_FILE (current_dir);
345 if (STRINGP (error_file) && STRING_MULTIBYTE (error_file)) 366 if (STRINGP (error_file) && STRING_MULTIBYTE (error_file))
346 error_file = ENCODE_FILE (error_file); 367 error_file = ENCODE_FILE (error_file);
368 if (STRINGP (output_file) && STRING_MULTIBYTE (output_file))
369 output_file = ENCODE_FILE (output_file);
347 UNGCPRO; 370 UNGCPRO;
348 } 371 }
349 372
350 display_p = INTERACTIVE && nargs >= 4 && !NILP (args[3]); 373 display_p_volatile = INTERACTIVE && nargs >= 4 && !NILP (args[3]);
351 374
352 filefd = emacs_open (SSDATA (infile), O_RDONLY, 0); 375 filefd = emacs_open (SSDATA (infile), O_RDONLY, 0);
353 if (filefd < 0) 376 if (filefd < 0)
@@ -355,6 +378,26 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
355 infile = DECODE_FILE (infile); 378 infile = DECODE_FILE (infile);
356 report_file_error ("Opening process input file", Fcons (infile, Qnil)); 379 report_file_error ("Opening process input file", Fcons (infile, Qnil));
357 } 380 }
381
382 if (STRINGP (output_file))
383 {
384#ifdef DOS_NT
385 fd_output = emacs_open (SSDATA (output_file),
386 O_WRONLY | O_TRUNC | O_CREAT | O_TEXT,
387 S_IREAD | S_IWRITE);
388#else /* not DOS_NT */
389 fd_output = creat (SSDATA (output_file), 0666);
390#endif /* not DOS_NT */
391 if (fd_output < 0)
392 {
393 output_file = DECODE_FILE (output_file);
394 report_file_error ("Opening process output file",
395 Fcons (output_file, Qnil));
396 }
397 if (STRINGP (error_file) || NILP (error_file))
398 output_to_buffer = 0;
399 }
400
358 /* Search for program; barf if not found. */ 401 /* Search for program; barf if not found. */
359 { 402 {
360 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 403 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
@@ -375,11 +418,11 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
375 && SREF (path, 1) == ':') 418 && SREF (path, 1) == ':')
376 path = Fsubstring (path, make_number (2), Qnil); 419 path = Fsubstring (path, make_number (2), Qnil);
377 420
378 new_argv = (const unsigned char **) 421 SAFE_ALLOCA (new_argv, const unsigned char **,
379 alloca (max (2, nargs - 2) * sizeof (char *)); 422 (nargs > 4 ? nargs - 2 : 2) * sizeof *new_argv);
380 if (nargs > 4) 423 if (nargs > 4)
381 { 424 {
382 register int i; 425 ptrdiff_t i;
383 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 426 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
384 427
385 GCPRO5 (infile, buffer, current_dir, path, error_file); 428 GCPRO5 (infile, buffer, current_dir, path, error_file);
@@ -401,26 +444,32 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
401 new_argv[0] = SDATA (path); 444 new_argv[0] = SDATA (path);
402 445
403#ifdef MSDOS /* MW, July 1993 */ 446#ifdef MSDOS /* MW, July 1993 */
404 if ((outf = egetenv ("TMPDIR"))) 447
405 strcpy (tempfile = alloca (strlen (outf) + 20), outf); 448 /* If we're redirecting STDOUT to a file, that file is already open
406 else 449 on fd_output. */
407 { 450 if (fd_output < 0)
408 tempfile = alloca (20);
409 *tempfile = '\0';
410 }
411 dostounix_filename (tempfile);
412 if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/')
413 strcat (tempfile, "/");
414 strcat (tempfile, "detmp.XXX");
415 mktemp (tempfile);
416
417 outfilefd = creat (tempfile, S_IREAD | S_IWRITE);
418 if (outfilefd < 0)
419 { 451 {
420 emacs_close (filefd); 452 if ((outf = egetenv ("TMPDIR")))
421 report_file_error ("Opening process output file", 453 strcpy (tempfile = alloca (strlen (outf) + 20), outf);
422 Fcons (build_string (tempfile), Qnil)); 454 else
455 {
456 tempfile = alloca (20);
457 *tempfile = '\0';
458 }
459 dostounix_filename (tempfile);
460 if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/')
461 strcat (tempfile, "/");
462 strcat (tempfile, "detmp.XXX");
463 mktemp (tempfile);
464 outfilefd = creat (tempfile, S_IREAD | S_IWRITE);
465 if (outfilefd < 0) {
466 emacs_close (filefd);
467 report_file_error ("Opening process output file",
468 Fcons (build_string (tempfile), Qnil));
469 }
423 } 470 }
471 else
472 outfilefd = fd_output;
424 fd[0] = filefd; 473 fd[0] = filefd;
425 fd[1] = outfilefd; 474 fd[1] = outfilefd;
426#endif /* MSDOS */ 475#endif /* MSDOS */
@@ -445,7 +494,14 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
445 register char **save_environ = environ; 494 register char **save_environ = environ;
446 register int fd1 = fd[1]; 495 register int fd1 = fd[1];
447 int fd_error = fd1; 496 int fd_error = fd1;
497#ifdef HAVE_WORKING_VFORK
498 sigset_t procmask;
499 sigset_t blocked;
500 struct sigaction sigpipe_action;
501#endif
448 502
503 if (fd_output >= 0)
504 fd1 = fd_output;
449#if 0 /* Some systems don't have sigblock. */ 505#if 0 /* Some systems don't have sigblock. */
450 mask = sigblock (sigmask (SIGCHLD)); 506 mask = sigblock (sigmask (SIGCHLD));
451#endif 507#endif
@@ -511,41 +567,87 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
511 if (fd_error != outfilefd) 567 if (fd_error != outfilefd)
512 emacs_close (fd_error); 568 emacs_close (fd_error);
513 fd1 = -1; /* No harm in closing that one! */ 569 fd1 = -1; /* No harm in closing that one! */
514 /* Since CRLF is converted to LF within `decode_coding', we can 570 if (tempfile)
515 always open a file with binary mode. */
516 fd[0] = emacs_open (tempfile, O_RDONLY | O_BINARY, 0);
517 if (fd[0] < 0)
518 { 571 {
519 unlink (tempfile); 572 /* Since CRLF is converted to LF within `decode_coding', we
520 emacs_close (filefd); 573 can always open a file with binary mode. */
521 report_file_error ("Cannot re-open temporary file", Qnil); 574 fd[0] = emacs_open (tempfile, O_RDONLY | O_BINARY, 0);
575 if (fd[0] < 0)
576 {
577 unlink (tempfile);
578 emacs_close (filefd);
579 report_file_error ("Cannot re-open temporary file",
580 Fcons (build_string (tempfile), Qnil));
581 }
522 } 582 }
583 else
584 fd[0] = -1; /* We are not going to read from tempfile. */
523#else /* not MSDOS */ 585#else /* not MSDOS */
524#ifdef WINDOWSNT 586#ifdef WINDOWSNT
525 pid = child_setup (filefd, fd1, fd_error, (char **) new_argv, 587 pid = child_setup (filefd, fd1, fd_error, (char **) new_argv,
526 0, current_dir); 588 0, current_dir);
527#else /* not WINDOWSNT */ 589#else /* not WINDOWSNT */
590
591#ifdef HAVE_WORKING_VFORK
592 /* On many hosts (e.g. Solaris 2.4), if a vforked child calls `signal',
593 this sets the parent's signal handlers as well as the child's.
594 So delay all interrupts whose handlers the child might munge,
595 and record the current handlers so they can be restored later. */
596 sigemptyset (&blocked);
597 sigaddset (&blocked, SIGPIPE);
598 sigaction (SIGPIPE, 0, &sigpipe_action);
599 sigprocmask (SIG_BLOCK, &blocked, &procmask);
600#endif
601
528 BLOCK_INPUT; 602 BLOCK_INPUT;
529 603
530 pid = vfork (); 604 /* vfork, and prevent local vars from being clobbered by the vfork. */
605 {
606 int volatile fd_error_volatile = fd_error;
607 int volatile fd_output_volatile = fd_output;
608 int volatile output_to_buffer_volatile = output_to_buffer;
609 unsigned char const **volatile new_argv_volatile = new_argv;
610
611 pid = vfork ();
612
613 fd_error = fd_error_volatile;
614 fd_output = fd_output_volatile;
615 output_to_buffer = output_to_buffer_volatile;
616 new_argv = new_argv_volatile;
617 }
531 618
532 if (pid == 0) 619 if (pid == 0)
533 { 620 {
534 if (fd[0] >= 0) 621 if (fd[0] >= 0)
535 emacs_close (fd[0]); 622 emacs_close (fd[0]);
536#ifdef HAVE_SETSID 623#ifdef HAVE_SETSID
537 setsid (); 624 setsid ();
538#endif 625#endif
539#if defined (USG) 626#if defined (USG)
540 setpgrp (); 627 setpgrp ();
541#else 628#else
542 setpgrp (pid, pid); 629 setpgrp (pid, pid);
543#endif /* USG */ 630#endif /* USG */
631
632 /* GConf causes us to ignore SIGPIPE, make sure it is restored
633 in the child. */
634 //signal (SIGPIPE, SIG_DFL);
635#ifdef HAVE_WORKING_VFORK
636 sigprocmask (SIG_SETMASK, &procmask, 0);
637#endif
638
544 child_setup (filefd, fd1, fd_error, (char **) new_argv, 639 child_setup (filefd, fd1, fd_error, (char **) new_argv,
545 0, current_dir); 640 0, current_dir);
546 } 641 }
547 642
548 UNBLOCK_INPUT; 643 UNBLOCK_INPUT;
644
645#ifdef HAVE_WORKING_VFORK
646 /* Restore the signal state. */
647 sigaction (SIGPIPE, &sigpipe_action, 0);
648 sigprocmask (SIG_SETMASK, &procmask, 0);
649#endif
650
549#endif /* not WINDOWSNT */ 651#endif /* not WINDOWSNT */
550 652
551 /* The MSDOS case did this already. */ 653 /* The MSDOS case did this already. */
@@ -558,6 +660,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
558 /* Close most of our fd's, but not fd[0] 660 /* Close most of our fd's, but not fd[0]
559 since we will use that to read input from. */ 661 since we will use that to read input from. */
560 emacs_close (filefd); 662 emacs_close (filefd);
663 if (fd_output >= 0)
664 emacs_close (fd_output);
561 if (fd1 >= 0 && fd1 != fd_error) 665 if (fd1 >= 0 && fd1 != fd_error)
562 emacs_close (fd1); 666 emacs_close (fd1);
563 } 667 }
@@ -584,7 +688,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
584 record_unwind_protect (call_process_cleanup, 688 record_unwind_protect (call_process_cleanup,
585 Fcons (Fcurrent_buffer (), 689 Fcons (Fcurrent_buffer (),
586 Fcons (make_number (fd[0]), 690 Fcons (make_number (fd[0]),
587 build_string (tempfile)))); 691 build_string (tempfile ? tempfile : ""))));
588#else 692#else
589 record_unwind_protect (call_process_cleanup, 693 record_unwind_protect (call_process_cleanup,
590 Fcons (Fcurrent_buffer (), 694 Fcons (Fcurrent_buffer (),
@@ -612,9 +716,9 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
612 { 716 {
613 if (EQ (coding_systems, Qt)) 717 if (EQ (coding_systems, Qt))
614 { 718 {
615 int i; 719 ptrdiff_t i;
616 720
617 args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2); 721 SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2);
618 args2[0] = Qcall_process; 722 args2[0] = Qcall_process;
619 for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; 723 for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
620 coding_systems 724 coding_systems
@@ -631,7 +735,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
631 /* In unibyte mode, character code conversion should not take 735 /* In unibyte mode, character code conversion should not take
632 place but EOL conversion should. So, setup raw-text or one 736 place but EOL conversion should. So, setup raw-text or one
633 of the subsidiary according to the information just setup. */ 737 of the subsidiary according to the information just setup. */
634 if (NILP (current_buffer->enable_multibyte_characters) 738 if (NILP (BVAR (current_buffer, enable_multibyte_characters))
635 && !NILP (val)) 739 && !NILP (val))
636 val = raw_text_coding_system (val); 740 val = raw_text_coding_system (val);
637 setup_coding_system (val, &process_coding); 741 setup_coding_system (val, &process_coding);
@@ -640,135 +744,140 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
640 immediate_quit = 1; 744 immediate_quit = 1;
641 QUIT; 745 QUIT;
642 746
643 { 747 if (output_to_buffer)
644 register EMACS_INT nread; 748 {
645 int first = 1; 749 register EMACS_INT nread;
646 EMACS_INT total_read = 0; 750 int first = 1;
647 int carryover = 0; 751 EMACS_INT total_read = 0;
648 int display_on_the_fly = display_p; 752 int carryover = 0;
649 struct coding_system saved_coding; 753 int display_p = display_p_volatile;
650 754 int display_on_the_fly = display_p;
651 saved_coding = process_coding; 755 struct coding_system saved_coding;
652 while (1) 756
653 { 757 saved_coding = process_coding;
654 /* Repeatedly read until we've filled as much as possible 758 while (1)
655 of the buffer size we have. But don't read 759 {
656 less than 1024--save that for the next bufferful. */ 760 /* Repeatedly read until we've filled as much as possible
657 nread = carryover; 761 of the buffer size we have. But don't read
658 while (nread < bufsize - 1024) 762 less than 1024--save that for the next bufferful. */
659 { 763 nread = carryover;
660 int this_read = emacs_read (fd[0], buf + nread, 764 while (nread < bufsize - 1024)
661 bufsize - nread); 765 {
766 int this_read = emacs_read (fd[0], buf + nread,
767 bufsize - nread);
662 768
663 if (this_read < 0) 769 if (this_read < 0)
664 goto give_up; 770 goto give_up;
665 771
666 if (this_read == 0) 772 if (this_read == 0)
667 { 773 {
668 process_coding.mode |= CODING_MODE_LAST_BLOCK; 774 process_coding.mode |= CODING_MODE_LAST_BLOCK;
669 break; 775 break;
670 } 776 }
671 777
672 nread += this_read; 778 nread += this_read;
673 total_read += this_read; 779 total_read += this_read;
674 780
675 if (display_on_the_fly) 781 if (display_on_the_fly)
676 break; 782 break;
677 } 783 }
678 784
679 /* Now NREAD is the total amount of data in the buffer. */ 785 /* Now NREAD is the total amount of data in the buffer. */
680 immediate_quit = 0; 786 immediate_quit = 0;
681 787
682 if (!NILP (buffer)) 788 if (!NILP (buffer))
683 { 789 {
684 if (NILP (current_buffer->enable_multibyte_characters) 790 if (NILP (BVAR (current_buffer, enable_multibyte_characters))
685 && ! CODING_MAY_REQUIRE_DECODING (&process_coding)) 791 && ! CODING_MAY_REQUIRE_DECODING (&process_coding))
686 insert_1_both (buf, nread, nread, 0, 1, 0); 792 insert_1_both (buf, nread, nread, 0, 1, 0);
687 else 793 else
688 { /* We have to decode the input. */ 794 { /* We have to decode the input. */
689 Lisp_Object curbuf; 795 Lisp_Object curbuf;
690 int count1 = SPECPDL_INDEX (); 796 int count1 = SPECPDL_INDEX ();
691 797
692 XSETBUFFER (curbuf, current_buffer); 798 XSETBUFFER (curbuf, current_buffer);
693 /* We cannot allow after-change-functions be run 799 /* We cannot allow after-change-functions be run
694 during decoding, because that might modify the 800 during decoding, because that might modify the
695 buffer, while we rely on process_coding.produced to 801 buffer, while we rely on process_coding.produced to
696 faithfully reflect inserted text until we 802 faithfully reflect inserted text until we
697 TEMP_SET_PT_BOTH below. */ 803 TEMP_SET_PT_BOTH below. */
698 specbind (Qinhibit_modification_hooks, Qt); 804 specbind (Qinhibit_modification_hooks, Qt);
699 decode_coding_c_string (&process_coding, buf, nread, 805 decode_coding_c_string (&process_coding,
700 curbuf); 806 (unsigned char *) buf, nread, curbuf);
701 unbind_to (count1, Qnil); 807 unbind_to (count1, Qnil);
702 if (display_on_the_fly 808 if (display_on_the_fly
703 && CODING_REQUIRE_DETECTION (&saved_coding) 809 && CODING_REQUIRE_DETECTION (&saved_coding)
704 && ! CODING_REQUIRE_DETECTION (&process_coding)) 810 && ! CODING_REQUIRE_DETECTION (&process_coding))
705 { 811 {
706 /* We have detected some coding system. But, 812 /* We have detected some coding system. But,
707 there's a possibility that the detection was 813 there's a possibility that the detection was
708 done by insufficient data. So, we give up 814 done by insufficient data. So, we give up
709 displaying on the fly. */ 815 displaying on the fly. */
710 if (process_coding.produced > 0) 816 if (process_coding.produced > 0)
711 del_range_2 (process_coding.dst_pos, 817 del_range_2 (process_coding.dst_pos,
712 process_coding.dst_pos_byte, 818 process_coding.dst_pos_byte,
713 process_coding.dst_pos 819 process_coding.dst_pos
714 + process_coding.produced_char, 820 + process_coding.produced_char,
715 process_coding.dst_pos_byte 821 process_coding.dst_pos_byte
716 + process_coding.produced, 0); 822 + process_coding.produced, 0);
717 display_on_the_fly = 0; 823 display_on_the_fly = 0;
718 process_coding = saved_coding; 824 process_coding = saved_coding;
719 carryover = nread; 825 carryover = nread;
720 /* This is to make the above condition always 826 /* This is to make the above condition always
721 fails in the future. */ 827 fails in the future. */
722 saved_coding.common_flags 828 saved_coding.common_flags
723 &= ~CODING_REQUIRE_DETECTION_MASK; 829 &= ~CODING_REQUIRE_DETECTION_MASK;
724 continue; 830 continue;
725 } 831 }
726 832
727 TEMP_SET_PT_BOTH (PT + process_coding.produced_char, 833 TEMP_SET_PT_BOTH (PT + process_coding.produced_char,
728 PT_BYTE + process_coding.produced); 834 PT_BYTE + process_coding.produced);
729 carryover = process_coding.carryover_bytes; 835 carryover = process_coding.carryover_bytes;
730 if (carryover > 0) 836 if (carryover > 0)
731 memcpy (buf, process_coding.carryover, 837 memcpy (buf, process_coding.carryover,
732 process_coding.carryover_bytes); 838 process_coding.carryover_bytes);
733 } 839 }
734 } 840 }
735 841
736 if (process_coding.mode & CODING_MODE_LAST_BLOCK) 842 if (process_coding.mode & CODING_MODE_LAST_BLOCK)
737 break; 843 break;
738 844
739 /* Make the buffer bigger as we continue to read more data, 845 /* Make the buffer bigger as we continue to read more data,
740 but not past CALLPROC_BUFFER_SIZE_MAX. */ 846 but not past CALLPROC_BUFFER_SIZE_MAX. */
741 if (bufsize < CALLPROC_BUFFER_SIZE_MAX && total_read > 32 * bufsize) 847 if (bufsize < CALLPROC_BUFFER_SIZE_MAX && total_read > 32 * bufsize)
742 if ((bufsize *= 2) > CALLPROC_BUFFER_SIZE_MAX) 848 if ((bufsize *= 2) > CALLPROC_BUFFER_SIZE_MAX)
743 bufsize = CALLPROC_BUFFER_SIZE_MAX; 849 bufsize = CALLPROC_BUFFER_SIZE_MAX;
744 850
745 if (display_p) 851 if (display_p)
746 { 852 {
747 if (first) 853 if (first)
748 prepare_menu_bars (); 854 prepare_menu_bars ();
749 first = 0; 855 first = 0;
750 redisplay_preserve_echo_area (1); 856 redisplay_preserve_echo_area (1);
751 /* This variable might have been set to 0 for code 857 /* This variable might have been set to 0 for code
752 detection. In that case, we set it back to 1 because 858 detection. In that case, we set it back to 1 because
753 we should have already detected a coding system. */ 859 we should have already detected a coding system. */
754 display_on_the_fly = 1; 860 display_on_the_fly = 1;
755 } 861 }
756 immediate_quit = 1; 862 immediate_quit = 1;
757 QUIT; 863 QUIT;
758 } 864 }
759 give_up: ; 865 give_up: ;
760 866
761 Vlast_coding_system_used = CODING_ID_NAME (process_coding.id); 867 Vlast_coding_system_used = CODING_ID_NAME (process_coding.id);
762 /* If the caller required, let the buffer inherit the 868 /* If the caller required, let the buffer inherit the
763 coding-system used to decode the process output. */ 869 coding-system used to decode the process output. */
764 if (inherit_process_coding_system) 870 if (inherit_process_coding_system)
765 call1 (intern ("after-insert-file-set-buffer-file-coding-system"), 871 call1 (intern ("after-insert-file-set-buffer-file-coding-system"),
766 make_number (total_read)); 872 make_number (total_read));
767 } 873 }
768 874
769#ifndef MSDOS 875#ifndef MSDOS
770 /* Wait for it to terminate, unless it already has. */ 876 /* Wait for it to terminate, unless it already has. */
771 wait_for_termination (pid); 877 if (output_to_buffer)
878 wait_for_termination (pid);
879 else
880 interruptible_wait_for_termination (pid);
772#endif 881#endif
773 882
774 immediate_quit = 0; 883 immediate_quit = 0;
@@ -777,6 +886,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
777 when exiting. */ 886 when exiting. */
778 call_process_exited = 1; 887 call_process_exited = 1;
779 888
889 SAFE_FREE ();
780 unbind_to (count, Qnil); 890 unbind_to (count, Qnil);
781 891
782 if (synch_process_termsig) 892 if (synch_process_termsig)
@@ -787,7 +897,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
787 signame = strsignal (synch_process_termsig); 897 signame = strsignal (synch_process_termsig);
788 898
789 if (signame == 0) 899 if (signame == 0)
790 signame = "unknown"; 900 signame = "unknown";
791 901
792 synch_process_death = signame; 902 synch_process_death = signame;
793 } 903 }
@@ -815,8 +925,10 @@ DEFUN ("call-process-region", Fcall_process_region, Scall_process_region,
815The remaining arguments are optional. 925The remaining arguments are optional.
816Delete the text if fourth arg DELETE is non-nil. 926Delete the text if fourth arg DELETE is non-nil.
817 927
818Insert output in BUFFER before point; t means current buffer; 928Insert output in BUFFER before point; t means current buffer; nil for
819 nil for BUFFER means discard it; 0 means discard and don't wait. 929 BUFFER means discard it; 0 means discard and don't wait; and `(:file
930 FILE)', where FILE is a file name string, means that it should be
931 written to that file.
820BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case, 932BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case,
821REAL-BUFFER says what to do with standard output, as above, 933REAL-BUFFER says what to do with standard output, as above,
822while STDERR-FILE says what to do with standard error in the child. 934while STDERR-FILE says what to do with standard error in the child.
@@ -832,7 +944,7 @@ and returns a numeric exit status or a signal description string.
832If you quit, the process is killed with SIGINT, or SIGKILL if you quit again. 944If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.
833 945
834usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &rest ARGS) */) 946usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &rest ARGS) */)
835 (int nargs, register Lisp_Object *args) 947 (ptrdiff_t nargs, Lisp_Object *args)
836{ 948{
837 struct gcpro gcpro1; 949 struct gcpro gcpro1;
838 Lisp_Object filename_string; 950 Lisp_Object filename_string;
@@ -841,7 +953,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
841 /* Qt denotes we have not yet called Ffind_operation_coding_system. */ 953 /* Qt denotes we have not yet called Ffind_operation_coding_system. */
842 Lisp_Object coding_systems; 954 Lisp_Object coding_systems;
843 Lisp_Object val, *args2; 955 Lisp_Object val, *args2;
844 int i; 956 ptrdiff_t i;
845 char *tempfile; 957 char *tempfile;
846 Lisp_Object tmpdir, pattern; 958 Lisp_Object tmpdir, pattern;
847 959
@@ -865,44 +977,51 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
865#endif 977#endif
866 } 978 }
867 979
868 pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); 980 {
869 tempfile = (char *) alloca (SBYTES (pattern) + 1); 981 USE_SAFE_ALLOCA;
870 memcpy (tempfile, SDATA (pattern), SBYTES (pattern) + 1); 982 pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir);
871 coding_systems = Qt; 983 SAFE_ALLOCA (tempfile, char *, SBYTES (pattern) + 1);
984 memcpy (tempfile, SDATA (pattern), SBYTES (pattern) + 1);
985 coding_systems = Qt;
872 986
873#ifdef HAVE_MKSTEMP 987#ifdef HAVE_MKSTEMP
874 { 988 {
875 int fd; 989 int fd;
876 990
877 BLOCK_INPUT; 991 BLOCK_INPUT;
878 fd = mkstemp (tempfile); 992 fd = mkstemp (tempfile);
879 UNBLOCK_INPUT; 993 UNBLOCK_INPUT;
880 if (fd == -1) 994 if (fd == -1)
881 report_file_error ("Failed to open temporary file", 995 report_file_error ("Failed to open temporary file",
882 Fcons (Vtemp_file_name_pattern, Qnil)); 996 Fcons (Vtemp_file_name_pattern, Qnil));
883 else 997 else
884 close (fd); 998 close (fd);
885 } 999 }
886#else 1000#else
887 mktemp (tempfile); 1001 mktemp (tempfile);
888#endif 1002#endif
889 1003
890 filename_string = build_string (tempfile); 1004 filename_string = build_string (tempfile);
891 GCPRO1 (filename_string); 1005 GCPRO1 (filename_string);
1006 SAFE_FREE ();
1007 }
1008
892 start = args[0]; 1009 start = args[0];
893 end = args[1]; 1010 end = args[1];
894 /* Decide coding-system of the contents of the temporary file. */ 1011 /* Decide coding-system of the contents of the temporary file. */
895 if (!NILP (Vcoding_system_for_write)) 1012 if (!NILP (Vcoding_system_for_write))
896 val = Vcoding_system_for_write; 1013 val = Vcoding_system_for_write;
897 else if (NILP (current_buffer->enable_multibyte_characters)) 1014 else if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
898 val = Qraw_text; 1015 val = Qraw_text;
899 else 1016 else
900 { 1017 {
901 args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2); 1018 USE_SAFE_ALLOCA;
1019 SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2);
902 args2[0] = Qcall_process_region; 1020 args2[0] = Qcall_process_region;
903 for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; 1021 for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
904 coding_systems = Ffind_operation_coding_system (nargs + 1, args2); 1022 coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
905 val = CONSP (coding_systems) ? XCDR (coding_systems) : Qnil; 1023 val = CONSP (coding_systems) ? XCDR (coding_systems) : Qnil;
1024 SAFE_FREE ();
906 } 1025 }
907 val = complement_process_encoding_system (val); 1026 val = complement_process_encoding_system (val);
908 1027
@@ -961,18 +1080,18 @@ add_env (char **env, char **new_env, char *string)
961 { 1080 {
962 char *p = *ep, *q = string; 1081 char *p = *ep, *q = string;
963 while (ok) 1082 while (ok)
964 { 1083 {
965 if (*q != *p) 1084 if (*q != *p)
966 break; 1085 break;
967 if (*q == 0) 1086 if (*q == 0)
968 /* The string is a lone variable name; keep it for now, we 1087 /* The string is a lone variable name; keep it for now, we
969 will remove it later. It is a placeholder for a 1088 will remove it later. It is a placeholder for a
970 variable that is not to be included in the environment. */ 1089 variable that is not to be included in the environment. */
971 break; 1090 break;
972 if (*q == '=') 1091 if (*q == '=')
973 ok = 0; 1092 ok = 0;
974 p++, q++; 1093 p++, q++;
975 } 1094 }
976 } 1095 }
977 if (ok) 1096 if (ok)
978 *new_env++ = string; 1097 *new_env++ = string;
@@ -1076,8 +1195,8 @@ child_setup (int in, int out, int err, register char **new_argv, int set_pgrp, L
1076 new_length = 0; 1195 new_length = 0;
1077 1196
1078 for (tem = Vprocess_environment; 1197 for (tem = Vprocess_environment;
1079 CONSP (tem) && STRINGP (XCAR (tem)); 1198 CONSP (tem) && STRINGP (XCAR (tem));
1080 tem = XCDR (tem)) 1199 tem = XCDR (tem))
1081 { 1200 {
1082 if (strncmp (SSDATA (XCAR (tem)), "DISPLAY", 7) == 0 1201 if (strncmp (SSDATA (XCAR (tem)), "DISPLAY", 7) == 0
1083 && (SDATA (XCAR (tem)) [7] == '\0' 1202 && (SDATA (XCAR (tem)) [7] == '\0'
@@ -1130,11 +1249,11 @@ child_setup (int in, int out, int err, register char **new_argv, int set_pgrp, L
1130 p = q = env; 1249 p = q = env;
1131 while (*p != 0) 1250 while (*p != 0)
1132 { 1251 {
1133 while (*q != 0 && strchr (*q, '=') == NULL) 1252 while (*q != 0 && strchr (*q, '=') == NULL)
1134 q++; 1253 q++;
1135 *p = *q++; 1254 *p = *q++;
1136 if (*p != 0) 1255 if (*p != 0)
1137 p++; 1256 p++;
1138 } 1257 }
1139 } 1258 }
1140 1259
@@ -1244,12 +1363,12 @@ relocate_fd (int fd, int minfd)
1244#endif 1363#endif
1245 if (new == -1) 1364 if (new == -1)
1246 { 1365 {
1247 const char *message1 = "Error while setting up child: "; 1366 const char *message_1 = "Error while setting up child: ";
1248 const char *errmessage = strerror (errno); 1367 const char *errmessage = strerror (errno);
1249 const char *message2 = "\n"; 1368 const char *message_2 = "\n";
1250 emacs_write (2, message1, strlen (message1)); 1369 emacs_write (2, message_1, strlen (message_1));
1251 emacs_write (2, errmessage, strlen (errmessage)); 1370 emacs_write (2, errmessage, strlen (errmessage));
1252 emacs_write (2, message2, strlen (message2)); 1371 emacs_write (2, message_2, strlen (message_2));
1253 _exit (1); 1372 _exit (1);
1254 } 1373 }
1255 emacs_close (fd); 1374 emacs_close (fd);
@@ -1484,30 +1603,18 @@ init_callproc (void)
1484void 1603void
1485set_initial_environment (void) 1604set_initial_environment (void)
1486{ 1605{
1487 register char **envp; 1606 char **envp;
1488#ifdef CANNOT_DUMP 1607 for (envp = environ; *envp; envp++)
1489 Vprocess_environment = Qnil; 1608 Vprocess_environment = Fcons (build_string (*envp),
1490#else 1609 Vprocess_environment);
1491 if (initialized) 1610 /* Ideally, the `copy' shouldn't be necessary, but it seems it's frequent
1492#endif 1611 to use `delete' and friends on process-environment. */
1493 { 1612 Vinitial_environment = Fcopy_sequence (Vprocess_environment);
1494 for (envp = environ; *envp; envp++)
1495 Vprocess_environment = Fcons (build_string (*envp),
1496 Vprocess_environment);
1497 /* Ideally, the `copy' shouldn't be necessary, but it seems it's frequent
1498 to use `delete' and friends on process-environment. */
1499 Vinitial_environment = Fcopy_sequence (Vprocess_environment);
1500 }
1501} 1613}
1502 1614
1503void 1615void
1504syms_of_callproc (void) 1616syms_of_callproc (void)
1505{ 1617{
1506#ifdef DOS_NT
1507 Qbuffer_file_type = intern_c_string ("buffer-file-type");
1508 staticpro (&Qbuffer_file_type);
1509#endif /* DOS_NT */
1510
1511#ifndef DOS_NT 1618#ifndef DOS_NT
1512 Vtemp_file_name_pattern = build_string ("emacsXXXXXX"); 1619 Vtemp_file_name_pattern = build_string ("emacsXXXXXX");
1513#elif defined (WINDOWSNT) 1620#elif defined (WINDOWSNT)