#include "blockinput.h"
#include "keyboard.h"
#include "dispextern.h"
+#include "composite.h"
+#include "atimer.h"
#define max(a, b) ((a) > (b) ? (a) : (b))
DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0,
"Start a program in a subprocess. Return the process object for it.\n\
-Args are NAME BUFFER PROGRAM &rest PROGRAM-ARGS\n\
NAME is name for process. It is modified if necessary to make it unique.\n\
BUFFER is the buffer or (buffer-name) to associate with the process.\n\
Process output goes at end of that buffer, unless you specify\n\
return Qnil;
}
-
-SIGTYPE
-create_process_1 (signo)
- int signo;
+void
+create_process_1 (timer)
+ struct atimer *timer;
{
-#if defined (USG) && !defined (POSIX_SIGNALS)
- /* USG systems forget handlers when they are used;
- must reestablish each time */
- signal (signo, create_process_1);
-#endif /* USG */
+ /* Nothing to do. */
}
+
#if 0 /* This doesn't work; see the note before sigchld_handler. */
#ifdef USG
#ifdef SIGCHLD
/* If the subfork execv fails, and it exits,
this close hangs. I don't know why.
So have an interrupt jar it loose. */
- stop_polling ();
- signal (SIGALRM, create_process_1);
- alarm (1);
- XPROCESS (process)->subtty = Qnil;
- if (forkin >= 0)
- emacs_close (forkin);
- alarm (0);
- start_polling ();
+ {
+ struct atimer *timer;
+ EMACS_TIME offset;
+
+ stop_polling ();
+ EMACS_SET_SECS_USECS (offset, 1, 0);
+ timer = start_atimer (ATIMER_RELATIVE, offset, create_process_1, 0);
+
+ XPROCESS (process)->subtty = Qnil;
+ if (forkin >= 0)
+ emacs_close (forkin);
+
+ cancel_atimer (timer);
+ start_polling ();
+ }
+
if (forkin != forkout && forkout >= 0)
emacs_close (forkout);
Some kernels have a bug which causes retrying connect to fail
after a connect. Polling can interfere with gethostbyname too. */
#ifdef POLL_FOR_INPUT
+ record_unwind_protect (unwind_stop_other_atimers, Qnil);
bind_polling_period (10);
#endif
Causes "poll: interrupted system call" messages when Emacs is run
in an X window
Turn off periodic alarms (in case they are in use) */
- stop_polling ();
+ turn_on_atimers (0);
#endif
while (1)
{
int timeout_reduced_for_timers = 0;
-#ifdef HAVE_X_WINDOWS
- if (display_busy_cursor_p)
- Fx_hide_busy_cursor (Qnil);
-#endif
-
/* If calling from keyboard input, do not quit
since we want to return C-g as an input character.
Otherwise, do pending quit if requested. */
start_polling ();
#endif
-#ifdef HAVE_X_WINDOWS
- if (display_busy_cursor_p)
- if (!inhibit_busy_cursor)
- Fx_show_busy_cursor ();
-#endif
-
return got_some_input;
}
\f
Vinhibit_quit = Qt;
update_echo_area ();
Fsleep_for (make_number (2), Qnil);
+ return Qt;
}
/* Read pending output from the process channel,
else
{
insert_1_both (chars, nchars, nbytes, 0, 1, 1);
- signal_after_change (opoint, 0, PT - opoint);
+ signal_after_change (before, 0, PT - before);
+ update_compositions (before, PT, CHECK_BORDER);
}
set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
is sent. But if the data ends at the middle of multi-byte
representation, that incomplete sequence of bytes are sent without
being encoded. Should we store them in a buffer to prepend them to
- the data send later? */
+ the data send later?
+
+ This function can evaluate Lisp code and can garbage collect. */
void
send_process (proc, buf, len, object)
{
/* Use volatile to protect variables from being clobbered by longjmp. */
int rv;
- volatile unsigned char *procname = XSTRING (XPROCESS (proc)->name)->data;
struct coding_system *coding;
struct gcpro gcpro1;
int carryover = XINT (XPROCESS (proc)->encoding_carryover);
if (! NILP (XPROCESS (proc)->raw_status_low))
update_status (XPROCESS (proc));
if (! EQ (XPROCESS (proc)->status, Qrun))
- error ("Process %s not running", procname);
+ error ("Process %s not running",
+ XSTRING (XPROCESS (proc)->name)->data);
if (XINT (XPROCESS (proc)->outfd) < 0)
- error ("Output file descriptor of %s is closed", procname);
+ error ("Output file descriptor of %s is closed",
+ XSTRING (XPROCESS (proc)->name)->data);
coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)];
Vlast_coding_system_used = coding->symbol;
Lisp_Object zero;
int offset;
+#ifdef BROKEN_PTY_READ_AFTER_EAGAIN
+ /* A gross hack to work around a bug in FreeBSD.
+ In the following sequence, read(2) returns
+ bogus data:
+
+ write(2) 1022 bytes
+ write(2) 954 bytes, get EAGAIN
+ read(2) 1024 bytes in process_read_output
+ read(2) 11 bytes in process_read_output
+
+ That is, read(2) returns more bytes than have
+ ever been written successfully. The 1033 bytes
+ read are the 1022 bytes written successfully
+ after processing (for example with CRs added if
+ the terminal is set up that way which it is
+ here). The same bytes will be seen again in a
+ later read(2), without the CRs. */
+
+ if (errno == EAGAIN)
+ {
+ int flags = FWRITE;
+ ioctl (XINT (XPROCESS (proc)->outfd), TIOCFLUSH,
+ &flags);
+ }
+#endif /* BROKEN_PTY_READ_AFTER_EAGAIN */
+
/* Running filters might relocate buffers or strings.
Arrange to relocate BUF. */
if (BUFFERP (object))
XSETINT (XPROCESS (proc)->tick, ++process_tick);
deactivate_process (proc);
#ifdef VMS
- error ("Error writing to process %s; closed it", procname);
+ error ("Error writing to process %s; closed it",
+ XSTRING (XPROCESS (proc)->name)->data);
#else
- error ("SIGPIPE raised on process %s; closed it", procname);
+ error ("SIGPIPE raised on process %s; closed it",
+ XSTRING (XPROCESS (proc)->name)->data);
#endif
}
Vinhibit_quit = Qt;
update_echo_area ();
Fsleep_for (make_number (2), Qnil);
+ return Qt;
}
static void
/* Turn off periodic alarms (in case they are in use)
because the select emulator uses alarms. */
- stop_polling ();
+ turn_on_atimers (0);
while (1)
{