|
|
1.1 ! root 1: /* Asynchronous subprocess control for GNU Emacs. ! 2: Copyright (C) 1985 Richard M. Stallman. ! 3: ! 4: This file is part of GNU Emacs. ! 5: ! 6: GNU Emacs is distributed in the hope that it will be useful, ! 7: but WITHOUT ANY WARRANTY. No author or distributor ! 8: accepts responsibility to anyone for the consequences of using it ! 9: or for whether it serves any particular purpose or works at all, ! 10: unless he says so in writing. Refer to the GNU Emacs General Public ! 11: License for full details. ! 12: ! 13: Everyone is granted permission to copy, modify and redistribute ! 14: GNU Emacs, but only under the conditions described in the ! 15: GNU Emacs General Public License. A copy of this license is ! 16: supposed to have been given to you along with GNU Emacs so you ! 17: can know your rights and responsibilities. It should be in a ! 18: file named COPYING. Among other things, the copyright notice ! 19: and this notice must be preserved on all copies. */ ! 20: ! 21: ! 22: #include <signal.h> ! 23: ! 24: #include "config.h" ! 25: ! 26: #ifdef subprocesses ! 27: /* The entire file is within this conditional */ ! 28: ! 29: #include <stdio.h> ! 30: #include <errno.h> ! 31: #include <setjmp.h> ! 32: #include <sys/types.h> /* some typedefs are used in sys/file.h */ ! 33: #include <sys/file.h> ! 34: #include <sys/stat.h> ! 35: #ifdef BSD ! 36: #include <sys/ioctl.h> ! 37: #endif /* BSD */ ! 38: #ifdef USG ! 39: #include <termio.h> ! 40: #include <fcntl.h> ! 41: #endif /* USG */ ! 42: ! 43: #ifdef HAVE_TIMEVAL ! 44: #if defined (USG) && !defined (UNIPLUS) ! 45: #include <time.h> ! 46: #else ! 47: #include <sys/time.h> ! 48: #endif ! 49: #endif /* HAVE_TIMEVAL */ ! 50: ! 51: #if defined (HPUX) && defined (HAVE_PTYS) ! 52: #include <sys/ptyio.h> ! 53: #endif ! 54: ! 55: #undef NULL ! 56: #include "lisp.h" ! 57: #include "window.h" ! 58: #include "buffer.h" ! 59: #include "process.h" ! 60: #include "termhooks.h" ! 61: ! 62: /* Define SIGCHLD as an alias for SIGCLD. There are many conditionals ! 63: testing SIGCHLD. */ ! 64: ! 65: #if !defined (SIGCHLD) && defined (SIGCLD) ! 66: #define SIGCHLD SIGCLD ! 67: #endif /* SIGCLD */ ! 68: ! 69: /* Define the structure that the wait system call stores. ! 70: On many systems, there is a structure defined for this. ! 71: But on vanilla-ish USG systems there is not. */ ! 72: ! 73: #if !defined (BSD) && !defined (UNIPLUS) && !defined (STRIDE) ! 74: #define WAITTYPE int ! 75: #define WIFSTOPPED(w) ((w&0377) == 0177) ! 76: #define WIFSIGNALED(w) ((w&0377) != 0177 && (w&~0377) == 0) ! 77: #define WIFEXITED(w) ((w&0377) == 0) ! 78: #define WRETCODE(w) (w >> 8) ! 79: #define WSTOPSIG(w) (w >> 8) ! 80: #define WCOREDUMP(w) ((w&0200) != 0) ! 81: #define WTERMSIG(w) (w & 0377) ! 82: #else ! 83: #ifdef BSD4_1 ! 84: #include <wait.h> ! 85: #else ! 86: #include <sys/wait.h> ! 87: #endif /* not BSD 4.1 */ ! 88: #define WAITTYPE union wait ! 89: #define WRETCODE(w) w.w_retcode ! 90: #define WSTOPSIG(w) w.w_stopsig ! 91: #define WCOREDUMP(w) w.w_coredump ! 92: #define WTERMSIG(w) w.w_termsig ! 93: #endif ! 94: ! 95: extern errno; ! 96: extern sys_nerr; ! 97: extern char *sys_errlist[]; ! 98: ! 99: #ifndef BSD4_1 ! 100: extern char *sys_siglist[]; ! 101: #else ! 102: char *sys_siglist[] = ! 103: { ! 104: "bum signal!!", ! 105: "hangup", ! 106: "interrupt", ! 107: "quit", ! 108: "illegal instruction", ! 109: "trace trap", ! 110: "iot instruction", ! 111: "emt instruction", ! 112: "floating point exception", ! 113: "kill", ! 114: "bus error", ! 115: "segmentation violation", ! 116: "bad argument to system call", ! 117: "write on a pipe with no one to read it", ! 118: "alarm clock", ! 119: "software termination signal from kill", ! 120: "status signal", ! 121: "sendable stop signal not from tty", ! 122: "stop signal from tty", ! 123: "continue a stopped process", ! 124: "child status has changed", ! 125: "background read attempted from control tty", ! 126: "background write attempted from control tty", ! 127: "input record available at control tty", ! 128: "exceeded CPU time limit", ! 129: "exceeded file size limit" ! 130: }; ! 131: #endif ! 132: ! 133: #ifdef vipc ! 134: ! 135: #include "vipc.h" ! 136: extern int comm_server; ! 137: extern int net_listen_address; ! 138: #endif vipc ! 139: ! 140: ! 141: #ifdef SKTPAIR ! 142: #include <sys/socket.h> ! 143: #endif /* SKTPAIR */ ! 144: ! 145: int child_changed; /* Flag when a child process has ceased ! 146: to be */ ! 147: ! 148: /* Mask of bits indicating the descriptors that we wait for input on */ ! 149: ! 150: int input_wait_mask; ! 151: ! 152: int delete_exited_processes; ! 153: ! 154: #define MAXDESC 32 ! 155: ! 156: /* Indexed by descriptor, gives the process (if any) for that descriptor */ ! 157: Lisp_Object chan_process[MAXDESC]; ! 158: ! 159: /* Alist of elements (NAME . PROCESS) */ ! 160: Lisp_Object Vprocess_alist; ! 161: ! 162: Lisp_Object Qprocessp; ! 163: ! 164: Lisp_Object get_process (); ! 165: ! 166: /* Buffered-ahead input char from process, indexed by channel. ! 167: -1 means empty (no char is buffered). ! 168: Used on sys V where the only way to tell if there is any ! 169: output from the process is to read at least one char. ! 170: Always -1 on systems that support FIONREAD. */ ! 171: ! 172: int proc_buffered_char[MAXDESC]; ! 173: ! 174: #ifdef HAVE_PTYS ! 175: ! 176: /* Open an available pty, putting descriptor in *ptyv, ! 177: and return the file name of the pty. Return 0 if none available. */ ! 178: ! 179: char ptyname[24]; ! 180: ! 181: char * ! 182: pty (ptyv) ! 183: int *ptyv; ! 184: { ! 185: struct stat stb; ! 186: register c, i; ! 187: ! 188: for (c = FIRST_PTY_LETTER; c <= 'z'; c++) ! 189: for (i = 0; i < 16; i++) ! 190: { ! 191: #ifdef HPUX ! 192: sprintf (ptyname, "/dev/ptym/pty%c%x", c, i); ! 193: #else ! 194: sprintf (ptyname, "/dev/pty%c%x", c, i); ! 195: #endif /* not HPUX */ ! 196: if (stat (ptyname, &stb) < 0) ! 197: return 0; ! 198: ! 199: *ptyv = open (ptyname, O_RDWR | O_NDELAY, 0); ! 200: if (*ptyv >= 0) ! 201: { ! 202: /* check to make certain that both sides are available ! 203: this avoids a nasty yet stupid bug in rlogins */ ! 204: int x; ! 205: #ifdef HPUX ! 206: sprintf (ptyname, "/dev/pty/tty%c%x", c, i); ! 207: #else ! 208: sprintf (ptyname, "/dev/tty%c%x", c, i); ! 209: #endif /* not HPUX */ ! 210: #ifndef UNIPLUS ! 211: x = open (ptyname, O_RDWR | O_NDELAY, 0); ! 212: if (x < 0) ! 213: { ! 214: close (*ptyv); ! 215: continue; ! 216: } ! 217: close(x); ! 218: #endif /* not UNIPLUS */ ! 219: /* ! 220: * If the following statement is included, ! 221: * then a 0 length record is EOT, but no other ! 222: * control characters can be sent down the pty ! 223: * (e.g., ^S/^Q, ^O, etc.). If it is not ! 224: * included, then sending ^D down the pty-pipe ! 225: * makes a pretty good EOF. ! 226: */ ! 227: /* ioctl( *ptyv, TIOCREMOTE, &on ); /* for EOT */ ! 228: /* this is said to be unecessary, and to be harmful in 4.3. */ ! 229: /* ioctl (*ptyv, FIONBIO, &on); */ ! 230: return ptyname; ! 231: } ! 232: } ! 233: return 0; ! 234: } ! 235: ! 236: #endif /* HAVE_PTYS */ ! 237: ! 238: Lisp_Object ! 239: make_process (name) ! 240: Lisp_Object name; ! 241: { ! 242: Lisp_Object val, tem, name1; ! 243: register struct Lisp_Process *p; ! 244: char suffix[10]; ! 245: register int i; ! 246: ! 247: val = Fmake_vector (make_number ((sizeof (struct Lisp_Process) ! 248: - sizeof (int) - sizeof (struct Lisp_Vector *)) ! 249: / sizeof (Lisp_Object)), ! 250: Qnil); ! 251: XSETTYPE (val, Lisp_Process); ! 252: ! 253: p = XPROCESS (val); ! 254: XFASTINT (p->infd) = 0; ! 255: XFASTINT (p->outfd) = 0; ! 256: XFASTINT (p->pid) = 0; ! 257: XFASTINT (p->flags) = 0; ! 258: XFASTINT (p->reason) = 0; ! 259: p->mark = Fmake_marker (); ! 260: ! 261: /* If name is already in use, modify it until it is unused. */ ! 262: ! 263: name1 = name; ! 264: for (i = 1; ; i++) ! 265: { ! 266: tem = Fget_process (name1); ! 267: if (NULL (tem)) break; ! 268: sprintf (suffix, "<%d>", i); ! 269: name1 = concat2 (name, build_string (suffix)); ! 270: } ! 271: name = name1; ! 272: p->name = name; ! 273: Vprocess_alist = Fcons (Fcons (name, val), Vprocess_alist); ! 274: return val; ! 275: } ! 276: ! 277: remove_process (proc) ! 278: Lisp_Object proc; ! 279: { ! 280: Lisp_Object pair; ! 281: ! 282: pair = Frassq (proc, Vprocess_alist); ! 283: Vprocess_alist = Fdelq (pair, Vprocess_alist); ! 284: Fset_marker (XPROCESS (proc)->mark, Qnil, Qnil); ! 285: ! 286: deactivate_process (proc); ! 287: } ! 288: ! 289: DEFUN ("processp", Fprocessp, Sprocessp, 1, 1, 0, ! 290: "Return t if OBJECT is a process.") ! 291: (obj) ! 292: Lisp_Object obj; ! 293: { ! 294: return XTYPE (obj) == Lisp_Process ? Qt : Qnil; ! 295: } ! 296: ! 297: DEFUN ("get-process", Fget_process, Sget_process, 1, 1, 0, ! 298: "Return the process named NAME, or nil if there is none.") ! 299: (name) ! 300: Lisp_Object name; ! 301: { ! 302: if (XTYPE (name) == Lisp_Process) ! 303: return name; ! 304: CHECK_STRING (name, 0); ! 305: return Fcdr (Fassoc (name, Vprocess_alist)); ! 306: } ! 307: ! 308: DEFUN ("get-buffer-process", Fget_buffer_process, Sget_buffer_process, 1, 1, 0, ! 309: "Return the (or, a) process associated with BUFFER.\n\ ! 310: BUFFER may be a buffer or the name of one.") ! 311: (name) ! 312: Lisp_Object name; ! 313: { ! 314: Lisp_Object buf, tail, proc; ! 315: ! 316: if (NULL (name)) return Qnil; ! 317: buf = Fget_buffer (name); ! 318: if (NULL (buf)) return Qnil; ! 319: ! 320: for (tail = Vprocess_alist; !NULL (tail); tail = Fcdr (tail)) ! 321: { ! 322: proc = Fcdr (Fcar (tail)); ! 323: if (XTYPE (proc) == Lisp_Process && EQ (XPROCESS (proc)->buffer, buf)) ! 324: return proc; ! 325: } ! 326: return Qnil; ! 327: } ! 328: ! 329: /* This is how commands for the user decode process arguments */ ! 330: ! 331: Lisp_Object ! 332: get_process (name) ! 333: Lisp_Object name; ! 334: { ! 335: Lisp_Object proc; ! 336: if (NULL (name)) ! 337: proc = Fget_buffer_process (Fcurrent_buffer ()); ! 338: else ! 339: { ! 340: proc = Fget_process (name); ! 341: if (NULL (proc)) ! 342: proc = Fget_buffer_process (Fget_buffer (name)); ! 343: } ! 344: ! 345: if (!NULL (proc)) ! 346: return proc; ! 347: ! 348: if (NULL (name)) ! 349: error ("Current buffer has no process"); ! 350: else ! 351: error ("Process %s does not exist", XSTRING (name)->data); ! 352: /* NOTREACHED */ ! 353: } ! 354: ! 355: DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0, ! 356: "Delete PROCESS: kill it and forget about it immediately.\n\ ! 357: PROCESS may be a process or the name of one, or a buffer name.") ! 358: (proc) ! 359: Lisp_Object proc; ! 360: { ! 361: proc = get_process (proc); ! 362: if (XFASTINT (XPROCESS (proc)->infd)) ! 363: Fkill_process (proc, Qnil); ! 364: remove_process (proc); ! 365: return Qnil; ! 366: } ! 367: ! 368: DEFUN ("process-status", Fprocess_status, Sprocess_status, 1, 1, 0, ! 369: "Return the status of PROCESS: a symbol, one of these:\n\ ! 370: run -- for a process that is running.\n\ ! 371: stop -- for a process stopped but continuable.\n\ ! 372: exit -- for a process that has exited.\n\ ! 373: signal -- for a process that has got a fatal signal.\n\ ! 374: command -- for a command channel opened to Emacs by another process.\n\ ! 375: external -- for an i/o channel opened to Emacs by another process.\n\ ! 376: nil -- if arg is a process name and no such process exists.") ! 377: (proc) ! 378: Lisp_Object proc; ! 379: { ! 380: register struct Lisp_Process *p; ! 381: proc = Fget_process (proc); ! 382: if (NULL (proc)) ! 383: return proc; ! 384: p = XPROCESS (proc); ! 385: ! 386: switch (XFASTINT (p->flags) & PROC_STATUS) ! 387: { ! 388: case RUNNING: ! 389: if (!NULL (p->childp)) ! 390: return intern ("run"); ! 391: else if (!NULL (p->command_channel_p)) ! 392: return intern ("command"); ! 393: return intern ("external"); ! 394: ! 395: case EXITED: ! 396: return intern ("exit"); ! 397: ! 398: case SIGNALED: ! 399: return intern ("signal"); ! 400: ! 401: case STOPPED: ! 402: return intern ("stop"); ! 403: } ! 404: ! 405: /* NOTREACHED */ ! 406: } ! 407: ! 408: DEFUN ("process-id", Fprocess_id, Sprocess_id, 1, 1, 0, ! 409: "Return the process id of PROCESS.\n\ ! 410: This is the pid of the Unix process which PROCESS uses or talks to.") ! 411: (proc) ! 412: Lisp_Object proc; ! 413: { ! 414: CHECK_PROCESS (proc, 0); ! 415: return XPROCESS (proc)->pid; ! 416: } ! 417: ! 418: DEFUN ("process-name", Fprocess_name, Sprocess_name, 1, 1, 0, ! 419: "Return the name of PROCESS, as a string.\n\ ! 420: This is the name of the program invoked in PROCESS,\n\ ! 421: possibly modified to make it unique among process names.") ! 422: (proc) ! 423: Lisp_Object proc; ! 424: { ! 425: CHECK_PROCESS (proc, 0); ! 426: return XPROCESS (proc)->name; ! 427: } ! 428: ! 429: DEFUN ("process-command", Fprocess_command, Sprocess_command, 1, 1, 0, ! 430: "Return the command that was executed to start PROCESS.\n\ ! 431: This is a list of strings, the first string being the program executed\n\ ! 432: and the rest of the strings being the arguments given to it.\n\ ! 433: For a non-child channel, this is nil.") ! 434: (proc) ! 435: Lisp_Object proc; ! 436: { ! 437: CHECK_PROCESS (proc, 0); ! 438: return XPROCESS (proc)->command; ! 439: } ! 440: ! 441: DEFUN ("set-process-buffer", Fset_process_buffer, Sset_process_buffer, ! 442: 2, 2, 0, ! 443: "Set buffer associated with PROCESS to BUFFER (a buffer, or nil).") ! 444: (proc, buffer) ! 445: Lisp_Object proc, buffer; ! 446: { ! 447: CHECK_PROCESS (proc, 0); ! 448: if (!NULL (buffer)) ! 449: CHECK_BUFFER (buffer, 1); ! 450: XPROCESS (proc)->buffer = buffer; ! 451: return buffer; ! 452: } ! 453: ! 454: DEFUN ("process-buffer", Fprocess_buffer, Sprocess_buffer, ! 455: 1, 1, 0, ! 456: "Return the buffer PROCESS is associated with.\n\ ! 457: Output from PROCESS is inserted in this buffer\n\ ! 458: unless PROCESS has a filter.") ! 459: (proc) ! 460: Lisp_Object proc; ! 461: { ! 462: CHECK_PROCESS (proc, 0); ! 463: return XPROCESS (proc)->buffer; ! 464: } ! 465: ! 466: DEFUN ("process-mark", Fprocess_mark, Sprocess_mark, ! 467: 1, 1, 0, ! 468: "Return the marker for the end of the last output from PROCESS.") ! 469: (proc) ! 470: Lisp_Object proc; ! 471: { ! 472: CHECK_PROCESS (proc, 0); ! 473: return XPROCESS (proc)->mark; ! 474: } ! 475: ! 476: DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter, ! 477: 2, 2, 0, ! 478: "Give PROCESS the filter function FILTER; nil means no filter.\n\ ! 479: When a process has a filter, each time it does output\n\ ! 480: the entire string of output is passed to the filter.\n\ ! 481: The filter gets two arguments: the process and the string of output.\n\ ! 482: If the process has a filter, its buffer is not used for output.") ! 483: (proc, filter) ! 484: Lisp_Object proc, filter; ! 485: { ! 486: CHECK_PROCESS (proc, 0); ! 487: XPROCESS (proc)->filter = filter; ! 488: return filter; ! 489: } ! 490: ! 491: DEFUN ("process-filter", Fprocess_filter, Sprocess_filter, ! 492: 1, 1, 0, ! 493: "Returns the filter function of PROCESS; nil if none.\n\ ! 494: See set-process-filter for more info on filter functions.") ! 495: (proc) ! 496: Lisp_Object proc; ! 497: { ! 498: CHECK_PROCESS (proc, 0); ! 499: return XPROCESS (proc)->filter; ! 500: } ! 501: ! 502: DEFUN ("set-process-sentinel", Fset_process_sentinel, Sset_process_sentinel, ! 503: 2, 2, 0, ! 504: "Give PROCESS the sentinel SENTINEL; nil for none.\n\ ! 505: The sentinel is called as a function when the process changes state.\n\ ! 506: It gets two arguments: the process, and a string describing the change.") ! 507: (proc, sentinel) ! 508: Lisp_Object proc, sentinel; ! 509: { ! 510: CHECK_PROCESS (proc, 0); ! 511: XPROCESS (proc)->sentinel = sentinel; ! 512: return sentinel; ! 513: } ! 514: ! 515: DEFUN ("process-sentinel", Fprocess_sentinel, Sprocess_sentinel, ! 516: 1, 1, 0, ! 517: "Return the sentinel of PROCESS; nil if none.\n\ ! 518: See set-process-sentinel for more info on sentinels.") ! 519: (proc) ! 520: Lisp_Object proc; ! 521: { ! 522: CHECK_PROCESS (proc, 0); ! 523: return XPROCESS (proc)->sentinel; ! 524: } ! 525: ! 526: DEFUN ("process-kill-without-query", Fprocess_kill_without_query, ! 527: Sprocess_kill_without_query, 1, 1, 0, ! 528: "Say no query needed if this process is running when Emacs is exited.") ! 529: (proc) ! 530: Lisp_Object proc; ! 531: { ! 532: CHECK_PROCESS (proc, 0); ! 533: XPROCESS (proc)->kill_without_query = Qt; ! 534: return Qt; ! 535: } ! 536: ! 537: Lisp_Object ! 538: list_processes_1 () ! 539: { ! 540: Lisp_Object tail, proc, minspace, tem, tem1; ! 541: register struct buffer *old = bf_cur; ! 542: register struct Lisp_Process *p; ! 543: register int state; ! 544: char tembuf[10]; ! 545: ! 546: XFASTINT (minspace) = 1; ! 547: ! 548: SetBfp (XBUFFER (Vstandard_output)); ! 549: Fbuffer_flush_undo (Vstandard_output); ! 550: ! 551: bf_cur->truncate_lines = Qt; ! 552: ! 553: write_string ("\ ! 554: Proc Status Buffer Command\n\ ! 555: ---- ------ ------ -------\n", -1); ! 556: ! 557: for (tail = Vprocess_alist; !NULL (tail); tail = Fcdr (tail)) ! 558: { ! 559: proc = Fcdr (Fcar (tail)); ! 560: p = XPROCESS (proc); ! 561: if (NULL (p->childp)) ! 562: continue; ! 563: ! 564: Finsert (1, &p->name); ! 565: Findent_to (make_number (13), minspace); ! 566: ! 567: state = XFASTINT (p->flags) & PROC_STATUS; ! 568: switch (state) ! 569: { ! 570: case RUNNING: ! 571: write_string ("Run", -1); ! 572: break; ! 573: ! 574: case STOPPED: ! 575: write_string ("Stop", -1); ! 576: break; ! 577: ! 578: case EXITED: ! 579: write_string ("Exit", -1); ! 580: if (XFASTINT (p->reason)) ! 581: { ! 582: sprintf (tembuf, " %d", XFASTINT (p->reason)); ! 583: write_string (tembuf, -1); ! 584: } ! 585: remove_process (proc); ! 586: break; ! 587: ! 588: case SIGNALED: ! 589: if (XFASTINT (p->reason) < NSIG) ! 590: write_string (sys_siglist [XFASTINT (p->reason)], -1); ! 591: else ! 592: write_string ("Signal", -1); ! 593: remove_process (proc); ! 594: } ! 595: ! 596: Findent_to (make_number (22), minspace); ! 597: if (NULL (p->buffer)) ! 598: InsStr ("(none)"); ! 599: else if (NULL (XBUFFER (p->buffer)->name)) ! 600: InsStr ("(Killed)"); ! 601: else ! 602: Finsert (1, &XBUFFER (p->buffer)->name); ! 603: ! 604: Findent_to (make_number (37), minspace); ! 605: ! 606: tem = p->command; ! 607: while (1) ! 608: { ! 609: tem1 = Fcar (tem); ! 610: Finsert (1, &tem1); ! 611: tem = Fcdr (tem); ! 612: if (NULL (tem)) ! 613: break; ! 614: InsStr (" "); ! 615: } ! 616: ! 617: InsStr ("\n"); ! 618: } ! 619: ! 620: SetBfp (old); ! 621: return Qnil; ! 622: } ! 623: ! 624: DEFUN ("list-processes", Flist_processes, Slist_processes, 0, 0, "", ! 625: "Display a list of all processes.\n\ ! 626: \(Any processes listed as Exited or Signaled are actually eliminated\n\ ! 627: after the listing is made.)") ! 628: () ! 629: { ! 630: internal_with_output_to_temp_buffer ("*Process List*", ! 631: list_processes_1, Qnil); ! 632: return Qnil; ! 633: } ! 634: ! 635: DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0, ! 636: "Start a program in a subprocess. Return the process object for it.\n\ ! 637: First arg is name for process. It is modified if nec to make it unique.\n\ ! 638: Second arg is buffer to associate with the process (or buffer name).\n\ ! 639: Process output goes at end of that buffer, unless you specify\n\ ! 640: an output stream or filter function to handle the output.\n\ ! 641: Third arg is program file name. It is searched for as in the shell.\n\ ! 642: Remaining arguments are strings to give program as arguments.") ! 643: (nargs, args) ! 644: int nargs; ! 645: Lisp_Object *args; ! 646: { ! 647: Lisp_Object buffer, name, program, proc, tem; ! 648: register unsigned char **new_argv; ! 649: register int i; ! 650: ! 651: name = args[0]; ! 652: CHECK_STRING (name, 0); ! 653: ! 654: buffer = args[1]; ! 655: program = args[2]; ! 656: ! 657: CHECK_STRING (program, 2); ! 658: ! 659: new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *)); ! 660: ! 661: for (i = 3; i < nargs; i++) ! 662: { ! 663: tem = args[i]; ! 664: CHECK_STRING (tem, i); ! 665: new_argv[i - 2] = XSTRING (tem)->data; ! 666: } ! 667: new_argv[i - 2] = 0; ! 668: new_argv[0] = XSTRING (program)->data; ! 669: ! 670: /* If program file name is not absolute, search our path for it */ ! 671: if (new_argv[0][0] != '/') ! 672: { ! 673: tem = Qnil; ! 674: openp (Vexec_path, program, "", &tem, 1); ! 675: if (NULL (tem)) ! 676: report_file_error ("Searching for program", Fcons (program, Qnil)); ! 677: new_argv[0] = XSTRING (tem)->data; ! 678: } ! 679: ! 680: if (!NULL (buffer)) ! 681: buffer = Fget_buffer_create (buffer); ! 682: proc = make_process (name); ! 683: ! 684: XPROCESS (proc)->childp = Qt; ! 685: XPROCESS (proc)->command_channel_p = Qnil; ! 686: XPROCESS (proc)->buffer = buffer; ! 687: XPROCESS (proc)->sentinel = Qnil; ! 688: XPROCESS (proc)->filter = Qnil; ! 689: XPROCESS (proc)->command = Flist (nargs - 2, args + 2); ! 690: ! 691: create_process (proc, new_argv); ! 692: ! 693: return proc; ! 694: } ! 695: ! 696: create_process_1 (signo) ! 697: int signo; ! 698: { ! 699: #ifdef USG ! 700: /* USG systems forget handlers when they are used; ! 701: must reestablish each time */ ! 702: signal (signo, create_process_1); ! 703: #endif /* USG */ ! 704: } ! 705: ! 706: create_process (process, new_argv) ! 707: Lisp_Object process; ! 708: char **new_argv; ! 709: { ! 710: int pid, inchannel, outchannel, forkin, forkout; ! 711: int sv[2]; ! 712: int (*sigchld)(); ! 713: ! 714: #ifdef HAVE_PTYS ! 715: char *ptyname; ! 716: ! 717: ptyname = pty (&inchannel); ! 718: outchannel = inchannel; ! 719: if (ptyname) ! 720: { ! 721: forkout = forkin = open (ptyname, O_RDWR, 0); ! 722: if (forkin < 0) ! 723: report_file_error ("Opening pty", Qnil); ! 724: } ! 725: else ! 726: #endif /* HAVE_PTYS */ ! 727: #ifdef SKTPAIR ! 728: { ! 729: if (socketpair (AF_UNIX, SOCK_STREAM, 0, sv) < 0) ! 730: report_file_error ("Opening socketpair", Qnil); ! 731: outchannel = inchannel = sv[0]; ! 732: forkout = forkin = sv[1]; ! 733: } ! 734: #else /* not SKTPAIR */ ! 735: { ! 736: pipe (sv); ! 737: inchannel = sv[0]; ! 738: forkout = sv[1]; ! 739: pipe (sv); ! 740: outchannel = sv[1]; ! 741: forkin = sv[0]; ! 742: } ! 743: #endif /* not SKTPAIR */ ! 744: ! 745: #ifdef FIOCLEX ! 746: ioctl (inchannel, FIOCLEX, 0); ! 747: ioctl (outchannel, FIOCLEX, 0); ! 748: #endif ! 749: ! 750: /* Stride people say it's a mystery why this is needed ! 751: as well as the O_NDELAY, but that it fails without this. */ ! 752: #ifdef STRIDE ! 753: { ! 754: int one = 1; ! 755: ioctl (inchannel, FIONBIO, &one); ! 756: } ! 757: #endif ! 758: ! 759: #ifdef O_NDELAY ! 760: fcntl (inchannel, F_SETFL, O_NDELAY); ! 761: #endif ! 762: ! 763: chan_process[inchannel] = process; ! 764: XFASTINT (XPROCESS (process)->infd) = inchannel; ! 765: XFASTINT (XPROCESS (process)->outfd) = outchannel; ! 766: XFASTINT (XPROCESS (process)->flags) = RUNNING; ! 767: ! 768: input_wait_mask |= ChannelMask (inchannel); ! 769: ! 770: /* Delay interrupts until we have a chance to store ! 771: the new fork's pid in its process structure */ ! 772: #ifdef SIGCHLD ! 773: #ifdef BSD4_1 ! 774: sighold (SIGCHLD); ! 775: #else /* not BSD4_1 */ ! 776: #if defined (BSD) || defined (UNIPLUS) ! 777: sigsetmask (1 << (SIGCHLD - 1)); ! 778: #else /* ordinary USG */ ! 779: sigchld = signal (SIGCHLD, SIG_DFL); ! 780: #endif /* ordinary USG */ ! 781: #endif /* not BSD4_1 */ ! 782: #endif /* SIGCHLD */ ! 783: ! 784: pid = vfork (); ! 785: if (pid == 0) ! 786: { ! 787: int xforkin = forkin; ! 788: int xforkout = forkout; ! 789: #ifdef HAVE_PTYS ! 790: #ifdef TIOCNOTTY ! 791: /* In 4.3BSD, the TIOCSPGRP bug has been fixed, and now you ! 792: can do TIOCSPGRP only to the process's controlling tty. ! 793: We must make the pty terminal the controlling tty of the child. */ ! 794: if (ptyname) ! 795: { ! 796: /* I wonder: would just ioctl (0, TIOCNOTTY, 0) work here? ! 797: I can't test it since I don't have 4.3. */ ! 798: int j = open ("/dev/tty", O_RDWR, 0); ! 799: ioctl (j, TIOCNOTTY, 0); ! 800: close (j); ! 801: ! 802: #ifndef UNIPLUS ! 803: /* I wonder if close (open (ptyname, ...)) would work? */ ! 804: close (xforkin); ! 805: xforkout = xforkin = open (ptyname, O_RDWR, 0); ! 806: ! 807: if (xforkin < 0) ! 808: abort (); ! 809: #endif /* not UNIPLUS */ ! 810: } ! 811: #endif /* TIOCNOTTY */ ! 812: #endif /* HAVE_PTYS */ ! 813: child_setup (xforkin, xforkout, xforkout, new_argv); ! 814: } ! 815: ! 816: /* If the subfork execv fails, and it exits, ! 817: this close hangs. I don't know why. ! 818: So have an interrupt jar it loose. */ ! 819: signal (SIGALRM, create_process_1); ! 820: alarm (1); ! 821: close (forkin); ! 822: alarm (0); ! 823: if (forkin != forkout) ! 824: close (forkout); ! 825: ! 826: if (pid < 0) ! 827: { ! 828: remove_process (process); ! 829: report_file_error ("Doing vfork", Qnil); ! 830: } ! 831: ! 832: XFASTINT (XPROCESS (process)->pid) = pid; ! 833: ! 834: #ifdef SIGCHLD ! 835: #ifdef BSD4_1 ! 836: sigrelse (SIGCHLD); ! 837: #else /* not BSD4_1 */ ! 838: #if defined (BSD) || defined (UNIPLUS) ! 839: sigsetmask (0); ! 840: #else /* ordinary USG */ ! 841: signal (SIGCHLD, sigchld); ! 842: #endif /* ordinary USG */ ! 843: #endif /* not BSD4_1 */ ! 844: #endif /* SIGCHLD */ ! 845: } ! 846: ! 847: deactivate_process (proc) ! 848: Lisp_Object proc; ! 849: { ! 850: register int inchannel, outchannel; ! 851: register struct Lisp_Process *p = XPROCESS (proc); ! 852: ! 853: inchannel = XFASTINT (p->infd); ! 854: outchannel = XFASTINT (p->outfd); ! 855: ! 856: if (inchannel) ! 857: { ! 858: /* Beware SIGCHLD hereabouts. */ ! 859: flush_pending_output (inchannel); ! 860: close (inchannel); ! 861: if (outchannel && outchannel != inchannel) ! 862: close (outchannel); ! 863: ! 864: XFASTINT (p->infd) = 0; ! 865: XFASTINT (p->outfd) = 0; ! 866: chan_process[inchannel] = Qnil; ! 867: input_wait_mask &= ~ChannelMask (inchannel); ! 868: } ! 869: } ! 870: ! 871: DEFUN ("accept-process-output", Faccept_process_output, Saccept_process_output, ! 872: 0, 1, 0, ! 873: "Allow any pending output from subprocesses to be read by Emacs.\n\ ! 874: It is read into the processs' buffers or given to their filter functions.\n\ ! 875: Non-nil arg PROCESS means do not return until some output has been received\n\ ! 876: from PROCESS.") ! 877: (proc) ! 878: Lisp_Object proc; ! 879: { ! 880: if (NULL (proc)) ! 881: wait_reading_process_input (-1, 0, 0); ! 882: else ! 883: { ! 884: proc = get_process (proc); ! 885: wait_reading_process_input (0, 10 + XFASTINT (XPROCESS (proc)->infd), ! 886: 0); ! 887: } ! 888: return Qnil; ! 889: } ! 890: ! 891: /* Read and dispose of subprocess output ! 892: while waiting for timeout to elapse and/or keyboard input to be available. ! 893: ! 894: time_limit is the timeout in seconds, or zero for no limit. ! 895: -1 means gobble data available immediately but don't wait for any. ! 896: ! 897: read_kbd is 1 to return when input is available. ! 898: Negative means caller will actually read the input. ! 899: 10 + I means wait until input received from channel I. ! 900: ! 901: do_display means redisplay should be done to show ! 902: subprocess output that arrives. */ ! 903: ! 904: wait_reading_process_input (time_limit, read_kbd, do_display) ! 905: int time_limit, read_kbd, do_display; ! 906: { ! 907: register int channel, nfds, m; ! 908: int Available = 0; ! 909: int Exception; ! 910: Lisp_Object proc; ! 911: #ifdef HAVE_TIMEVAL ! 912: struct timeval timeout, end_time, garbage; ! 913: #else ! 914: long timeout, end_time, temp; ! 915: #endif /* not HAVE_TIMEVAL */ ! 916: int Atemp; ! 917: int wait_channel = 0; ! 918: extern kbd_count; ! 919: ! 920: if (read_kbd > 10) ! 921: { ! 922: wait_channel = read_kbd - 10; ! 923: read_kbd = 0; ! 924: } ! 925: ! 926: /* Since we may need to wait several times, ! 927: compute the absolute time to return at. */ ! 928: if (time_limit) ! 929: { ! 930: #ifdef HAVE_TIMEVAL ! 931: gettimeofday (&end_time, &garbage); ! 932: end_time.tv_sec += time_limit; ! 933: #else /* not HAVE_TIMEVAL */ ! 934: time (&end_time); ! 935: end_time += time_limit; ! 936: #endif /* not HAVE_TIMEVAL */ ! 937: } ! 938: ! 939: while (1) ! 940: { ! 941: /* If calling from keyboard input, do not quit ! 942: since we want to return C-g as an input character. ! 943: Otherwise, do pending quit if requested. */ ! 944: if (read_kbd >= 0) ! 945: QUIT; ! 946: ! 947: /* If status of something has changed, and no input is available, ! 948: notify the user of the change right away */ ! 949: if (child_changed && do_display) ! 950: { ! 951: Atemp = input_wait_mask; ! 952: #ifdef HAVE_TIMEVAL ! 953: timeout.tv_sec=0; timeout.tv_usec=0; ! 954: #else /* not HAVE_TIMEVAL */ ! 955: timeout = 0; ! 956: #endif /* not HAVE_TIMEVAL */ ! 957: if (select (MAXDESC, &Atemp, 0, 0, &timeout) <= 0) ! 958: change_msgs(); ! 959: } ! 960: ! 961: if (fix_screen_hook) ! 962: (*fix_screen_hook) (); ! 963: ! 964: /* Compute time from now till when time limit is up */ ! 965: /* Exit if already run out */ ! 966: if (time_limit == -1) ! 967: { ! 968: /* -1 specified for timeout means ! 969: gobble output available now ! 970: but don't wait at all. */ ! 971: time_limit = -2; ! 972: #ifdef HAVE_TIMEVAL ! 973: timeout.tv_sec = 0; ! 974: timeout.tv_usec = 0; ! 975: #else ! 976: timeout = 0; ! 977: #endif /* not HAVE_TIMEVAL */ ! 978: } ! 979: else if (time_limit) ! 980: { ! 981: #ifdef HAVE_TIMEVAL ! 982: gettimeofday (&timeout, &garbage); ! 983: timeout.tv_sec = end_time.tv_sec - timeout.tv_sec; ! 984: timeout.tv_usec = end_time.tv_usec - timeout.tv_usec; ! 985: if (timeout.tv_usec < 0) ! 986: timeout.tv_usec += 1000000, ! 987: timeout.tv_sec--; ! 988: if (timeout.tv_sec < 0) ! 989: break; ! 990: #else /* not HAVE_TIMEVAL */ ! 991: time (&temp); ! 992: timeout = end_time - temp; ! 993: if (timeout < 0) ! 994: break; ! 995: #endif /* not HAVE_TIMEVAL */ ! 996: } ! 997: else ! 998: { ! 999: #ifdef HAVE_TIMEVAL ! 1000: /* If no real timeout, loop sleeping with a big timeout ! 1001: so that input interrupt can wake us up by zeroing it */ ! 1002: timeout.tv_sec = 100; ! 1003: timeout.tv_usec = 0; ! 1004: #else /* not HAVE_TIMEVAL */ ! 1005: timeout = 100000; /* 100000 recognized by the select emulator */ ! 1006: #endif /* not HAVE_TIMEVAL */ ! 1007: } ! 1008: ! 1009: /* Cause C-g and alarm signals to take immediate action, ! 1010: and cause input available signals to zero out timeout */ ! 1011: if (read_kbd < 0) ! 1012: set_waiting_for_input (&timeout); ! 1013: ! 1014: /* Wait till there is something to do */ ! 1015: ! 1016: Available = Exception = input_wait_mask; ! 1017: if (!read_kbd) ! 1018: Available &= ~1; ! 1019: ! 1020: if (read_kbd && kbd_count) ! 1021: nfds = 0; ! 1022: else ! 1023: nfds = select (MAXDESC, &Available, 0, &Exception, &timeout); ! 1024: ! 1025: if (fix_screen_hook) ! 1026: (*fix_screen_hook) (); ! 1027: ! 1028: /* Make C-g and alarm signals set flags again */ ! 1029: clear_waiting_for_input (); ! 1030: ! 1031: if (time_limit && nfds == 0) /* timeout elapsed */ ! 1032: break; ! 1033: if (nfds < 0) ! 1034: { ! 1035: if (errno == EINTR) ! 1036: Available = 0; ! 1037: else if (errno == EBADF) ! 1038: abort (); ! 1039: else ! 1040: error("select error: %s", sys_errlist[errno]); ! 1041: } ! 1042: ! 1043: /* Check for keyboard input */ ! 1044: /* If there is any, return immediately ! 1045: to give it higher priority than subprocesses */ ! 1046: ! 1047: if (read_kbd && (kbd_count || !NULL (Vquit_flag))) ! 1048: break; ! 1049: ! 1050: if (read_kbd && (Available & ChannelMask (0))) ! 1051: break; ! 1052: ! 1053: #ifdef vipc ! 1054: /* Check for connection from other process */ ! 1055: ! 1056: if (Available & ChannelMask (comm_server)) ! 1057: { ! 1058: Available &= ~(ChannelMask (comm_server)); ! 1059: create_commchan (); ! 1060: } ! 1061: #endif vipc ! 1062: ! 1063: /* Check for data from a process or a command channel */ ! 1064: ! 1065: for (channel = 3; Available && channel < MAXDESC; channel++) ! 1066: { ! 1067: m = ChannelMask (channel); ! 1068: if (m & Available) ! 1069: { ! 1070: Available &= ~m; ! 1071: /* If waiting for this channel, ! 1072: arrange to return as soon as no more input ! 1073: to be processed. No more waiting. */ ! 1074: if (wait_channel == channel) ! 1075: { ! 1076: wait_channel = 0; ! 1077: time_limit = -1; ! 1078: } ! 1079: proc = chan_process[channel]; ! 1080: if (NULL (proc)) ! 1081: continue; ! 1082: ! 1083: #ifdef vipc ! 1084: /* It's a command channel */ ! 1085: if (!NULL (XPROCESS (proc)->command_channel_p)) ! 1086: { ! 1087: ProcessCommChan (channel, proc); ! 1088: if (NULL (XPROCESS (proc)->command_channel_p)) ! 1089: { ! 1090: /* It has ceased to be a command channel! */ ! 1091: int bytes_available; ! 1092: if (ioctl (channel, FIONREAD, &bytes_available) < 0) ! 1093: bytes_available = 0; ! 1094: if (bytes_available) ! 1095: Available |= m; ! 1096: } ! 1097: continue; ! 1098: } ! 1099: #endif vipc ! 1100: ! 1101: /* Read data from the process, starting with our ! 1102: buffered-ahead character if we have one. */ ! 1103: ! 1104: if (read_process_output (proc, channel) > 0) ! 1105: { ! 1106: if (do_display) ! 1107: DoDsp (1); ! 1108: } ! 1109: else ! 1110: { ! 1111: /* Preserve status of processes already terminated. */ ! 1112: child_changed++; ! 1113: deactivate_process (proc); ! 1114: ! 1115: /* ! 1116: * With pty:s, when the parent process of a pty exits we are notified, ! 1117: * just as we would be with any of our other children. After the process ! 1118: * exits, select() will indicate that we can read the channel. When we ! 1119: * do this, read() returns 0. Upon receiving this, we close the channel. ! 1120: * ! 1121: * For external channels, when the peer closes the connection, select() ! 1122: * will indicate that we can read the channel. When we do this, read() ! 1123: * returns -1 with errno = ECONNRESET. Since we never get notified of ! 1124: * this via wait3(), we must explictly mark the process as having exited. ! 1125: */ ! 1126: if ((XFASTINT (XPROCESS (proc)->flags) & PROC_STATUS) ! 1127: == RUNNING) ! 1128: { ! 1129: XFASTINT (XPROCESS (proc)->flags) = EXITED | CHANGED; ! 1130: XFASTINT (XPROCESS (proc)->reason) = 0; ! 1131: } ! 1132: } ! 1133: } ! 1134: } /* end for */ ! 1135: } /* end while */ ! 1136: } ! 1137: ! 1138: /* Read pending output from the process channel, ! 1139: starting with our buffered-ahead character if we have one. ! 1140: Yield number of characters read. */ ! 1141: ! 1142: read_process_output (proc, channel) ! 1143: Lisp_Object proc; ! 1144: register int channel; ! 1145: { ! 1146: register int count; ! 1147: register int total = 0; ! 1148: char buf[1024]; ! 1149: ! 1150: while (1) ! 1151: { ! 1152: if (proc_buffered_char[channel] < 0) ! 1153: count = read (channel, buf, sizeof buf); ! 1154: else ! 1155: { ! 1156: buf[0] = proc_buffered_char[channel]; ! 1157: proc_buffered_char[channel] = -1; ! 1158: count = read (channel, buf + 1, sizeof buf - 1) + 1; ! 1159: } ! 1160: ! 1161: if (count <= 0) ! 1162: break; ! 1163: ! 1164: total += count; ! 1165: handle_process_output (proc, buf, count); ! 1166: } ! 1167: return total; ! 1168: } ! 1169: ! 1170: /* ! 1171: * Output has been received from a process on "chan" and should be stuffed in ! 1172: * the correct buffer. ! 1173: */ ! 1174: handle_process_output (proc, chars, nchars) ! 1175: Lisp_Object proc; ! 1176: char *chars; ! 1177: int nchars; ! 1178: { ! 1179: Lisp_Object outstream; ! 1180: register struct buffer *old = bf_cur; ! 1181: register struct Lisp_Process *p = XPROCESS (proc); ! 1182: register int opoint; ! 1183: ! 1184: outstream = p->filter; ! 1185: if (!NULL (outstream)) ! 1186: { ! 1187: call2 (outstream, proc, make_string (chars, nchars)); ! 1188: return 1; ! 1189: } ! 1190: ! 1191: /* If no filter, write into buffer if it isn't dead. */ ! 1192: if (!NULL (p->buffer) && !NULL (XBUFFER (p->buffer)->name)) ! 1193: { ! 1194: Fset_buffer (p->buffer); ! 1195: opoint = point; ! 1196: ! 1197: /* Insert new output into buffer ! 1198: at the current end-of-output marker, ! 1199: thus preserving logical ordering of input and output. */ ! 1200: if (XMARKER (p->mark)->buffer) ! 1201: SetPoint (marker_position (p->mark)); ! 1202: else ! 1203: SetPoint (NumCharacters + 1); ! 1204: if (point <= opoint) ! 1205: opoint += nchars; ! 1206: ! 1207: InsCStr (chars, nchars); ! 1208: Fset_marker (p->mark, make_number (point), p->buffer); ! 1209: RedoModes++; ! 1210: ! 1211: SetPoint (opoint); ! 1212: SetBfp (old); ! 1213: } ! 1214: else return 0; ! 1215: ! 1216: /* Old feature was, delete early chars in chunks if ! 1217: buffer gets bigger that ProcessBufferSize. ! 1218: This feature is flushed */ ! 1219: ! 1220: return 1; ! 1221: } ! 1222: ! 1223: /* Sending data to subprocess */ ! 1224: ! 1225: jmp_buf send_process_frame; ! 1226: ! 1227: send_process_trap () ! 1228: { ! 1229: #ifdef BSD4_1 ! 1230: sigrelse (SIGPIPE); ! 1231: sigrelse (SIGALRM); ! 1232: #endif /* BSD4_1 */ ! 1233: longjmp (send_process_frame, 1); ! 1234: } ! 1235: ! 1236: send_process_1 (proc, buf, len) ! 1237: Lisp_Object proc; ! 1238: char *buf; ! 1239: int len; ! 1240: { ! 1241: /* Don't use register vars; longjmp can lose them. */ ! 1242: int rv; ! 1243: unsigned char *procname = XSTRING (XPROCESS (proc)->name)->data; ! 1244: ! 1245: if ((XFASTINT (XPROCESS (proc)->flags) & PROC_STATUS) != RUNNING) ! 1246: error ("Process %s not running", procname); ! 1247: ! 1248: signal (SIGPIPE, send_process_trap); ! 1249: ! 1250: if (!setjmp (send_process_frame)) ! 1251: while (len > 0) ! 1252: { ! 1253: rv = write (XFASTINT (XPROCESS (proc)->outfd), buf, len); ! 1254: if (rv < 0) ! 1255: break; ! 1256: buf += rv; ! 1257: len -= rv; ! 1258: } ! 1259: else ! 1260: { ! 1261: signal (SIGPIPE, SIG_DFL); ! 1262: XFASTINT (XPROCESS (proc)->flags) = EXITED | CHANGED; ! 1263: deactivate_process (proc); ! 1264: error ("SIGPIPE raised on process %s; closed it", procname); ! 1265: } ! 1266: ! 1267: signal (SIGPIPE, SIG_DFL); ! 1268: ! 1269: if (rv < 0) ! 1270: report_file_error ("writing to process", Fcons (proc, Qnil)); ! 1271: } ! 1272: ! 1273: /*** Is it really safe for this to get an error ? */ ! 1274: ! 1275: send_process (proc, buf, count) ! 1276: Lisp_Object proc; ! 1277: char *buf; ! 1278: int count; ! 1279: { ! 1280: #ifdef vipc ! 1281: struct { int checkword, type, datalen; } header; ! 1282: ! 1283: if (!NULL (XPROCESS (proc)->command_channel_p)) ! 1284: { ! 1285: checkword = UNIQUE_FROB; ! 1286: type = VIPC_MESG; ! 1287: datalen = count; ! 1288: send_process_1 (proc, &header, sizeof header); ! 1289: } ! 1290: #endif vipc ! 1291: send_process_1 (proc, buf, count); ! 1292: } ! 1293: ! 1294: DEFUN ("send-region", Fsend_region, Ssend_region, 3, 3, 0, ! 1295: "Send current contents of region as input to PROCESS.\n\ ! 1296: PROCESS may be a process name.\n\ ! 1297: Called from program, takes three arguments, PROCESS, START and END.") ! 1298: (process, start, end) ! 1299: Lisp_Object process, start, end; ! 1300: { ! 1301: Lisp_Object proc; ! 1302: proc = get_process (process); ! 1303: validate_region (&start, &end); ! 1304: ! 1305: if (XINT (start) < bf_s1 && XINT (end) >= bf_s1) ! 1306: GapTo (start); ! 1307: ! 1308: send_process (proc, &CharAt (XINT (start)), XINT (end) - XINT (start)); ! 1309: ! 1310: return Qnil; ! 1311: } ! 1312: ! 1313: DEFUN ("send-string", Fsend_string, Ssend_string, 2, 2, 0, ! 1314: "Send PROCESS the contents of STRING as input.\n\ ! 1315: PROCESS may be a process name.") ! 1316: (process, string) ! 1317: Lisp_Object process, string; ! 1318: { ! 1319: Lisp_Object proc; ! 1320: CHECK_STRING (string, 1); ! 1321: proc = get_process (process); ! 1322: send_process (proc, XSTRING (string)->data, XSTRING (string)->size); ! 1323: return Qnil; ! 1324: } ! 1325: ! 1326: /* send a signal number SIGNO to PROCESS. ! 1327: CURRENT_GROUP means send to the process group that currently owns ! 1328: the terminal being used to communicate with PROCESS. ! 1329: This is used for various commands in shell mode. ! 1330: If NOMSG is zero, insert signal-announcements into process's buffers ! 1331: right away. */ ! 1332: ! 1333: sig_process (process, signo, current_group, nomsg) ! 1334: Lisp_Object process; ! 1335: int signo; ! 1336: Lisp_Object current_group; ! 1337: int nomsg; ! 1338: { ! 1339: Lisp_Object proc; ! 1340: register struct Lisp_Process *p; ! 1341: int gid; ! 1342: ! 1343: proc = get_process (process); ! 1344: p = XPROCESS (proc); ! 1345: ! 1346: if (NULL (p->childp)) ! 1347: error ("Process %s is not a subprocess", ! 1348: XSTRING (p->name)->data); ! 1349: if (!XFASTINT (p->infd)) ! 1350: error ("Process %s is not active", ! 1351: XSTRING (p->name)->data); ! 1352: ! 1353: #ifdef TIOCGPGRP /* Not sure about this! (fnf) */ ! 1354: /* If we are using pgrps, get a pgrp number and make it negative. */ ! 1355: if (!NULL (current_group)) ! 1356: { ! 1357: ioctl (XFASTINT (p->infd), TIOCGPGRP, &gid); ! 1358: gid = - gid; ! 1359: } ! 1360: else ! 1361: gid = - XFASTINT (p->pid); ! 1362: #else /* not using pgrps */ ! 1363: /* Can't select pgrps on this system, so we know that ! 1364: the child itself heads the pgrp. */ ! 1365: gid = - XFASTINT (p->pid); ! 1366: #endif /* not using pgrps */ ! 1367: ! 1368: switch (signo) ! 1369: { ! 1370: #ifdef SIGCONT ! 1371: case SIGCONT: ! 1372: XFASTINT (p->flags) = RUNNING | CHANGED; ! 1373: child_changed++; ! 1374: break; ! 1375: #endif ! 1376: case SIGINT: ! 1377: case SIGQUIT: ! 1378: case SIGKILL: ! 1379: flush_pending_output (XFASTINT (p->infd)); ! 1380: break; ! 1381: } ! 1382: /* gid may be a pid, or minus a pgrp's number */ ! 1383: #ifdef BSD ! 1384: /* On bsd, [man says] kill does not accept a negative number to kill a pgrp. ! 1385: Must do that differently. */ ! 1386: killpg (-gid, signo); ! 1387: #else /* Not BSD. */ ! 1388: kill (gid, signo); ! 1389: #endif /* Not BSD. */ ! 1390: ! 1391: /* Put notices in buffers now, since it is safe now. ! 1392: Because of this, we know that a process we have just killed ! 1393: will never need to use its buffer again. */ ! 1394: if (!nomsg) ! 1395: change_msgs (); ! 1396: } ! 1397: ! 1398: DEFUN ("interrupt-process", Finterrupt_process, Sinterrupt_process, 0, 2, 0, ! 1399: "Interrupt process PROCESS. May be process or name of one.\n\ ! 1400: Nil or no arg means current buffer's process.\n\ ! 1401: Second arg CURRENT-GROUP non-nil means send signal to\n\ ! 1402: the current process-group of the process's controlling terminal\n\ ! 1403: rather than to the process's own process group.\n\ ! 1404: If the process is a shell, this means interrupt current subjob\n\ ! 1405: rather than the shell.") ! 1406: (process, current_group) ! 1407: Lisp_Object process, current_group; ! 1408: { ! 1409: sig_process (process, SIGINT, current_group, 0); ! 1410: return process; ! 1411: } ! 1412: ! 1413: DEFUN ("kill-process", Fkill_process, Skill_process, 0, 2, 0, ! 1414: "Kill process PROCESS. May be process or name of one.\n\ ! 1415: See function interrupt-process for more details on usage.") ! 1416: (process, current_group) ! 1417: Lisp_Object process, current_group; ! 1418: { ! 1419: sig_process (process, SIGKILL, current_group, 0); ! 1420: return process; ! 1421: } ! 1422: ! 1423: DEFUN ("quit-process", Fquit_process, Squit_process, 0, 2, 0, ! 1424: "Send QUIT signal to process PROCESS. May be process or name of one.\n\ ! 1425: See function interrupt-process for more details on usage.") ! 1426: (process, current_group) ! 1427: Lisp_Object process, current_group; ! 1428: { ! 1429: sig_process (process, SIGQUIT, current_group, 0); ! 1430: return process; ! 1431: } ! 1432: ! 1433: DEFUN ("stop-process", Fstop_process, Sstop_process, 0, 2, 0, ! 1434: "Stop process PROCESS. May be process or name of one.\n\ ! 1435: See function interrupt-process for more details on usage.") ! 1436: (process, current_group) ! 1437: Lisp_Object process, current_group; ! 1438: { ! 1439: #ifndef SIGTSTP ! 1440: error ("no SIGTSTP support"); ! 1441: #else ! 1442: sig_process (process, SIGTSTP, current_group, 0); ! 1443: #endif ! 1444: return process; ! 1445: } ! 1446: ! 1447: DEFUN ("continue-process", Fcontinue_process, Scontinue_process, 0, 2, 0, ! 1448: "Continue process PROCESS. May be process or name of one.\n\ ! 1449: See function interrupt-process for more details on usage.") ! 1450: (process, current_group) ! 1451: Lisp_Object process, current_group; ! 1452: { ! 1453: #ifdef SIGCONT ! 1454: sig_process (process, SIGCONT, current_group, 0); ! 1455: #else ! 1456: error ("no SIGCONT support"); ! 1457: #endif ! 1458: return process; ! 1459: } ! 1460: ! 1461: DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0, ! 1462: "Make PROCESS see end-of-file in its input.\n\ ! 1463: Eof comes after any text already sent to it.\n\ ! 1464: Nil or no arg means current buffer's process.") ! 1465: (process) ! 1466: Lisp_Object process; ! 1467: { ! 1468: Lisp_Object proc; ! 1469: ! 1470: proc = get_process (process); ! 1471: send_process (proc, "\004", 1); ! 1472: return process; ! 1473: } ! 1474: ! 1475: /* Kill all processes associated with `buffer'. ! 1476: If `buffer' is nil, kill all processes */ ! 1477: ! 1478: kill_buffer_processes (buffer) ! 1479: Lisp_Object buffer; ! 1480: { ! 1481: Lisp_Object tail, proc; ! 1482: ! 1483: for (tail = Vprocess_alist; XGCTYPE (tail) == Lisp_Cons; ! 1484: tail = XCONS (tail)->cdr) ! 1485: { ! 1486: proc = XCONS (XCONS (tail)->car)->cdr; ! 1487: if (XGCTYPE (proc) == Lisp_Process ! 1488: && (NULL (buffer) || EQ (XPROCESS (proc)->buffer, buffer))) ! 1489: if (XFASTINT (XPROCESS (proc)->infd)) ! 1490: sig_process (proc, SIGKILL, Qnil, 1); ! 1491: } ! 1492: } ! 1493: ! 1494: count_active_processes () ! 1495: { ! 1496: register Lisp_Object tail, proc; ! 1497: register int count = 0; ! 1498: ! 1499: for (tail = Vprocess_alist; !NULL (tail); tail = Fcdr (tail)) ! 1500: { ! 1501: proc = Fcdr (Fcar (tail)); ! 1502: ! 1503: if ((1 << (XFASTINT (XPROCESS (proc)->flags) & PROC_STATUS) ! 1504: & ((1 << RUNNING) | (1 << STOPPED))) ! 1505: && NULL (XPROCESS (proc)->kill_without_query)) ! 1506: count++; ! 1507: } ! 1508: ! 1509: return count; ! 1510: } ! 1511: ! 1512: /* On receipt of a signal that a child status has changed, ! 1513: loop asking about children with changed statuses until ! 1514: the system says there are no more. ! 1515: All we do is change the flags components; ! 1516: we do not run sentinels or print notifications. ! 1517: That is saved for the next time keyboard input is done, ! 1518: in order to avoid timing errors. */ ! 1519: ! 1520: /** WARNING: this can be called during garbage collection. ! 1521: Therefore, it must not be fooled by the presence of mark bits in ! 1522: Lisp objects. */ ! 1523: ! 1524: /** USG WARNING: Although it is not obvious from the documentation ! 1525: in signal(2), on a USG system the SIGCLD handler MUST NOT call ! 1526: signal() before executing at least one wait(), otherwise the handler ! 1527: will be called again, resulting in an infinite loop. The relevant ! 1528: portion of the documentation reads "SIGCLD signals will be queued ! 1529: and the signal-catching function will be continually reentered until ! 1530: the queue is empty". Invoking signal() causes the kernel to reexamine ! 1531: the SIGCLD queue. Fred Fish, UniSoft Systems Inc. */ ! 1532: ! 1533: child_sig (signo) ! 1534: int signo; ! 1535: { ! 1536: register int pid; ! 1537: WAITTYPE w; ! 1538: Lisp_Object tail, proc; ! 1539: register struct Lisp_Process *p; ! 1540: ! 1541: #ifdef BSD4_1 ! 1542: extern int synch_process_pid; ! 1543: extern int sigheld; ! 1544: sigheld |= sigbit (SIGCHLD); ! 1545: #endif ! 1546: ! 1547: loop: ! 1548: ! 1549: #ifdef WNOHANG ! 1550: #ifndef WUNTRACED ! 1551: #define WUNTRACED 0 ! 1552: #endif /* no WUNTRACED */ ! 1553: pid = wait3 (&w, WNOHANG | WUNTRACED, 0); ! 1554: if (pid <= 0) ! 1555: { ! 1556: if (errno == EINTR) ! 1557: { ! 1558: errno = 0; ! 1559: goto loop; ! 1560: } ! 1561: /* USG systems forget handlers when they are used; ! 1562: must reestablish each time */ ! 1563: #ifdef USG ! 1564: signal (signo, child_sig); /* WARNING - must come after wait3() */ ! 1565: #endif ! 1566: #ifdef BSD4_1 ! 1567: sigheld &= ~sigbit (SIGCHLD); ! 1568: sigrelse (SIGCHLD); ! 1569: #endif ! 1570: return; ! 1571: } ! 1572: #else ! 1573: pid = wait (&w); ! 1574: #endif /* no WNOHANG */ ! 1575: ! 1576: #ifdef BSD4_1 ! 1577: if (synch_process_pid == pid) ! 1578: synch_process_pid = 0; /* Zero it to show process has died. */ ! 1579: #endif ! 1580: ! 1581: for (tail = Vprocess_alist; XSYMBOL (tail) != XSYMBOL (Qnil); tail = XCONS (tail)->cdr) ! 1582: { ! 1583: proc = XCONS (XCONS (tail)->car)->cdr; ! 1584: p = XPROCESS (proc); ! 1585: if (!NULL (p->childp) && XFASTINT (p->pid) == pid) ! 1586: break; ! 1587: } ! 1588: ! 1589: if (XSYMBOL (tail) == XSYMBOL (Qnil)) ! 1590: #ifdef USG ! 1591: goto ignore; ! 1592: #else ! 1593: goto loop; /* We don't know who this is */ ! 1594: #endif ! 1595: ! 1596: child_changed++; ! 1597: if (WIFSTOPPED (w)) ! 1598: { ! 1599: XFASTINT (p->flags) = STOPPED | CHANGED; ! 1600: XFASTINT (p->reason) = WSTOPSIG (w); ! 1601: } ! 1602: else if (WIFEXITED (w)) ! 1603: { ! 1604: XFASTINT (p->flags) = EXITED | CHANGED; ! 1605: if (WCOREDUMP (w)) ! 1606: XFASTINT (p->flags) |= COREDUMPED; ! 1607: XFASTINT (p->reason) = WRETCODE (w); ! 1608: } ! 1609: else if (WIFSIGNALED (w)) ! 1610: { ! 1611: XFASTINT (p->flags) = SIGNALED | CHANGED; ! 1612: if (WCOREDUMP (w)) ! 1613: XFASTINT (p->flags) |= COREDUMPED; ! 1614: XFASTINT (p->reason) = WTERMSIG (w); ! 1615: } ! 1616: #ifndef USG ! 1617: goto loop; ! 1618: #else ! 1619: ignore: ! 1620: signal (signo, child_sig); ! 1621: #endif /* not USG */ ! 1622: } ! 1623: ! 1624: /* Find all process marked as "changed" ! 1625: and notify the user in a suitable fashion ! 1626: (either run the sentinel or output a message). ! 1627: This is done while Emacs is waiting for keyboard input */ ! 1628: ! 1629: change_msgs() ! 1630: { ! 1631: Lisp_Object tail, proc, buffer; ! 1632: register struct Lisp_Process *p; ! 1633: register struct buffer *old = bf_cur; ! 1634: char line[50]; ! 1635: int opoint; ! 1636: ! 1637: child_changed = 0; ! 1638: ! 1639: for (tail = Vprocess_alist; !NULL (tail); tail = Fcdr (tail)) ! 1640: { ! 1641: proc = Fcdr (Fcar (tail)); ! 1642: p = XPROCESS (proc); ! 1643: ! 1644: if (!(XFASTINT (p->flags) & CHANGED)) ! 1645: continue; ! 1646: ! 1647: /* If process is still active, read any output that remains. */ ! 1648: if (XFASTINT (p->infd)) ! 1649: read_process_output (proc, XFASTINT (p->infd)); ! 1650: ! 1651: XFASTINT (p->flags) &= ~CHANGED; ! 1652: ! 1653: line[0] = 0; ! 1654: buffer = p->buffer; ! 1655: ! 1656: if ((XFASTINT (p->flags) & PROC_STATUS) == SIGNALED ! 1657: || (XFASTINT (p->flags) & PROC_STATUS) == STOPPED) ! 1658: { ! 1659: sprintf (line, "%s%s\n", ! 1660: XFASTINT (p->reason) < NSIG ! 1661: ? sys_siglist[XFASTINT (p->reason)] : "unknown", ! 1662: XFASTINT (p->flags) & COREDUMPED ? " (core dumped)" : ""); ! 1663: if (line[0] >= 'A' && line[0] <= 'Z') ! 1664: line[0] += 040; ! 1665: ! 1666: if ((XFASTINT (p->flags) & PROC_STATUS) == SIGNALED) ! 1667: if (delete_exited_processes) ! 1668: remove_process (proc); ! 1669: else ! 1670: deactivate_process (proc); ! 1671: } ! 1672: else if ((XFASTINT (p->flags) & PROC_STATUS) == EXITED) ! 1673: { ! 1674: if (XFASTINT (p->reason)) ! 1675: sprintf (line, "exited abnormally with code %d\n", ! 1676: XFASTINT (p->reason)); ! 1677: else ! 1678: sprintf (line, "finished\n"); ! 1679: ! 1680: if (delete_exited_processes) ! 1681: remove_process (proc); ! 1682: else ! 1683: deactivate_process (proc); ! 1684: } ! 1685: ! 1686: if (!NULL (p->sentinel)) ! 1687: exec_sentinel (proc, build_string (line)); ! 1688: else if (line[0] && !NULL (buffer)) ! 1689: { ! 1690: /* Avoid error if buffer is deleted ! 1691: (probably that's why the process is dead, too) */ ! 1692: if (NULL (XBUFFER (buffer)->name)) ! 1693: continue; ! 1694: Fset_buffer (buffer); ! 1695: opoint = point; ! 1696: SetPoint (NumCharacters + 1); ! 1697: if (point == opoint) ! 1698: opoint = -1; ! 1699: InsStr ("\nProcess "); ! 1700: Finsert (1, &p->name); ! 1701: InsStr (" "); ! 1702: InsStr (line); ! 1703: if (opoint > 0) ! 1704: SetPoint (opoint); ! 1705: } ! 1706: } /* end for */ ! 1707: ! 1708: SetBfp (old); ! 1709: ! 1710: RedoModes++; /* in case buffers use %s in mode-line-format */ ! 1711: DoDsp (1); ! 1712: } ! 1713: ! 1714: exec_sentinel (proc, reason) ! 1715: Lisp_Object proc, reason; ! 1716: { ! 1717: Lisp_Object sentinel; ! 1718: register struct Lisp_Process *p = XPROCESS (proc); ! 1719: ! 1720: sentinel = p->sentinel; ! 1721: if (NULL (sentinel)) ! 1722: return; ! 1723: ! 1724: p->sentinel = Qnil; ! 1725: call2 (sentinel, proc, reason); ! 1726: p->sentinel = sentinel; ! 1727: } ! 1728: ! 1729: init_process () ! 1730: { ! 1731: register int i; ! 1732: ! 1733: #ifdef SIGCHLD ! 1734: signal (SIGCHLD, child_sig); ! 1735: #endif ! 1736: ! 1737: input_wait_mask = ChannelMask(0); ! 1738: Vprocess_alist = Qnil; ! 1739: for (i = 0; i < MAXDESC; i++) ! 1740: { ! 1741: chan_process[i] = Qnil; ! 1742: proc_buffered_char[i] = -1; ! 1743: } ! 1744: } ! 1745: ! 1746: syms_of_process () ! 1747: { ! 1748: Qprocessp = intern ("processp"); ! 1749: staticpro (&Qprocessp); ! 1750: ! 1751: staticpro (&Vprocess_alist); ! 1752: ! 1753: DefBoolVar ("delete-exited-processes", &delete_exited_processes, ! 1754: "*Non-nil means delete processes immediately when they exit.\n\ ! 1755: nil means don't delete them until list-processes is done."); ! 1756: ! 1757: delete_exited_processes = 1; ! 1758: ! 1759: defsubr (&Sprocessp); ! 1760: defsubr (&Sget_process); ! 1761: defsubr (&Sget_buffer_process); ! 1762: defsubr (&Sdelete_process); ! 1763: defsubr (&Sprocess_status); ! 1764: defsubr (&Sprocess_id); ! 1765: defsubr (&Sprocess_name); ! 1766: defsubr (&Sprocess_command); ! 1767: defsubr (&Sset_process_buffer); ! 1768: defsubr (&Sprocess_buffer); ! 1769: defsubr (&Sprocess_mark); ! 1770: defsubr (&Sset_process_filter); ! 1771: defsubr (&Sprocess_filter); ! 1772: defsubr (&Sset_process_sentinel); ! 1773: defsubr (&Sprocess_sentinel); ! 1774: defsubr (&Sprocess_kill_without_query); ! 1775: defsubr (&Slist_processes); ! 1776: defsubr (&Sstart_process); ! 1777: defsubr (&Saccept_process_output); ! 1778: defsubr (&Ssend_region); ! 1779: defsubr (&Ssend_string); ! 1780: defsubr (&Sinterrupt_process); ! 1781: defsubr (&Skill_process); ! 1782: defsubr (&Squit_process); ! 1783: defsubr (&Sstop_process); ! 1784: defsubr (&Scontinue_process); ! 1785: defsubr (&Sprocess_send_eof); ! 1786: } ! 1787: ! 1788: #endif subprocesses
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.