*** ed19:[src]process.c Thu Apr 20 18:13:35 1995 --- ed1928:[src]process.c Thu May 4 12:29:41 1995 *************** *** 1,4 **** /* Asynchronous subprocess control for GNU Emacs. ! Copyright (C) 1985, 1986, 1987, 1988, 1993 Free Software Foundation, Inc. This file is part of GNU Emacs. --- 1,4 ---- /* Asynchronous subprocess control for GNU Emacs. ! Copyright (C) 1985, 86, 87, 88, 93, 94 Free Software Foundation, Inc. This file is part of GNU Emacs. *************** *** 18,27 **** the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! #ifdef VMS ! #define ALMOST_STATIC /* marks quantities which could be static were ! vms's create_process in this file. */ ! #else ! #define ALMOST_STATIC static ! #endif #include --- 18,27 ---- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! #ifdef VMS ! #define ALMOST_STATIC /* marks quantities which could be static were ! vms's create_process in this file. */ ! #else ! #define ALMOST_STATIC static ! #endif #include *************** *** 45,48 **** --- 45,51 ---- #include #include + #ifdef HAVE_UNISTD_H + #include + #endif #ifdef HAVE_SOCKETS /* TCP connection support, if kernel can do it */ *************** *** 70,79 **** #include "multinet_root:[multinet.include.netinet]in.h" #endif /* MULTINET */ ! #else /* ! VMS */ #include #include #include #include ! #endif /* ! VMS */ #endif /* HAVE_SOCKETS */ --- 73,82 ---- #include "multinet_root:[multinet.include.netinet]in.h" #endif /* MULTINET */ ! #else /* not VMS */ #include #include #include #include ! #endif /* VMS */ #endif /* HAVE_SOCKETS */ *************** *** 83,88 **** #endif ! /* DGUX inet_addr returns a 'struct in_addr'. */ ! #ifdef DGUX #define IN_ADDR struct in_addr #define NUMERIC_ADDR_ERROR (numeric_addr.s_addr == -1) --- 86,91 ---- #endif ! /* On some systems, e.g. DGUX, inet_addr returns a 'struct in_addr'. */ ! #ifdef HAVE_BROKEN_INET_ADDR #define IN_ADDR struct in_addr #define NUMERIC_ADDR_ERROR (numeric_addr.s_addr == -1) *************** *** 99,102 **** --- 102,109 ---- #endif /* BSD or STRIDE */ + #ifdef BROKEN_O_NONBLOCK + #undef O_NONBLOCK + #endif /* BROKEN_O_NONBLOCK */ + #ifdef NEED_BSDTTY #include *************** *** 121,124 **** --- 128,132 ---- Lisp_Object Qprocessp; Lisp_Object Qrun, Qstop, Qsignal, Qopen, Qclosed; + Lisp_Object Qlast_nonmenu_event; /* Qexit is declared and initialized in eval.c. */ *************** *** 153,167 **** #include "syswait.h" ! extern errno; ! #if 0 ! extern sys_nerr; ! extern char *sys_errlist[]; #endif #ifndef BSD4_1 #ifndef LINUX extern char *sys_siglist[]; ! #endif ! #else char *sys_siglist[] = { --- 161,177 ---- #include "syswait.h" ! extern int errno; ! extern char *strerror (); ! ! #ifndef HAVE_H_ERRNO ! extern int h_errno; #endif + #ifndef SYS_SIGLIST_DECLARED #ifndef BSD4_1 #ifndef LINUX extern char *sys_siglist[]; ! #endif /* not LINUX */ ! #else /* BSD4_1 */ char *sys_siglist[] = { *************** *** 194,197 **** --- 204,208 ---- }; #endif + #endif /* ! SYS_SIGLIST_DECLARED */ /* t means use pty, nil means use a pipe, *************** *** 232,239 **** --- 243,259 ---- #endif /* no FD_SET */ + /* If we support X Windows, turn on the code to poll periodically + to detect C-g. It isn't actually used when doing interrupt input. */ + #ifdef HAVE_X_WINDOWS + #define POLL_FOR_INPUT + #endif + /* Mask of bits indicating the descriptors that we wait for input on */ ALMOST_STATIC SELECT_TYPE input_wait_mask; + /* The largest descriptor currently in use for a process object. */ + static int max_process_desc; + /* Descriptor to use for keyboard input. */ static int keyboard_descriptor; *************** *** 243,250 **** /* Indexed by descriptor, gives the process (if any) for that descriptor */ ! ALMOST_STATIC Lisp_Object chan_process[MAXDESC]; /* Alist of elements (NAME . PROCESS) */ ! static Lisp_Object Vprocess_alist; /* Buffered-ahead input char from process, indexed by channel. --- 263,270 ---- /* Indexed by descriptor, gives the process (if any) for that descriptor */ ! Lisp_Object chan_process[MAXDESC]; /* Alist of elements (NAME . PROCESS) */ ! Lisp_Object Vprocess_alist; /* Buffered-ahead input char from process, indexed by channel. *************** *** 257,260 **** --- 277,283 ---- static Lisp_Object get_process (); + + /* Maximum number of bytes to send to a pty without an eof. */ + static int pty_max_bytes; /* Compute the Lisp form of the process status, p->status, from *************** *** 334,338 **** if (EQ (symbol, Qsignal) || EQ (symbol, Qstop)) { ! string = build_string (code < NSIG ? sys_siglist[code] : "unknown"); string2 = build_string (coredump ? " (core dumped)\n" : "\n"); XSTRING (string)->data[0] = DOWNCASE (XSTRING (string)->data[0]); --- 357,366 ---- if (EQ (symbol, Qsignal) || EQ (symbol, Qstop)) { ! char *signame = 0; ! if (code < NSIG) ! signame = sys_siglist[code]; ! if (signame == 0) ! signame = "unknown"; ! string = build_string (signame); string2 = build_string (coredump ? " (core dumped)\n" : "\n"); XSTRING (string)->data[0] = DOWNCASE (XSTRING (string)->data[0]); *************** *** 462,466 **** error ("Too many VMS processes."); #endif ! /* size of process structure includes the vector header, so deduct for that. But struct Lisp_Vector includes the first --- 490,494 ---- error ("Too many VMS processes."); #endif ! /* size of process structure includes the vector header, so deduct for that. But struct Lisp_Vector includes the first *************** *** 576,597 **** register Lisp_Object name; { ! register Lisp_Object proc; ! if (NILP (name)) ! proc = Fget_buffer_process (Fcurrent_buffer ()); else { ! proc = Fget_process (name); if (NILP (proc)) ! proc = Fget_buffer_process (Fget_buffer (name)); } - - if (!NILP (proc)) - return proc; - - if (NILP (name)) - error ("Current buffer has no process"); else ! error ("Process %s does not exist", XSTRING (name)->data); ! /* NOTREACHED */ } --- 604,635 ---- register Lisp_Object name; { ! register Lisp_Object proc, obj; ! if (STRINGP (name)) ! { ! obj = Fget_process (name); ! if (NILP (obj)) ! obj = Fget_buffer (name); ! if (NILP (obj)) ! error ("Process %s does not exist", XSTRING (name)->data); ! } ! else if (NILP (name)) ! obj = Fcurrent_buffer (); else + obj = name; + + /* Now obj should be either a buffer object or a process object. + */ + if (BUFFERP (obj)) { ! proc = Fget_buffer_process (obj); if (NILP (proc)) ! error ("Buffer %s has no process", XSTRING (XBUFFER (obj)->name)->data); } else ! { ! CHECK_PROCESS (obj, 0); ! proc = obj; ! } ! return proc; } *************** *** 640,646 **** register struct Lisp_Process *p; register Lisp_Object status; ! proc = Fget_process (proc); if (NILP (proc)) return proc; p = XPROCESS (proc); if (!NILP (p->raw_status_low)) --- 678,690 ---- register struct Lisp_Process *p; register Lisp_Object status; ! ! if (STRINGP (proc)) ! proc = Fget_process (proc); ! else ! proc = get_process (proc); ! if (NILP (proc)) return proc; + p = XPROCESS (proc); if (!NILP (p->raw_status_low)) *************** *** 798,805 **** } DEFUN ("process-kill-without-query", Fprocess_kill_without_query, Sprocess_kill_without_query, 1, 2, 0, "Say no query needed if PROCESS is running when Emacs is exited.\n\ ! Optional second argument if non-nill says to require a query.\n\ Value is t if a query was formerly required.") (proc, value) --- 842,865 ---- } + DEFUN ("set-process-window-size", Fset_process_window_size, + Sset_process_window_size, 3, 3, 0, + "Tell PROCESS that it has logical window size HEIGHT and WIDTH.") + (proc, height, width) + register Lisp_Object proc, height, width; + { + CHECK_PROCESS (proc, 0); + CHECK_NATNUM (height, 0); + CHECK_NATNUM (width, 0); + if (set_window_size (XINT (XPROCESS (proc)->infd), + XINT (height), XINT(width)) <= 0) + return Qnil; + else + return Qt; + } + DEFUN ("process-kill-without-query", Fprocess_kill_without_query, Sprocess_kill_without_query, 1, 2, 0, "Say no query needed if PROCESS is running when Emacs is exited.\n\ ! Optional second argument if non-nil says to require a query.\n\ Value is t if a query was formerly required.") (proc, value) *************** *** 872,882 **** Lisp_Object tem; tem = Fcar (Fcdr (p->status)); - #if 0 - #ifdef VMS - if (XINT (tem) < NSIG) - write_string (sys_errlist [XINT (tem)], -1); - else - #endif - #else #ifdef VMS if (XINT (tem) < NSIG) --- 932,935 ---- *************** *** 884,888 **** else #endif - #endif Fprinc (symbol, Qnil); } --- 937,940 ---- *************** *** 1036,1069 **** new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *)); - for (i = 3; i < nargs; i++) - { - tem = args[i]; - CHECK_STRING (tem, i); - new_argv[i - 2] = XSTRING (tem)->data; - } - new_argv[i - 2] = 0; - new_argv[0] = XSTRING (program)->data; - #ifndef VMS /* If program file name is not absolute, search our path for it */ ! if (new_argv[0][0] != '/') { tem = Qnil; openp (Vexec_path, program, EXEC_SUFFIXES, &tem, 1); if (NILP (tem)) report_file_error ("Searching for program", Fcons (program, Qnil)); new_argv[0] = XSTRING (tem)->data; } ! #else /* VMS */ { ! char *hack_vms_program_name (); /* defined in vmsproc.c */ if (strcmp (new_argv[0], "*dcl*") == 0 ! && strcmp (new_argv[1], "-c") == 0) ! new_argv[2] = hack_vms_program_name (new_argv[2]); else ! new_argv[0] = hack_vms_program_name (new_argv[0]); ! } #endif /* not VMS */ proc = make_process (name); /* If an error occurs and we can't start the process, we want to --- 1088,1142 ---- new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *)); #ifndef VMS /* If program file name is not absolute, search our path for it */ ! if (XSTRING (program)->data[0] != '/') { + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; + tem = Qnil; + GCPRO4 (name, program, buffer, current_dir); openp (Vexec_path, program, EXEC_SUFFIXES, &tem, 1); + UNGCPRO; if (NILP (tem)) report_file_error ("Searching for program", Fcons (program, Qnil)); new_argv[0] = XSTRING (tem)->data; } ! else ! new_argv[0] = XSTRING (program)->data; ! #define START 4 ! #else { ! int start = 4; ! CHECK_STRING (args[0], 0); if (strcmp (new_argv[0], "*dcl*") == 0 ! && nargs > start + 1) ! { ! CHECK_STRING (args[1], 1); ! if (strcmp (new_argv[1], "-c") == 0) ! { ! new_argv[0] = XSTRING (args[0])->data; ! new_argv[1] = XSTRING (args[start])->data; ! start++; ! CHECK_STRING (args[start], start); ! new_argv[2] = hack_vms_program_name (XSTRING (args[start])->data); ! start++; ! } ! } else ! new_argv[0] = hack_vms_program_name (XSTRING (args[0])->data); ! #define START start #endif /* not VMS */ + for (i = START; i < nargs; i++) + { + tem = args[i]; + CHECK_STRING (tem, i); + new_argv[i - 2] = XSTRING (tem)->data; + } + new_argv[i - 2] = 0; + #ifdef VMS + } + #endif + proc = make_process (name); /* If an error occurs and we can't start the process, we want to *************** *** 1151,1155 **** #ifdef HAVE_PTYS ! if (EQ (Vprocess_connection_type, Qt)) outchannel = inchannel = allocate_pty (); --- 1224,1228 ---- #ifdef HAVE_PTYS ! if (!NILP (Vprocess_connection_type)) outchannel = inchannel = allocate_pty (); *************** *** 1246,1249 **** --- 1319,1326 ---- #endif /* SIGCHLD */ + FD_SET (inchannel, &input_wait_mask); + if (inchannel > max_process_desc) + max_process_desc = inchannel; + /* Until we store the proper pid, enable sigchld_handler to recognize an unknown pid as standing for this process. *************** *** 1275,1289 **** /* First, disconnect its current controlling terminal. */ #ifdef HAVE_SETSID setsid (); - #ifdef TIOCSCTTY /* Make the pty's terminal the controlling terminal. */ if (pty_flag) ! /* We ignore the return value ! because faith@cs.unc.edu says that is necessary on Linux. */ ! ioctl (xforkin, TIOCSCTTY, 0); #endif #else /* not HAVE_SETSID */ #ifdef USG ! /* It's very important to call setpgrp() here and no time afterwards. Otherwise, we lose our controlling tty which is set when we open the pty. */ --- 1352,1370 ---- /* First, disconnect its current controlling terminal. */ #ifdef HAVE_SETSID + /* We tried doing setsid only if pty_flag, but it caused + process_set_signal to fail on SGI when using a pipe. */ setsid (); /* Make the pty's terminal the controlling terminal. */ if (pty_flag) ! { ! #ifdef TIOCSCTTY ! /* We ignore the return value ! because faith@cs.unc.edu says that is necessary on Linux. */ ! ioctl (xforkin, TIOCSCTTY, 0); #endif + } #else /* not HAVE_SETSID */ #ifdef USG ! /* It's very important to call setpgrp here and no time afterwards. Otherwise, we lose our controlling tty which is set when we open the pty. */ *************** *** 1291,1294 **** --- 1372,1394 ---- #endif /* USG */ #endif /* not HAVE_SETSID */ + #if defined (HAVE_TERMIOS) && defined (LDISC1) + if (pty_flag && xforkin >= 0) + { + struct termios t; + tcgetattr (xforkin, &t); + t.c_lflag = LDISC1; + if (tcsetattr (xforkin, TCSANOW, &t) < 0) + write (1, "create_process/tcsetattr LDISC1 failed\n", 39); + } + #else + #if defined (NTTYDISC) && defined (TIOCSETD) + if (pty_flag && xforkin >= 0) + { + /* Use new line discipline. */ + int ldisc = NTTYDISC; + ioctl (xforkin, TIOCSETD, &ldisc); + } + #endif + #endif #ifdef TIOCNOTTY /* In 4.3BSD, the TIOCSPGRP bug has been fixed, and now you *************** *** 1317,1320 **** --- 1417,1424 ---- if (pty_flag) { + #ifdef SET_CHILD_PTY_PGRP + int pgrp = getpid (); + #endif + /* I wonder if close (open (pty_name, ...)) would work? */ if (xforkin >= 0) *************** *** 1322,1325 **** --- 1426,1434 ---- xforkout = xforkin = open (pty_name, O_RDWR, 0); + #ifdef SET_CHILD_PTY_PGRP + ioctl (xforkin, TIOCSPGRP, &pgrp); + ioctl (xforkout, TIOCSPGRP, &pgrp); + #endif + if (xforkin < 0) abort (); *************** *** 1327,1331 **** #endif /* not UNIPLUS and not RTU */ #ifdef SETUP_SLAVE_PTY ! SETUP_SLAVE_PTY; #endif /* SETUP_SLAVE_PTY */ #ifdef AIX --- 1436,1443 ---- #endif /* not UNIPLUS and not RTU */ #ifdef SETUP_SLAVE_PTY ! if (pty_flag) ! { ! SETUP_SLAVE_PTY; ! } #endif /* SETUP_SLAVE_PTY */ #ifdef AIX *************** *** 1351,1355 **** #endif /* SIGCHLD */ ! child_setup_tty (xforkout); child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir); --- 1463,1471 ---- #endif /* SIGCHLD */ ! signal (SIGINT, SIG_DFL); ! signal (SIGQUIT, SIG_DFL); ! ! if (pty_flag) ! child_setup_tty (xforkout); child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir); *************** *** 1359,1368 **** if (pid < 0) ! report_file_error ("Doing vfork", Qnil); XFASTINT (XPROCESS (process)->pid) = pid; - FD_SET (inchannel, &input_wait_mask); - /* If the subfork execv fails, and it exits, this close hangs. I don't know why. --- 1475,1488 ---- if (pid < 0) ! { ! if (forkin >= 0) ! close (forkin); ! if (forkin != forkout && forkout >= 0) ! close (forkout); ! report_file_error ("Doing vfork", Qnil); ! } XFASTINT (XPROCESS (process)->pid) = pid; /* If the subfork execv fails, and it exits, this close hangs. I don't know why. *************** *** 1371,1388 **** signal (SIGALRM, create_process_1); alarm (1); ! #ifdef SYSV4_PTYS ! /* OK to close only if it's not a pty. Otherwise we need to leave ! it open for ioctl to get pgrp when signals are sent, or to send ! the interrupt characters through if that's how we're signalling ! subprocesses. Alternately if you are concerned about running out ! of file descriptors, you could just save the tty name and open ! just to do the ioctl. */ ! if (NILP (XFASTINT (XPROCESS (process)->pty_flag))) ! #endif ! { ! XPROCESS (process)->subtty = Qnil; ! if (forkin >= 0) ! close (forkin); ! } alarm (0); start_polling (); --- 1491,1497 ---- signal (SIGALRM, create_process_1); alarm (1); ! XPROCESS (process)->subtty = Qnil; ! if (forkin >= 0) ! close (forkin); alarm (0); start_polling (); *************** *** 1448,1456 **** struct hostent host_info_fixed; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; GCPRO4 (name, buffer, host, service); CHECK_STRING (name, 0); CHECK_STRING (host, 0); ! if (XTYPE(service) == Lisp_Int) port = htons ((unsigned short) XINT (service)); else --- 1557,1567 ---- struct hostent host_info_fixed; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; + int retry = 0; + int count = specpdl_ptr - specpdl; GCPRO4 (name, buffer, host, service); CHECK_STRING (name, 0); CHECK_STRING (host, 0); ! if (XTYPE (service) == Lisp_Int) port = htons ((unsigned short) XINT (service)); else *************** *** 1470,1474 **** #ifndef TERM ! host_info_ptr = gethostbyname (XSTRING (host)->data); if (host_info_ptr == 0) /* Attempt to interpret host as numeric inet address */ --- 1581,1596 ---- #ifndef TERM ! while (1) ! { ! #ifdef TRY_AGAIN ! h_errno = 0; ! #endif ! host_info_ptr = gethostbyname (XSTRING (host)->data); ! #ifdef TRY_AGAIN ! if (! (host_info_ptr == 0 && h_errno == TRY_AGAIN)) ! #endif ! break; ! Fsleep_for (make_number (1), Qnil); ! } if (host_info_ptr == 0) /* Attempt to interpret host as numeric inet address */ *************** *** 1492,1502 **** host_info.h_length = strlen (addr_list[0]); } - #else /* TERM */ - s = connect_server (0); - if (s < 0) - report_file_error ("error creating socket", Fcons (name, Qnil)); - send_command (s, C_PORT, 0, "%s:%d", XSTRING (host)->data, ntohs (port)); - send_command (s, C_DUMB, 1, 0); - #endif /* TERM */ bzero (&address, sizeof address); --- 1614,1617 ---- *************** *** 1510,1519 **** report_file_error ("error creating socket", Fcons (name, Qnil)); loop: ! if (connect (s, (struct sockaddr *) &address, sizeof address) == -1) { int xerrno = errno; if (errno == EINTR) goto loop; #ifdef VMS socket_close (s); --- 1625,1658 ---- report_file_error ("error creating socket", Fcons (name, Qnil)); + /* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR) + when connect is interrupted. So let's not let it get interrupted. + Note we do not turn off polling, because polling is only used + when not interrupt_input, and thus not normally used on the systems + which have this bug. On systems which use polling, there's no way + to quit if polling is turned off. */ + if (interrupt_input) + unrequest_sigio (); + + /* Slow down polling to every ten seconds. + Some kernels have a bug which causes retrying connect to fail + after a connect. */ + #ifdef POLL_FOR_INPUT + bind_polling_period (10); + #endif + loop: ! if (connect (s, (struct sockaddr *) &address, sizeof address) == -1 ! && errno != EISCONN) { int xerrno = errno; + if (errno == EINTR) goto loop; + if (errno == EADDRINUSE && retry < 20) + { + retry++; + goto loop; + } + #ifdef VMS socket_close (s); *************** *** 1521,1524 **** --- 1660,1667 ---- close (s); #endif + + if (interrupt_input) + request_sigio (); + errno = xerrno; report_file_error ("connection failed", *************** *** 1526,1529 **** --- 1669,1687 ---- } + #ifdef POLL_FOR_INPUT + unbind_to (count, Qnil); + #endif + + if (interrupt_input) + request_sigio (); + + #else /* TERM */ + s = connect_server (0); + if (s < 0) + report_file_error ("error creating socket", Fcons (name, Qnil)); + send_command (s, C_PORT, 0, "%s:%d", XSTRING (host)->data, ntohs (port)); + send_command (s, C_DUMB, 1, 0); + #endif /* TERM */ + #ifdef VMS { *************** *** 1568,1571 **** --- 1726,1731 ---- XPROCESS (proc)->status = Qrun; FD_SET (inch, &input_wait_mask); + if (inch > max_process_desc) + max_process_desc = inch; UNGCPRO; *************** *** 1604,1611 **** if (outchannel >= 0 && outchannel != inchannel) close (outchannel); - #ifdef SYSV4_PTYS - if (!NILP (p->subtty)) - close (XINT (p->subtty)); - #endif #endif --- 1764,1767 ---- *************** *** 1614,1617 **** --- 1770,1783 ---- chan_process[inchannel] = Qnil; FD_CLR (inchannel, &input_wait_mask); + if (inchannel == max_process_desc) + { + int i; + /* We just closed the highest-numbered process input descriptor, + so recompute the highest-numbered one now. */ + max_process_desc = 0; + for (i = 0; i < MAXDESC; i++) + if (!NILP (chan_process[i])) + max_process_desc = i; + } } } *************** *** 1717,1721 **** for user-input when that process-filter was called. waiting_for_input cannot be used as that is by definition 0 when ! lisp code is being evalled */ static int waiting_for_user_input_p; --- 1883,1890 ---- for user-input when that process-filter was called. waiting_for_input cannot be used as that is by definition 0 when ! lisp code is being evalled. ! This is also used in record_asynch_buffer_change. ! For that purpose, this must be 0 ! when not inside wait_reading_process_input. */ static int waiting_for_user_input_p; *************** *** 1797,1800 **** --- 1966,1974 ---- } + /* It would not be safe to call this below, + where we call redisplay_preserve_echo_area. */ + if (do_display && frame_garbaged) + prepare_menu_bars (); + while (1) { *************** *** 1851,1855 **** { /* It's okay for us to do this and then continue with ! the loop, since timeout has already been zeroed out. */ clear_waiting_for_input (); status_notify (); --- 2025,2029 ---- { /* It's okay for us to do this and then continue with ! the loop, since timeout has already been zeroed out. */ clear_waiting_for_input (); status_notify (); *************** *** 1870,1877 **** Available = input_wait_mask; ! /* We used to have && wait_for_cell == 0 ! but that led to lossage handling selection_request events: ! within one, we would start to handle another. */ ! if (! XINT (read_kbd)) FD_CLR (keyboard_descriptor, &Available); --- 2044,2048 ---- Available = input_wait_mask; ! if (! XINT (read_kbd) && wait_for_cell == 0) FD_CLR (keyboard_descriptor, &Available); *************** *** 1881,1885 **** and indicates that a frame is trashed, the select may block displaying a trashed screen. */ ! if (frame_garbaged) redisplay_preserve_echo_area (); --- 2052,2056 ---- and indicates that a frame is trashed, the select may block displaying a trashed screen. */ ! if (frame_garbaged && do_display) redisplay_preserve_echo_area (); *************** *** 1929,1933 **** yielding EBADF here or at select() call above. So, SIGHUP is ignored (see def of PTY_TTY_NAME_SPRINTF ! in m-ibmrt-aix.h), and here we just ignore the select error. Cleanup occurs c/o status_notify after SIGCLD. */ FD_ZERO (&Available); /* Cannot depend on values returned */ --- 2100,2104 ---- yielding EBADF here or at select() call above. So, SIGHUP is ignored (see def of PTY_TTY_NAME_SPRINTF ! in m/ibmrt-aix.h), and here we just ignore the select error. Cleanup occurs c/o status_notify after SIGCLD. */ FD_ZERO (&Available); /* Cannot depend on values returned */ *************** *** 1937,1953 **** } else - { - #if 0 - error("select error: %s", sys_errlist[xerrno]); - #else #ifdef VMS ! char *errmsg = strerror(xerrno, vaxc$errno); #else ! char *errmsg = strerror(xerrno); ! #endif ! error("select error: %s", ! errmsg == 0 ? "undocumented error" : errmsg); ! #endif ! } } #if defined(sun) && !defined(USG5_4) --- 2108,2115 ---- } else #ifdef VMS ! error("select error: %s", strerror (xerrno, vaxc$errno)); #else ! error("select error: %s", strerror (xerrno)); } #if defined(sun) && !defined(USG5_4) *************** *** 1968,1974 **** to give it higher priority than subprocesses */ ! /* We used to do his if wait_for_cell, but that caused infinite recursion in selection request events. */ ! if ((XINT (read_kbd)) && detect_input_pending ()) { --- 2130,2136 ---- to give it higher priority than subprocesses */ ! /* We used to do this if wait_for_cell, but that caused infinite recursion in selection request events. */ ! if ((XINT (read_kbd) || wait_for_cell) && detect_input_pending ()) { *************** *** 2005,2009 **** but this is safer in the short run. */ for (channel = keyboard_descriptor == 0 ? FIRST_PROC_DESC : 0; ! channel < MAXDESC; channel++) { if (FD_ISSET (channel, &Available)) --- 2167,2171 ---- but this is safer in the short run. */ for (channel = keyboard_descriptor == 0 ? FIRST_PROC_DESC : 0; ! channel <= max_process_desc; channel++) { if (FD_ISSET (channel, &Available)) *************** *** 2091,2094 **** --- 2253,2258 ---- } /* end while exit conditions not met */ + waiting_for_user_input_p = 0; + /* If calling from keyboard input, do not quit since we want to return C-g as an input character. *************** *** 2129,2133 **** nchars = vms_read_fd (channel, chars, sizeof chars, vs->translate_p); #else /* not VMS */ - if (proc_buffered_char[channel] < 0) nchars = read (channel, chars, sizeof chars); --- 2293,2296 ---- *************** *** 2154,2161 **** --- 2317,2327 ---- int count = specpdl_ptr - specpdl; Lisp_Object odeactivate; + Lisp_Object obuffer; odeactivate = Vdeactivate_mark; + obuffer = Fcurrent_buffer (); specbind (Qinhibit_quit, Qt); + specbind (Qlast_nonmenu_event, Qt); call2 (outstream, proc, make_string (chars, nchars)); *************** *** 2163,2166 **** --- 2329,2338 ---- Vdeactivate_mark = odeactivate; + if (! EQ (Fcurrent_buffer (), obuffer)) + record_asynch_buffer_change (); + + if (waiting_for_user_input_p) + prepare_menu_bars (); + unbind_to (count, Qnil); return nchars; *************** *** 2188,2192 **** thus preserving logical ordering of input and output. */ if (XMARKER (p->mark)->buffer) ! SET_PT (marker_position (p->mark)); else SET_PT (ZV); --- 2360,2364 ---- thus preserving logical ordering of input and output. */ if (XMARKER (p->mark)->buffer) ! SET_PT (clip_to_bounds (BEGV, marker_position (p->mark), ZV)); else SET_PT (ZV); *************** *** 2231,2239 **** DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p, Swaiting_for_user_input_p, 0, 0, 0, ! "Returns non-NIL if emacs is waiting for input from the user.\n\ This is intended for use by asynchronous process output filters and sentinels.") () { ! return ((waiting_for_user_input_p) ? Qt : Qnil); } --- 2403,2411 ---- DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p, Swaiting_for_user_input_p, 0, 0, 0, ! "Returns non-nil if emacs is waiting for input from the user.\n\ This is intended for use by asynchronous process output filters and sentinels.") () { ! return (waiting_for_user_input_p ? Qt : Qnil); } *************** *** 2252,2261 **** longjmp (send_process_frame, 1); } ! #endif /* not VMS */ ! send_process (proc, buf, len) Lisp_Object proc; char *buf; int len; { /* Don't use register vars; longjmp can lose them. */ --- 2424,2438 ---- longjmp (send_process_frame, 1); } ! #endif ! ! /* Send some data to process PROC. ! BUF is the beginning of the data; LEN is the number of characters. ! OBJECT is the Lisp object that the data comes from. */ ! send_process (proc, buf, len, object) Lisp_Object proc; char *buf; int len; + Lisp_Object object; { /* Don't use register vars; longjmp can lose them. */ *************** *** 2263,2267 **** unsigned char *procname = XSTRING (XPROCESS (proc)->name)->data; - #ifdef VMS struct Lisp_Process *p = XPROCESS (proc); --- 2440,2443 ---- *************** *** 2277,2280 **** --- 2453,2470 ---- error ("Process %s not running", procname); + if (pty_max_bytes == 0) + { + #if defined (HAVE_FPATHCONF) && defined (_PC_MAX_CANON) + pty_max_bytes = fpathconf (XFASTINT (XPROCESS (proc)->outfd), + _PC_MAX_CANON); + if (pty_max_bytes < 0) + pty_max_bytes = 250; + #else + pty_max_bytes = 250; + #endif + /* Deduct one, to leave space for the eof. */ + pty_max_bytes--; + } + if (!setjmp (send_process_frame)) while (len > 0) *************** *** 2282,2289 **** int this = len; SIGTYPE (*old_sigpipe)(); ! /* Don't send more than 500 bytes at a time. */ ! if (this > 500) ! this = 500; #ifdef VMS #ifdef DEBUG --- 2472,2508 ---- int this = len; SIGTYPE (*old_sigpipe)(); + int flush_pty = 0; ! /* Decide how much data we can send in one batch. ! Long lines need to be split into multiple batches. */ ! if (!NILP (XPROCESS (proc)->pty_flag)) ! { ! /* Starting this at zero is always correct when not the first iteration ! because the previous iteration ended by sending C-d. ! It may not be correct for the first iteration ! if a partial line was sent in a separate send_process call. ! If that proves worth handling, we need to save linepos ! in the process object. */ ! int linepos = 0; ! char *ptr = buf; ! char *end = buf + len; ! ! /* Scan through this text for a line that is too long. */ ! while (ptr != end && linepos < pty_max_bytes) ! { ! if (*ptr == '\n') ! linepos = 0; ! else ! linepos++; ! ptr++; ! } ! /* If we found one, break the line there ! and put in a C-d to force the buffer through. */ ! this = ptr - buf; ! } ! ! /* Send this batch, using one or more write calls. */ ! while (this > 0) ! { #ifdef VMS #ifdef DEBUG *************** *** 2293,2333 **** vs->translate_p); #else ! old_sigpipe = (SIGTYPE (*) ()) signal (SIGPIPE, send_process_trap); ! rv = write (XINT (XPROCESS (proc)->outfd), buf, this); ! signal (SIGPIPE, old_sigpipe); ! #endif ! if (rv < 0) ! { ! if (0 #ifdef EWOULDBLOCK ! || errno == EWOULDBLOCK #endif #ifdef EAGAIN ! || errno == EAGAIN #endif ! ) ! { ! /* It would be nice to accept process output here, ! but that is difficult. For example, it could ! garbage what we are sending if that is from a buffer. */ ! immediate_quit = 1; ! QUIT; ! sleep (1); ! immediate_quit = 0; ! continue; } ! report_file_error ("writing to process", Fcons (proc, Qnil)); } - buf += rv; - len -= rv; - /* Allow input from processes between bursts of sending. - Otherwise things may get stopped up. */ - if (len > 0) - { - Lisp_Object zero; ! XFASTINT (zero) = 0; ! wait_reading_process_input (-1, 0, zero, 0); ! } } else --- 2512,2568 ---- vs->translate_p); #else ! old_sigpipe = (SIGTYPE (*) ()) signal (SIGPIPE, send_process_trap); ! rv = write (XINT (XPROCESS (proc)->outfd), buf, this); ! signal (SIGPIPE, old_sigpipe); ! #endif /* VMS */ ! ! if (rv < 0) ! { ! if (0 #ifdef EWOULDBLOCK ! || errno == EWOULDBLOCK #endif #ifdef EAGAIN ! || errno == EAGAIN #endif ! ) ! /* Buffer is full. Wait, accepting input; ! that may allow the program ! to finish doing output and read more. */ ! { ! Lisp_Object zero; ! int offset; ! ! /* Running filters might relocate buffers or strings. ! Arrange to relocate BUF. */ ! if (BUFFERP (object)) ! offset = BUF_PTR_CHAR_POS (XBUFFER (object), ! (unsigned char *) buf); ! else if (STRINGP (object)) ! offset = buf - (char *) XSTRING (object)->data; ! ! XFASTINT (zero) = 0; ! wait_reading_process_input (1, 0, zero, 0); ! ! if (BUFFERP (object)) ! buf = (char *) BUF_CHAR_ADDRESS (XBUFFER (object), offset); ! else if (STRINGP (object)) ! buf = offset + (char *) XSTRING (object)->data; ! ! rv = 0; ! } ! else ! /* This is a real error. */ ! report_file_error ("writing to process", Fcons (proc, Qnil)); } ! buf += rv; ! len -= rv; ! this -= rv; } ! /* If we sent just part of the string, put in an EOF ! to force it through, before we send the rest. */ ! if (len > 0) ! Fprocess_send_eof (proc); } else *************** *** 2368,2372 **** start1 = XINT (start); ! send_process (proc, &FETCH_CHAR (start1), XINT (end) - XINT (start)); return Qnil; --- 2603,2608 ---- start1 = XINT (start); ! send_process (proc, &FETCH_CHAR (start1), XINT (end) - XINT (start), ! Fcurrent_buffer ()); return Qnil; *************** *** 2387,2391 **** CHECK_STRING (string, 1); proc = get_process (process); ! send_process (proc, XSTRING (string)->data, XSTRING (string)->size); return Qnil; } --- 2623,2627 ---- CHECK_STRING (string, 1); proc = get_process (process); ! send_process (proc, XSTRING (string)->data, XSTRING (string)->size, string); return Qnil; } *************** *** 2399,2403 **** If we can, we try to signal PROCESS by sending control characters ! down the pipe. This allows us to signal inferiors who have changed their uid, for which killpg would return an EPERM error. */ --- 2635,2639 ---- If we can, we try to signal PROCESS by sending control characters ! down the pty. This allows us to signal inferiors who have changed their uid, for which killpg would return an EPERM error. */ *************** *** 2443,2460 **** case SIGINT: tcgetattr (XINT (p->infd), &t); ! send_process (proc, &t.c_cc[VINTR], 1); return; case SIGQUIT: tcgetattr (XINT (p->infd), &t); ! send_process (proc, &t.c_cc[VQUIT], 1); return; case SIGTSTP: tcgetattr (XINT (p->infd), &t); ! #if defined (VSWTCH) && !defined (IRIX5) ! send_process (proc, &t.c_cc[VSWTCH], 1); #else ! send_process (proc, &t.c_cc[VSUSP], 1); #endif return; --- 2679,2696 ---- case SIGINT: tcgetattr (XINT (p->infd), &t); ! send_process (proc, &t.c_cc[VINTR], 1, Qnil); return; case SIGQUIT: tcgetattr (XINT (p->infd), &t); ! send_process (proc, &t.c_cc[VQUIT], 1, Qnil); return; case SIGTSTP: tcgetattr (XINT (p->infd), &t); ! #if defined (VSWTCH) && !defined (PREFER_VSUSP) ! send_process (proc, &t.c_cc[VSWTCH], 1, Qnil); #else ! send_process (proc, &t.c_cc[VSUSP], 1, Qnil); #endif return; *************** *** 2474,2487 **** case SIGINT: ioctl (XINT (p->infd), TIOCGETC, &c); ! send_process (proc, &c.t_intrc, 1); return; case SIGQUIT: ioctl (XINT (p->infd), TIOCGETC, &c); ! send_process (proc, &c.t_quitc, 1); return; #ifdef SIGTSTP case SIGTSTP: ioctl (XINT (p->infd), TIOCGLTC, &lc); ! send_process (proc, &lc.t_suspc, 1); return; #endif /* ! defined (SIGTSTP) */ --- 2710,2723 ---- case SIGINT: ioctl (XINT (p->infd), TIOCGETC, &c); ! send_process (proc, &c.t_intrc, 1, Qnil); return; case SIGQUIT: ioctl (XINT (p->infd), TIOCGETC, &c); ! send_process (proc, &c.t_quitc, 1, Qnil); return; #ifdef SIGTSTP case SIGTSTP: ioctl (XINT (p->infd), TIOCGLTC, &lc); ! send_process (proc, &lc.t_suspc, 1, Qnil); return; #endif /* ! defined (SIGTSTP) */ *************** *** 2498,2511 **** case SIGINT: ioctl (XINT (p->infd), TCGETA, &t); ! send_process (proc, &t.c_cc[VINTR], 1); return; case SIGQUIT: ioctl (XINT (p->infd), TCGETA, &t); ! send_process (proc, &t.c_cc[VQUIT], 1); return; #ifdef SIGTSTP case SIGTSTP: ioctl (XINT (p->infd), TCGETA, &t); ! send_process (proc, &t.c_cc[VSWTCH], 1); return; #endif /* ! defined (SIGTSTP) */ --- 2734,2747 ---- case SIGINT: ioctl (XINT (p->infd), TCGETA, &t); ! send_process (proc, &t.c_cc[VINTR], 1, Qnil); return; case SIGQUIT: ioctl (XINT (p->infd), TCGETA, &t); ! send_process (proc, &t.c_cc[VQUIT], 1, Qnil); return; #ifdef SIGTSTP case SIGTSTP: ioctl (XINT (p->infd), TCGETA, &t); ! send_process (proc, &t.c_cc[VSWTCH], 1, Qnil); return; #endif /* ! defined (SIGTSTP) */ *************** *** 2572,2588 **** case SIGINT: #ifdef VMS ! send_process (proc, "\003", 1); /* ^C */ goto whoosh; #endif case SIGQUIT: #ifdef VMS ! #if 1 /* Experimental */ ! { ! unsigned long tem_pid = (getpid () & 0xffff0000) | (XFASTINT (p->pid)); ! sys$forcex (&tem_pid, 0, SS$_FORCEDEXIT); ! } ! #else ! send_process (proc, "\031", 1); /* ^Y */ ! #endif goto whoosh; #endif --- 2808,2818 ---- case SIGINT: #ifdef VMS ! send_process (proc, "\003", 1, Qnil); /* ^C */ goto whoosh; #endif case SIGQUIT: #ifdef VMS ! unsigned long tem_pid = (getpid () & 0xffff0000) | (XFASTINT (p->pid)); ! sys$forcex (&tem_pid, 0, SS$_FORCEDEXIT); goto whoosh; #endif *************** *** 2625,2629 **** "Interrupt process PROCESS. May be process or name of one.\n\ PROCESS may be a process, a buffer, or the name of a process or buffer.\n\ ! Nil or no arg means current buffer's process.\n\ Second arg CURRENT-GROUP non-nil means send signal to\n\ the current process-group of the process's controlling terminal\n\ --- 2855,2859 ---- "Interrupt process PROCESS. May be process or name of one.\n\ PROCESS may be a process, a buffer, or the name of a process or buffer.\n\ ! nil or no arg means current buffer's process.\n\ Second arg CURRENT-GROUP non-nil means send signal to\n\ the current process-group of the process's controlling terminal\n\ *************** *** 2702,2706 **** Eof comes after any text already sent to it.\n\ PROCESS may be a process, a buffer, the name of a process or buffer, or\n\ ! nil, indicating the current buffer's process.") (process) Lisp_Object process; --- 2932,2939 ---- Eof comes after any text already sent to it.\n\ PROCESS may be a process, a buffer, the name of a process or buffer, or\n\ ! nil, indicating the current buffer's process.\n\ ! If PROCESS is a network connection, or is a process communicating\n\ ! through a pipe (as opposed to a pty), then you cannot send any more\n\ ! text to PROCESS after you call this function.") (process) Lisp_Object process; *************** *** 2725,2732 **** #else /* did not do TOICREMOTE */ #ifdef VMS ! send_process (proc, "\032", 1); /* ^z */ #else if (!NILP (XPROCESS (proc)->pty_flag)) ! send_process (proc, "\004", 1); else { --- 2958,2965 ---- #else /* did not do TOICREMOTE */ #ifdef VMS ! send_process (proc, "\032", 1, Qnil); /* ^z */ #else if (!NILP (XPROCESS (proc)->pty_flag)) ! send_process (proc, "\004", 1, Qnil); else { *************** *** 2755,2759 **** { if (NETCONN_P (proc)) ! deactivate_process (proc); else if (XINT (XPROCESS (proc)->infd) >= 0) process_send_signal (proc, SIGHUP, Qnil, 1); --- 2988,2992 ---- { if (NETCONN_P (proc)) ! Fdelete_process (proc); else if (XINT (XPROCESS (proc)->infd) >= 0) process_send_signal (proc, SIGHUP, Qnil, 1); *************** *** 2890,2906 **** synch_process_retcode = WRETCODE (w); else if (WIFSIGNALED (w)) ! #ifndef VMS ! synch_process_death = (char *) sys_siglist[WTERMSIG (w)]; ! #else ! #if 0 ! synch_process_death = sys_errlist[WTERMSIG (w)]; ! #else ! #ifdef VMS ! synch_process_death = strerror (WTERMSIG (w), vaxc$errno); ! #else ! synch_process_death = strerror (WTERMSIG (w)); ! #endif ! #endif ! #endif /* Tell wait_reading_process_input that it needs to wake up and --- 3123,3137 ---- synch_process_retcode = WRETCODE (w); else if (WIFSIGNALED (w)) ! { ! int code = WTERMSIG (w); ! char *signame = 0; ! ! if (code < NSIG) ! signame = sys_siglist[code]; ! if (signame == 0) ! signame = "unknown"; ! ! synch_process_death = signame; ! } /* Tell wait_reading_process_input that it needs to wake up and *************** *** 2938,2945 **** Lisp_Object proc, reason; { ! Lisp_Object sentinel; register struct Lisp_Process *p = XPROCESS (proc); int count = specpdl_ptr - specpdl; sentinel = p->sentinel; if (NILP (sentinel)) --- 3169,3178 ---- Lisp_Object proc, reason; { ! Lisp_Object sentinel, obuffer, odeactivate; register struct Lisp_Process *p = XPROCESS (proc); int count = specpdl_ptr - specpdl; + odeactivate = Vdeactivate_mark; + obuffer = Fcurrent_buffer (); sentinel = p->sentinel; if (NILP (sentinel)) *************** *** 2952,2956 **** --- 3185,3197 ---- /* Inhibit quit so that random quits don't screw up a running filter. */ specbind (Qinhibit_quit, Qt); + specbind (Qlast_nonmenu_event, Qt); call2 (sentinel, proc, reason); + + Vdeactivate_mark = odeactivate; + if (! EQ (Fcurrent_buffer (), obuffer)) + record_asynch_buffer_change (); + + if (waiting_for_user_input_p) + prepare_menu_bars (); unbind_to (count, Qnil); } *************** *** 2963,2970 **** { register Lisp_Object proc, buffer; ! Lisp_Object tail = Qnil; ! Lisp_Object msg = Qnil; struct gcpro gcpro1, gcpro2; /* We need to gcpro tail; if read_process_output calls a filter which deletes a process and removes the cons to which tail points --- 3204,3212 ---- { register Lisp_Object proc, buffer; ! Lisp_Object tail, msg; struct gcpro gcpro1, gcpro2; + tail = Qnil; + msg = Qnil; /* We need to gcpro tail; if read_process_output calls a filter which deletes a process and removes the cons to which tail points *************** *** 3018,3026 **** else if (!EQ (symbol, Qrun) && !NILP (buffer)) { ! Lisp_Object ro = XBUFFER (buffer)->read_only; ! Lisp_Object tem; struct buffer *old = current_buffer; int opoint; /* Avoid error if buffer is deleted (probably that's why the process is dead, too) */ --- 3260,3269 ---- else if (!EQ (symbol, Qrun) && !NILP (buffer)) { ! Lisp_Object ro, tem; struct buffer *old = current_buffer; int opoint; + ro = XBUFFER (buffer)->read_only; + /* Avoid error if buffer is deleted (probably that's why the process is dead, too) */ *************** *** 3074,3077 **** --- 3317,3321 ---- FD_ZERO (&input_wait_mask); + max_process_desc = 0; keyboard_descriptor = 0; *************** *** 3129,3132 **** --- 3373,3379 ---- staticpro (&Qclosed); + Qlast_nonmenu_event = intern ("last-nonmenu-event"); + staticpro (&Qlast_nonmenu_event); + staticpro (&Vprocess_alist); *************** *** 3139,3145 **** DEFVAR_LISP ("process-connection-type", &Vprocess_connection_type, "Control type of device used to communicate with subprocesses.\n\ ! Values are nil to use a pipe, and t or 'pty for a pty. Note that if\n\ ! pty's are not available, this variable will be ignored. The value takes\n\ ! effect when `start-process' is called."); Vprocess_connection_type = Qt; --- 3386,3393 ---- DEFVAR_LISP ("process-connection-type", &Vprocess_connection_type, "Control type of device used to communicate with subprocesses.\n\ ! Values are nil to use a pipe, or t or `pty' to use a pty.\n\ ! The value has no effect if the system has no ptys or if all ptys are busy:\n\ ! then a pipe is used in any case.\n\ ! The value takes effect when `start-process' is called."); Vprocess_connection_type = Qt; *************** *** 3159,3162 **** --- 3407,3411 ---- defsubr (&Sprocess_filter); defsubr (&Sset_process_sentinel); + defsubr (&Sset_process_window_size); defsubr (&Sprocess_sentinel); defsubr (&Sprocess_kill_without_query); *************** *** 3212,3216 **** do_display != 0 means redisplay should be done to show subprocess ! output that arrives. This version of the function ignores it. Return true iff we received input from any process. */ --- 3461,3465 ---- do_display != 0 means redisplay should be done to show subprocess ! output that arrives. Return true iff we received input from any process. */ *************** *** 3245,3248 **** --- 3494,3500 ---- timeout_p = 0; + /* This must come before stop_polling. */ + prepare_menu_bars (); + /* Turn off periodic alarms (in case they are in use) because the select emulator uses alarms. */ *************** *** 3276,3280 **** /* If a frame has been newly mapped and needs updating, reprocess its display stuff. */ ! if (frame_garbaged) redisplay_preserve_echo_area (); --- 3528,3532 ---- /* If a frame has been newly mapped and needs updating, reprocess its display stuff. */ ! if (frame_garbaged && do_display) redisplay_preserve_echo_area (); *************** *** 3320,3324 **** DEFUN ("get-buffer-process", Fget_buffer_process, Sget_buffer_process, 1, 1, 0, ! /* Don't confused make-docfile by having two doc strings for this function. make-docfile does not pay attention to #if, for good reason! */ 0) --- 3572,3576 ---- DEFUN ("get-buffer-process", Fget_buffer_process, Sget_buffer_process, 1, 1, 0, ! /* Don't confuse make-docfile by having two doc strings for this function. make-docfile does not pay attention to #if, for good reason! */ 0)