comparison src/process-nt.c @ 286:57709be46d1b r21-0b41

Import from CVS: tag r21-0b41
author cvs
date Mon, 13 Aug 2007 10:35:03 +0200
parents c42ec1d1cded
children e11d67e05968
comparison
equal deleted inserted replaced
285:9a3756523c1b 286:57709be46d1b
36 #include <shellapi.h> 36 #include <shellapi.h>
37 #include <signal.h> 37 #include <signal.h>
38 #ifdef HAVE_SOCKETS 38 #ifdef HAVE_SOCKETS
39 #include <winsock.h> 39 #include <winsock.h>
40 #endif 40 #endif
41
42 /* Bound by winnt.el */
43 Lisp_Object Qnt_quote_process_args;
41 44
42 /* Implemenation-specific data. Pointed to by Lisp_Process->process_data */ 45 /* Implemenation-specific data. Pointed to by Lisp_Process->process_data */
43 struct nt_process_data 46 struct nt_process_data
44 { 47 {
45 HANDLE h_process; 48 HANDLE h_process;
362 static void 365 static void
363 validate_signal_number (int signo) 366 validate_signal_number (int signo)
364 { 367 {
365 if (signo != SIGKILL && signo != SIGTERM 368 if (signo != SIGKILL && signo != SIGTERM
366 && signo != SIGQUIT && signo != SIGINT) 369 && signo != SIGQUIT && signo != SIGINT)
367 error ("Signal number %d not supported", signo); 370 signal_simple_error ("Signal number not supported", make_int (signo));
368 } 371 }
369 372
370 /*-----------------------------------------------------------------------*/ 373 /*-----------------------------------------------------------------------*/
371 /* Process methods */ 374 /* Process methods */
372 /*-----------------------------------------------------------------------*/ 375 /*-----------------------------------------------------------------------*/
467 DuplicateHandle (GetCurrentProcess(), hmyslurp, GetCurrentProcess(), &htmp, 470 DuplicateHandle (GetCurrentProcess(), hmyslurp, GetCurrentProcess(), &htmp,
468 0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS); 471 0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
469 hmyslurp = htmp; 472 hmyslurp = htmp;
470 } 473 }
471 474
472 /* Convert an argv vector into Win32 style command line. 475 /* Convert an argv vector into Win32 style command line by a call to
473 476 lisp function `nt-quote-process-args' which see (in winnt.el)*/
474 #### This works only for cmd, and not for cygwin bash. Perhaps,
475 instead of ad-hoc fiddling with different methods for quoting
476 process arguments in ntproc.c (disgust shudder), this must call a
477 smart lisp routine. The code here will be a fallback, if the
478 lisp function is not specified.
479 */
480 { 477 {
481 char** thisarg; 478 char** thisarg;
482 size_t size = 1; 479 Lisp_Object args_or_ret = Qnil;
480 struct gcpro gcpro1;
481
482 GCPRO1 (args_or_ret);
483 483
484 for (thisarg = argv; *thisarg; ++thisarg) 484 for (thisarg = argv; *thisarg; ++thisarg)
485 size += strlen (*thisarg) + 1; 485 args_or_ret = Fcons (build_string (*thisarg), args_or_ret);
486 486 args_or_ret = Fnreverse (args_or_ret);
487 command_line = alloca_array (char, size); 487
488 *command_line = 0; 488 args_or_ret = call1 (Qnt_quote_process_args, args_or_ret);
489 489
490 for (thisarg = argv; *thisarg; ++thisarg) 490 if (!STRINGP (args_or_ret))
491 { 491 /* Luser wrote his/her own clever version */
492 if (thisarg != argv) 492 error ("Bogus return value from `nt-quote-process-args'");
493 strcat (command_line, " "); 493
494 strcat (command_line, *thisarg); 494 command_line = alloca_array (char, (strlen (argv[0])
495 } 495 + XSTRING_LENGTH (args_or_ret) + 2));
496 strcpy (command_line, argv[0]);
497 strcat (command_line, " ");
498 strcat (command_line, XSTRING_DATA (args_or_ret));
499
500 UNGCPRO; /* args_or_ret */
496 } 501 }
497 502
498 /* Create process */ 503 /* Create process */
499 { 504 {
500 STARTUPINFO si; 505 STARTUPINFO si;
624 /* Lstream_write() will never successfully write less than the 629 /* Lstream_write() will never successfully write less than the
625 amount sent in. In the worst case, it just buffers the 630 amount sent in. In the worst case, it just buffers the
626 unwritten data. */ 631 unwritten data. */
627 writeret = Lstream_write (XLSTREAM (DATA_OUTSTREAM(p)), chunkbuf, 632 writeret = Lstream_write (XLSTREAM (DATA_OUTSTREAM(p)), chunkbuf,
628 chunklen); 633 chunklen);
634 Lstream_flush (XLSTREAM (DATA_OUTSTREAM(p)));
629 if (writeret < 0) 635 if (writeret < 0)
630 { 636 {
631 p->status_symbol = Qexit; 637 p->status_symbol = Qexit;
632 p->exit_code = ERROR_BROKEN_PIPE; 638 p->exit_code = ERROR_BROKEN_PIPE;
633 p->core_dumped = 0; 639 p->core_dumped = 0;
636 deactivate_process (proc); 642 deactivate_process (proc);
637 error ("Broken pipe error sending to process %s; closed it", 643 error ("Broken pipe error sending to process %s; closed it",
638 XSTRING_DATA (p->name)); 644 XSTRING_DATA (p->name));
639 } 645 }
640 646
641 while (Lstream_was_blocked_p (XLSTREAM (p->pipe_outstream))) 647 {
642 { 648 int wait_ms = 25;
643 /* Buffer is full. Wait, accepting input; that may allow 649 while (Lstream_was_blocked_p (XLSTREAM (p->pipe_outstream)))
644 the program to finish doing output and read more. */ 650 {
645 Faccept_process_output (Qnil, make_int (1), Qnil); 651 /* Buffer is full. Wait, accepting input; that may allow
646 Lstream_flush (XLSTREAM (p->pipe_outstream)); 652 the program to finish doing output and read more. */
647 } 653 Faccept_process_output (Qnil, Qzero, make_int (wait_ms));
654 Lstream_flush (XLSTREAM (p->pipe_outstream));
655 wait_ms = min (1000, 2 * wait_ms);
656 }
657 }
648 } 658 }
649 Lstream_flush (XLSTREAM (DATA_OUTSTREAM(p)));
650 } 659 }
651 660
652 /* 661 /*
653 * Send a signal number SIGNO to PROCESS. 662 * Send a signal number SIGNO to PROCESS.
654 * CURRENT_GROUP means send to the process group that currently owns 663 * CURRENT_GROUP means send to the process group that currently owns
925 #endif 934 #endif
926 #endif 935 #endif
927 } 936 }
928 937
929 void 938 void
939 syms_of_process_nt (void)
940 {
941 defsymbol (&Qnt_quote_process_args, "nt-quote-process-args");
942 }
943
944 void
930 vars_of_process_nt (void) 945 vars_of_process_nt (void)
931 { 946 {
932 } 947 }
933 948