Mercurial > hg > xemacs-beta
comparison src/process.c @ 185:3d6bfa290dbd r20-3b19
Import from CVS: tag r20-3b19
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:55:28 +0200 |
parents | 2d532a89d707 |
children | a2f645c6b9f8 |
comparison
equal
deleted
inserted
replaced
184:bcd2674570bf | 185:3d6bfa290dbd |
---|---|
221 | 221 |
222 static void | 222 static void |
223 print_process (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | 223 print_process (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) |
224 { | 224 { |
225 struct Lisp_Process *proc = XPROCESS (obj); | 225 struct Lisp_Process *proc = XPROCESS (obj); |
226 | 226 |
227 if (print_readably) | 227 if (print_readably) |
228 error ("printing unreadable object #<process %s>", | 228 error ("printing unreadable object #<process %s>", |
229 XSTRING_DATA (proc->name)); | 229 XSTRING_DATA (proc->name)); |
230 | 230 |
231 if (!escapeflag) | 231 if (!escapeflag) |
232 { | 232 { |
233 print_internal (proc->name, printcharfun, 0); | 233 print_internal (proc->name, printcharfun, 0); |
234 } | 234 } |
235 else | 235 else |
539 static Lisp_Object | 539 static Lisp_Object |
540 make_process_internal (Lisp_Object name) | 540 make_process_internal (Lisp_Object name) |
541 { | 541 { |
542 Lisp_Object val, name1; | 542 Lisp_Object val, name1; |
543 int i; | 543 int i; |
544 struct Lisp_Process *p | 544 struct Lisp_Process *p = |
545 = alloc_lcrecord (sizeof (struct Lisp_Process), lrecord_process); | 545 alloc_lcrecord_type (struct Lisp_Process, lrecord_process); |
546 | 546 |
547 /* If name is already in use, modify it until it is unused. */ | 547 /* If name is already in use, modify it until it is unused. */ |
548 name1 = name; | 548 name1 = name; |
549 for (i = 1; ; i++) | 549 for (i = 1; ; i++) |
550 { | 550 { |
551 char suffix[10]; | 551 char suffix[10]; |
552 Lisp_Object tem = Fget_process (name1); | 552 Lisp_Object tem = Fget_process (name1); |
553 if (NILP (tem)) | 553 if (NILP (tem)) |
554 break; | 554 break; |
555 sprintf (suffix, "<%d>", i); | 555 sprintf (suffix, "<%d>", i); |
556 name1 = concat2 (name, build_string (suffix)); | 556 name1 = concat2 (name, build_string (suffix)); |
557 } | 557 } |
558 name = name1; | 558 name = name1; |
705 | 705 |
706 static Bufbyte | 706 static Bufbyte |
707 get_eof_char (struct Lisp_Process *p) | 707 get_eof_char (struct Lisp_Process *p) |
708 { | 708 { |
709 /* Figure out the eof character for the outfd of the given process. | 709 /* Figure out the eof character for the outfd of the given process. |
710 * The following code is similar to that in process_send_signal, and | 710 * The following code is similar to that in process_send_signal, and |
711 * should probably be merged with that code somehow. */ | 711 * should probably be merged with that code somehow. */ |
712 | 712 |
713 CONST Bufbyte ctrl_d = (Bufbyte) '\004'; | 713 CONST Bufbyte ctrl_d = (Bufbyte) '\004'; |
714 | 714 |
715 if (!isatty (p->outfd)) | 715 if (!isatty (p->outfd)) |
716 return ctrl_d; | 716 return ctrl_d; |
717 #ifdef HAVE_TERMIOS | 717 #ifdef HAVE_TERMIOS |
718 { | 718 { |
719 struct termios t; | 719 struct termios t; |
747 return ctrl_d; | 747 return ctrl_d; |
748 else | 748 else |
749 return (Bufbyte) t.c_cc[VINTR]; | 749 return (Bufbyte) t.c_cc[VINTR]; |
750 } | 750 } |
751 #else /* ! defined (TCGETA) */ | 751 #else /* ! defined (TCGETA) */ |
752 /* Rather than complain, we'll just guess ^D, which is what | 752 /* Rather than complain, we'll just guess ^D, which is what |
753 * earlier emacsen always used. */ | 753 * earlier emacsen always used. */ |
754 return ctrl_d; | 754 return ctrl_d; |
755 #endif /* ! defined (TCGETA) */ | 755 #endif /* ! defined (TCGETA) */ |
756 #endif /* ! defined (TIOCGETC) */ | 756 #endif /* ! defined (TIOCGETC) */ |
757 #endif /* ! defined (HAVE_TERMIOS) */ | 757 #endif /* ! defined (HAVE_TERMIOS) */ |
805 What's going on here? */ | 805 What's going on here? */ |
806 #endif /* MULE */ | 806 #endif /* MULE */ |
807 } | 807 } |
808 | 808 |
809 static void | 809 static void |
810 create_process (Lisp_Object process, | 810 create_process (Lisp_Object process, |
811 char **new_argv, CONST char *current_dir) | 811 char **new_argv, CONST char *current_dir) |
812 { | 812 { |
813 /* This function rewritten by wing@666.com. */ | 813 /* This function rewritten by wing@666.com. */ |
814 | 814 |
815 int pid, inchannel, outchannel; | 815 int pid, inchannel, outchannel; |
957 # endif /* USG or not TIOCSCTTY */ | 957 # endif /* USG or not TIOCSCTTY */ |
958 | 958 |
959 /* Miscellaneous setup required for some systems. | 959 /* Miscellaneous setup required for some systems. |
960 Must be done before using tc* functions on xforkin. | 960 Must be done before using tc* functions on xforkin. |
961 This guarantees that isatty(xforkin) is true. */ | 961 This guarantees that isatty(xforkin) is true. */ |
962 | 962 |
963 # ifdef SETUP_SLAVE_PTY | 963 # ifdef SETUP_SLAVE_PTY |
964 SETUP_SLAVE_PTY; | 964 SETUP_SLAVE_PTY; |
965 # endif /* SETUP_SLAVE_PTY */ | 965 # endif /* SETUP_SLAVE_PTY */ |
966 | 966 |
967 # ifdef TIOCSCTTY | 967 # ifdef TIOCSCTTY |
968 /* We ignore the return value | 968 /* We ignore the return value |
969 because faith@cs.unc.edu says that is necessary on Linux. */ | 969 because faith@cs.unc.edu says that is necessary on Linux. */ |
970 assert (isatty (xforkin)); | 970 assert (isatty (xforkin)); |
971 ioctl (xforkin, TIOCSCTTY, 0); | 971 ioctl (xforkin, TIOCSCTTY, 0); |
1020 } | 1020 } |
1021 | 1021 |
1022 #ifdef WINDOWSNT | 1022 #ifdef WINDOWSNT |
1023 pid = child_setup (xforkin, xforkout, xforkout, | 1023 pid = child_setup (xforkin, xforkout, xforkout, |
1024 new_argv, current_dir); | 1024 new_argv, current_dir); |
1025 #else /* not WINDOWSNT */ | 1025 #else /* not WINDOWSNT */ |
1026 child_setup (xforkin, xforkout, xforkout, new_argv, current_dir); | 1026 child_setup (xforkin, xforkout, xforkout, new_argv, current_dir); |
1027 #endif /* not WINDOWSNT */ | 1027 #endif /* not WINDOWSNT */ |
1028 #endif /* not MSDOS */ | 1028 #endif /* not MSDOS */ |
1029 } | 1029 } |
1030 #ifdef EMACS_BTL | 1030 #ifdef EMACS_BTL |
1205 if (!NILP (Ffile_directory_p (program))) | 1205 if (!NILP (Ffile_directory_p (program))) |
1206 error ("Specified program for new process is a directory"); | 1206 error ("Specified program for new process is a directory"); |
1207 } | 1207 } |
1208 | 1208 |
1209 /* Nothing below here GCs so our string pointers shouldn't move. */ | 1209 /* Nothing below here GCs so our string pointers shouldn't move. */ |
1210 new_argv = (char **) alloca ((nargs - 1) * sizeof (char *)); | 1210 new_argv = alloca_array (char *, nargs - 1); |
1211 new_argv[0] = (char *) XSTRING_DATA (program); | 1211 new_argv[0] = (char *) XSTRING_DATA (program); |
1212 for (i = 3; i < nargs; i++) | 1212 for (i = 3; i < nargs; i++) |
1213 { | 1213 { |
1214 tem = args[i]; | 1214 tem = args[i]; |
1215 CHECK_STRING (tem); | 1215 CHECK_STRING (tem); |
1409 | 1409 |
1410 get_internet_address (host, &address, ERROR_ME); | 1410 get_internet_address (host, &address, ERROR_ME); |
1411 address.sin_port = port; | 1411 address.sin_port = port; |
1412 | 1412 |
1413 s = socket (address.sin_family, SOCK_STREAM, 0); | 1413 s = socket (address.sin_family, SOCK_STREAM, 0); |
1414 if (s < 0) | 1414 if (s < 0) |
1415 report_file_error ("error creating socket", list1 (name)); | 1415 report_file_error ("error creating socket", list1 (name)); |
1416 | 1416 |
1417 /* Turn off interrupts here -- see comments below. There used to | 1417 /* Turn off interrupts here -- see comments below. There used to |
1418 be code which called bind_polling_period() to slow the polling | 1418 be code which called bind_polling_period() to slow the polling |
1419 period down rather than turn it off, but that seems rather | 1419 period down rather than turn it off, but that seems rather |
1892 specially inside of the filedesc stream. */ | 1892 specially inside of the filedesc stream. */ |
1893 report_file_error ("writing to process", | 1893 report_file_error ("writing to process", |
1894 list1 (proc)); | 1894 list1 (proc)); |
1895 while (filedesc_stream_was_blocked (XLSTREAM (p->filedesc_stream))) | 1895 while (filedesc_stream_was_blocked (XLSTREAM (p->filedesc_stream))) |
1896 { | 1896 { |
1897 /* Buffer is full. Wait, accepting input; | 1897 /* Buffer is full. Wait, accepting input; |
1898 that may allow the program | 1898 that may allow the program |
1899 to finish doing output and read more. */ | 1899 to finish doing output and read more. */ |
1900 Faccept_process_output (Qnil, make_int (1), Qnil); | 1900 Faccept_process_output (Qnil, make_int (1), Qnil); |
1901 old_sigpipe = | 1901 old_sigpipe = |
1902 (SIGTYPE (*) (int)) signal (SIGPIPE, send_process_trap); | 1902 (SIGTYPE (*) (int)) signal (SIGPIPE, send_process_trap); |
1923 XSTRING_DATA (p->name)); | 1923 XSTRING_DATA (p->name)); |
1924 #endif | 1924 #endif |
1925 } | 1925 } |
1926 Lstream_flush (XLSTREAM (p->outstream)); | 1926 Lstream_flush (XLSTREAM (p->outstream)); |
1927 UNGCPRO; | 1927 UNGCPRO; |
1928 Lstream_delete (XLSTREAM (lstream)); | |
1928 } | 1929 } |
1929 | 1930 |
1930 DEFUN ("process-tty-name", Fprocess_tty_name, 1, 1, 0, /* | 1931 DEFUN ("process-tty-name", Fprocess_tty_name, 1, 1, 0, /* |
1931 Return the name of the terminal PROCESS uses, or nil if none. | 1932 Return the name of the terminal PROCESS uses, or nil if none. |
1932 This is the terminal that the process itself reads and writes on, | 1933 This is the terminal that the process itself reads and writes on, |
2312 { | 2313 { |
2313 /* Change the status of the process that was found. */ | 2314 /* Change the status of the process that was found. */ |
2314 p->tick++; | 2315 p->tick++; |
2315 process_tick++; | 2316 process_tick++; |
2316 update_status_from_wait_code (p, &w); | 2317 update_status_from_wait_code (p, &w); |
2317 | 2318 |
2318 /* If process has terminated, stop waiting for its output. */ | 2319 /* If process has terminated, stop waiting for its output. */ |
2319 if (WIFSIGNALED (w) || WIFEXITED (w)) | 2320 if (WIFSIGNALED (w) || WIFEXITED (w)) |
2320 { | 2321 { |
2321 if (p->infd >= 0) | 2322 if (p->infd >= 0) |
2322 { | 2323 { |
2346 } | 2347 } |
2347 } | 2348 } |
2348 } | 2349 } |
2349 | 2350 |
2350 exited_processes_index = 0; | 2351 exited_processes_index = 0; |
2351 | 2352 |
2352 EMACS_UNBLOCK_SIGNAL (SIGCHLD); | 2353 EMACS_UNBLOCK_SIGNAL (SIGCHLD); |
2353 } | 2354 } |
2354 | 2355 |
2355 /* On receipt of a signal that a child status has changed, | 2356 /* On receipt of a signal that a child status has changed, |
2356 loop asking about children with changed statuses until | 2357 loop asking about children with changed statuses until |
2379 | 2380 |
2380 while (sigchld_happened) | 2381 while (sigchld_happened) |
2381 { | 2382 { |
2382 int pid; | 2383 int pid; |
2383 int w; | 2384 int w; |
2384 | 2385 |
2385 /* Keep trying to get a status until we get a definitive result. */ | 2386 /* Keep trying to get a status until we get a definitive result. */ |
2386 do | 2387 do |
2387 { | 2388 { |
2388 errno = 0; | 2389 errno = 0; |
2389 #ifdef WNOHANG | 2390 #ifdef WNOHANG |
2390 # ifndef WUNTRACED | 2391 # ifndef WUNTRACED |
2391 # define WUNTRACED 0 | 2392 # define WUNTRACED 0 |
2398 #else /* not WNOHANG */ | 2399 #else /* not WNOHANG */ |
2399 pid = wait (&w); | 2400 pid = wait (&w); |
2400 #endif /* not WNOHANG */ | 2401 #endif /* not WNOHANG */ |
2401 } | 2402 } |
2402 while (pid <= 0 && errno == EINTR); | 2403 while (pid <= 0 && errno == EINTR); |
2403 | 2404 |
2404 if (pid <= 0) | 2405 if (pid <= 0) |
2405 break; | 2406 break; |
2406 | 2407 |
2407 if (exited_processes_index < MAX_EXITED_PROCESSES) | 2408 if (exited_processes_index < MAX_EXITED_PROCESSES) |
2408 { | 2409 { |
2409 exited_processes[exited_processes_index] = pid; | 2410 exited_processes[exited_processes_index] = pid; |
2410 exited_processes_status[exited_processes_index] = w; | 2411 exited_processes_status[exited_processes_index] = w; |
2411 exited_processes_index++; | 2412 exited_processes_index++; |
2412 } | 2413 } |
2413 | 2414 |
2414 /* On systems with WNOHANG, we just ignore the number | 2415 /* On systems with WNOHANG, we just ignore the number |
2415 of times that SIGCHLD was signalled, and keep looping | 2416 of times that SIGCHLD was signalled, and keep looping |
2416 until there are no more processes to wait on. If we | 2417 until there are no more processes to wait on. If we |
2417 don't have WNOHANG, we have to rely on the count in | 2418 don't have WNOHANG, we have to rely on the count in |
2418 SIGCHLD_HAPPENED. */ | 2419 SIGCHLD_HAPPENED. */ |
2433 will be called again, resulting in an infinite loop. The relevant | 2434 will be called again, resulting in an infinite loop. The relevant |
2434 portion of the documentation reads "SIGCLD signals will be queued | 2435 portion of the documentation reads "SIGCLD signals will be queued |
2435 and the signal-catching function will be continually reentered until | 2436 and the signal-catching function will be continually reentered until |
2436 the queue is empty". Invoking signal() causes the kernel to reexamine | 2437 the queue is empty". Invoking signal() causes the kernel to reexamine |
2437 the SIGCLD queue. Fred Fish, UniSoft Systems Inc. | 2438 the SIGCLD queue. Fred Fish, UniSoft Systems Inc. |
2438 | 2439 |
2439 (Note that now this only applies in SYS V Release 2 and before. | 2440 (Note that now this only applies in SYS V Release 2 and before. |
2440 On SYS V Release 3, we use sigset() to set the signal handler for | 2441 On SYS V Release 3, we use sigset() to set the signal handler for |
2441 the first time, and so we don't have to reestablish the signal handler | 2442 the first time, and so we don't have to reestablish the signal handler |
2442 in the handler below. On SYS V Release 4, we don't get this weirdo | 2443 in the handler below. On SYS V Release 4, we don't get this weirdo |
2443 behavior when we use sigaction(), which we do use.) */ | 2444 behavior when we use sigaction(), which we do use.) */ |
2462 | 2463 |
2463 #endif /* SIGCHLD */ | 2464 #endif /* SIGCHLD */ |
2464 | 2465 |
2465 /* Return a string describing a process status list. */ | 2466 /* Return a string describing a process status list. */ |
2466 | 2467 |
2467 static Lisp_Object | 2468 static Lisp_Object |
2468 status_message (struct Lisp_Process *p) | 2469 status_message (struct Lisp_Process *p) |
2469 { | 2470 { |
2470 Lisp_Object symbol = p->status_symbol; | 2471 Lisp_Object symbol = p->status_symbol; |
2471 int code = p->exit_code; | 2472 int code = p->exit_code; |
2472 int coredump = p->core_dumped; | 2473 int coredump = p->core_dumped; |
2591 msg = status_message (p); | 2592 msg = status_message (p); |
2592 | 2593 |
2593 /* If process is terminated, deactivate it or delete it. */ | 2594 /* If process is terminated, deactivate it or delete it. */ |
2594 symbol = p->status_symbol; | 2595 symbol = p->status_symbol; |
2595 | 2596 |
2596 if (EQ (symbol, Qsignal) | 2597 if (EQ (symbol, Qsignal) |
2597 || EQ (symbol, Qexit)) | 2598 || EQ (symbol, Qexit)) |
2598 { | 2599 { |
2599 if (delete_exited_processes) | 2600 if (delete_exited_processes) |
2600 remove_process (proc); | 2601 remove_process (proc); |
2601 else | 2602 else |
2833 return; | 2834 return; |
2834 } | 2835 } |
2835 } | 2836 } |
2836 #endif /* ! defined (SIGNALS_VIA_CHARACTERS) */ | 2837 #endif /* ! defined (SIGNALS_VIA_CHARACTERS) */ |
2837 | 2838 |
2838 #ifdef TIOCGPGRP | 2839 #ifdef TIOCGPGRP |
2839 /* Get the pgrp using the tty itself, if we have that. | 2840 /* Get the pgrp using the tty itself, if we have that. |
2840 Otherwise, use the pty to get the pgrp. | 2841 Otherwise, use the pty to get the pgrp. |
2841 On pfa systems, saka@pfu.fujitsu.co.JP writes: | 2842 On pfa systems, saka@pfu.fujitsu.co.JP writes: |
2842 "TIOCGPGRP symbol defined in sys/ioctl.h at E50. | 2843 "TIOCGPGRP symbol defined in sys/ioctl.h at E50. |
2843 But, TIOCGPGRP does not work on E50 ;-P works fine on E60" | 2844 But, TIOCGPGRP does not work on E50 ;-P works fine on E60" |
3199 case, p->pid is nil: p->pid is set at the same time that | 3200 case, p->pid is nil: p->pid is set at the same time that |
3200 the process is selected for input. */ | 3201 the process is selected for input. */ |
3201 #ifdef VMS | 3202 #ifdef VMS |
3202 { | 3203 { |
3203 VMS_PROC_STUFF *get_vms_process_pointer (), *vs; | 3204 VMS_PROC_STUFF *get_vms_process_pointer (), *vs; |
3204 if (outchannel >= 0) | 3205 if (outchannel >= 0) |
3205 sys$dassgn (outchannel); | 3206 sys$dassgn (outchannel); |
3206 vs = get_vms_process_pointer (XINT (p->pid)); | 3207 vs = get_vms_process_pointer (XINT (p->pid)); |
3207 if (vs) | 3208 if (vs) |
3208 give_back_vms_process_stuff (vs); | 3209 give_back_vms_process_stuff (vs); |
3209 } | 3210 } |
3367 defsymbol (&Qprocessp, "processp"); | 3368 defsymbol (&Qprocessp, "processp"); |
3368 defsymbol (&Qrun, "run"); | 3369 defsymbol (&Qrun, "run"); |
3369 defsymbol (&Qstop, "stop"); | 3370 defsymbol (&Qstop, "stop"); |
3370 defsymbol (&Qsignal, "signal"); | 3371 defsymbol (&Qsignal, "signal"); |
3371 /* Qexit is already defined by syms_of_eval | 3372 /* Qexit is already defined by syms_of_eval |
3372 * defsymbol (&Qexit, "exit"); | 3373 * defsymbol (&Qexit, "exit"); |
3373 */ | 3374 */ |
3374 defsymbol (&Qopen, "open"); | 3375 defsymbol (&Qopen, "open"); |
3375 defsymbol (&Qclosed, "closed"); | 3376 defsymbol (&Qclosed, "closed"); |
3376 | 3377 |
3377 DEFSUBR (Fprocessp); | 3378 DEFSUBR (Fprocessp); |