- Fprovide (intern_c_string ("make-network-process"), subfeatures);
- }
-#endif /* HAVE_SOCKETS */
-
-#if defined (DARWIN_OS)
- /* PTYs are broken on Darwin < 6, but are sometimes useful for interactive
- processes. As such, we only change the default value. */
- if (initialized)
- {
- char *release = get_operating_system_release();
- if (!release || !release[0] || (release[0] < MIN_PTY_KERNEL_VERSION
- && release[1] == '.')) {
- Vprocess_connection_type = Qnil;
- }
- }
-#endif
-}
-
-void
-syms_of_process ()
-{
- Qprocessp = intern_c_string ("processp");
- staticpro (&Qprocessp);
- Qrun = intern_c_string ("run");
- staticpro (&Qrun);
- Qstop = intern_c_string ("stop");
- staticpro (&Qstop);
- Qsignal = intern_c_string ("signal");
- staticpro (&Qsignal);
-
- /* Qexit is already staticpro'd by syms_of_eval; don't staticpro it
- here again.
-
- Qexit = intern_c_string ("exit");
- staticpro (&Qexit); */
-
- Qopen = intern_c_string ("open");
- staticpro (&Qopen);
- Qclosed = intern_c_string ("closed");
- staticpro (&Qclosed);
- Qconnect = intern_c_string ("connect");
- staticpro (&Qconnect);
- Qfailed = intern_c_string ("failed");
- staticpro (&Qfailed);
- Qlisten = intern_c_string ("listen");
- staticpro (&Qlisten);
- Qlocal = intern_c_string ("local");
- staticpro (&Qlocal);
- Qipv4 = intern_c_string ("ipv4");
- staticpro (&Qipv4);
-#ifdef AF_INET6
- Qipv6 = intern_c_string ("ipv6");
- staticpro (&Qipv6);
-#endif
- Qdatagram = intern_c_string ("datagram");
- staticpro (&Qdatagram);
- Qseqpacket = intern_c_string ("seqpacket");
- staticpro (&Qseqpacket);
-
- QCport = intern_c_string (":port");
- staticpro (&QCport);
- QCspeed = intern_c_string (":speed");
- staticpro (&QCspeed);
- QCprocess = intern_c_string (":process");
- staticpro (&QCprocess);
-
- QCbytesize = intern_c_string (":bytesize");
- staticpro (&QCbytesize);
- QCstopbits = intern_c_string (":stopbits");
- staticpro (&QCstopbits);
- QCparity = intern_c_string (":parity");
- staticpro (&QCparity);
- Qodd = intern_c_string ("odd");
- staticpro (&Qodd);
- Qeven = intern_c_string ("even");
- staticpro (&Qeven);
- QCflowcontrol = intern_c_string (":flowcontrol");
- staticpro (&QCflowcontrol);
- Qhw = intern_c_string ("hw");
- staticpro (&Qhw);
- Qsw = intern_c_string ("sw");
- staticpro (&Qsw);
- QCsummary = intern_c_string (":summary");
- staticpro (&QCsummary);
-
- Qreal = intern_c_string ("real");
- staticpro (&Qreal);
- Qnetwork = intern_c_string ("network");
- staticpro (&Qnetwork);
- Qserial = intern_c_string ("serial");
- staticpro (&Qserial);
-
- QCname = intern_c_string (":name");
- staticpro (&QCname);
- QCbuffer = intern_c_string (":buffer");
- staticpro (&QCbuffer);
- QChost = intern_c_string (":host");
- staticpro (&QChost);
- QCservice = intern_c_string (":service");
- staticpro (&QCservice);
- QCtype = intern_c_string (":type");
- staticpro (&QCtype);
- QClocal = intern_c_string (":local");
- staticpro (&QClocal);
- QCremote = intern_c_string (":remote");
- staticpro (&QCremote);
- QCcoding = intern_c_string (":coding");
- staticpro (&QCcoding);
- QCserver = intern_c_string (":server");
- staticpro (&QCserver);
- QCnowait = intern_c_string (":nowait");
- staticpro (&QCnowait);
- QCsentinel = intern_c_string (":sentinel");
- staticpro (&QCsentinel);
- QClog = intern_c_string (":log");
- staticpro (&QClog);
- QCnoquery = intern_c_string (":noquery");
- staticpro (&QCnoquery);
- QCstop = intern_c_string (":stop");
- staticpro (&QCstop);
- QCoptions = intern_c_string (":options");
- staticpro (&QCoptions);
- QCplist = intern_c_string (":plist");
- staticpro (&QCplist);
-
- Qlast_nonmenu_event = intern_c_string ("last-nonmenu-event");
- staticpro (&Qlast_nonmenu_event);
-
- staticpro (&Vprocess_alist);
-#ifdef SIGCHLD
- staticpro (&deleted_pid_list);
-#endif
-
- Qeuid = intern_c_string ("euid");
- staticpro (&Qeuid);
- Qegid = intern_c_string ("egid");
- staticpro (&Qegid);
- Quser = intern_c_string ("user");
- staticpro (&Quser);
- Qgroup = intern_c_string ("group");
- staticpro (&Qgroup);
- Qcomm = intern_c_string ("comm");
- staticpro (&Qcomm);
- Qstate = intern_c_string ("state");
- staticpro (&Qstate);
- Qppid = intern_c_string ("ppid");
- staticpro (&Qppid);
- Qpgrp = intern_c_string ("pgrp");
- staticpro (&Qpgrp);
- Qsess = intern_c_string ("sess");
- staticpro (&Qsess);
- Qttname = intern_c_string ("ttname");
- staticpro (&Qttname);
- Qtpgid = intern_c_string ("tpgid");
- staticpro (&Qtpgid);
- Qminflt = intern_c_string ("minflt");
- staticpro (&Qminflt);
- Qmajflt = intern_c_string ("majflt");
- staticpro (&Qmajflt);
- Qcminflt = intern_c_string ("cminflt");
- staticpro (&Qcminflt);
- Qcmajflt = intern_c_string ("cmajflt");
- staticpro (&Qcmajflt);
- Qutime = intern_c_string ("utime");
- staticpro (&Qutime);
- Qstime = intern_c_string ("stime");
- staticpro (&Qstime);
- Qtime = intern_c_string ("time");
- staticpro (&Qtime);
- Qcutime = intern_c_string ("cutime");
- staticpro (&Qcutime);
- Qcstime = intern_c_string ("cstime");
- staticpro (&Qcstime);
- Qctime = intern_c_string ("ctime");
- staticpro (&Qctime);
- Qpri = intern_c_string ("pri");
- staticpro (&Qpri);
- Qnice = intern_c_string ("nice");
- staticpro (&Qnice);
- Qthcount = intern_c_string ("thcount");
- staticpro (&Qthcount);
- Qstart = intern_c_string ("start");
- staticpro (&Qstart);
- Qvsize = intern_c_string ("vsize");
- staticpro (&Qvsize);
- Qrss = intern_c_string ("rss");
- staticpro (&Qrss);
- Qetime = intern_c_string ("etime");
- staticpro (&Qetime);
- Qpcpu = intern_c_string ("pcpu");
- staticpro (&Qpcpu);
- Qpmem = intern_c_string ("pmem");
- staticpro (&Qpmem);
- Qargs = intern_c_string ("args");
- staticpro (&Qargs);
-
- DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
- doc: /* *Non-nil means delete processes immediately when they exit.
-A value of nil means don't delete them until `list-processes' is run. */);
-
- delete_exited_processes = 1;
-
- DEFVAR_LISP ("process-connection-type", &Vprocess_connection_type,
- doc: /* Control type of device used to communicate with subprocesses.
-Values are nil to use a pipe, or t or `pty' to use a pty.
-The value has no effect if the system has no ptys or if all ptys are busy:
-then a pipe is used in any case.
-The value takes effect when `start-process' is called. */);
- Vprocess_connection_type = Qt;
-
-#ifdef ADAPTIVE_READ_BUFFERING
- DEFVAR_LISP ("process-adaptive-read-buffering", &Vprocess_adaptive_read_buffering,
- doc: /* If non-nil, improve receive buffering by delaying after short reads.
-On some systems, when Emacs reads the output from a subprocess, the output data
-is read in very small blocks, potentially resulting in very poor performance.
-This behavior can be remedied to some extent by setting this variable to a
-non-nil value, as it will automatically delay reading from such processes, to
-allow them to produce more output before Emacs tries to read it.
-If the value is t, the delay is reset after each write to the process; any other
-non-nil value means that the delay is not reset on write.
-The variable takes effect when `start-process' is called. */);
- Vprocess_adaptive_read_buffering = Qt;
-#endif
-
- defsubr (&Sprocessp);
- defsubr (&Sget_process);
- defsubr (&Sget_buffer_process);
- defsubr (&Sdelete_process);
- defsubr (&Sprocess_status);
- defsubr (&Sprocess_exit_status);
- defsubr (&Sprocess_id);
- defsubr (&Sprocess_name);
- defsubr (&Sprocess_tty_name);
- defsubr (&Sprocess_command);
- defsubr (&Sset_process_buffer);
- defsubr (&Sprocess_buffer);
- defsubr (&Sprocess_mark);
- defsubr (&Sset_process_filter);
- defsubr (&Sprocess_filter);
- defsubr (&Sset_process_sentinel);
- defsubr (&Sprocess_sentinel);
- defsubr (&Sset_process_window_size);
- defsubr (&Sset_process_inherit_coding_system_flag);
- defsubr (&Sprocess_inherit_coding_system_flag);
- defsubr (&Sset_process_query_on_exit_flag);
- defsubr (&Sprocess_query_on_exit_flag);
- defsubr (&Sprocess_contact);
- defsubr (&Sprocess_plist);
- defsubr (&Sset_process_plist);
- defsubr (&Slist_processes);
- defsubr (&Sprocess_list);
- defsubr (&Sstart_process);
-#ifdef HAVE_SERIAL
- defsubr (&Sserial_process_configure);
- defsubr (&Smake_serial_process);
-#endif /* HAVE_SERIAL */
-#ifdef HAVE_SOCKETS
- defsubr (&Sset_network_process_option);
- defsubr (&Smake_network_process);
- defsubr (&Sformat_network_address);
-#endif /* HAVE_SOCKETS */
-#if defined(HAVE_SOCKETS) && defined(HAVE_NET_IF_H) && defined(HAVE_SYS_IOCTL_H)
-#ifdef SIOCGIFCONF
- defsubr (&Snetwork_interface_list);
-#endif
-#if defined(SIOCGIFADDR) || defined(SIOCGIFHWADDR) || defined(SIOCGIFFLAGS)
- defsubr (&Snetwork_interface_info);
-#endif
-#endif /* HAVE_SOCKETS ... */
-#ifdef DATAGRAM_SOCKETS
- defsubr (&Sprocess_datagram_address);
- defsubr (&Sset_process_datagram_address);
-#endif
- defsubr (&Saccept_process_output);
- defsubr (&Sprocess_send_region);
- defsubr (&Sprocess_send_string);
- defsubr (&Sinterrupt_process);
- defsubr (&Skill_process);
- defsubr (&Squit_process);
- defsubr (&Sstop_process);
- defsubr (&Scontinue_process);
- defsubr (&Sprocess_running_child_p);
- defsubr (&Sprocess_send_eof);
- defsubr (&Ssignal_process);
- defsubr (&Swaiting_for_user_input_p);
- defsubr (&Sprocess_type);
- defsubr (&Sset_process_coding_system);
- defsubr (&Sprocess_coding_system);
- defsubr (&Sset_process_filter_multibyte);
- defsubr (&Sprocess_filter_multibyte_p);
- defsubr (&Slist_system_processes);
- defsubr (&Sprocess_attributes);
-}
-
-\f
-#else /* not subprocesses */
-
-#include <sys/types.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <setjmp.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "lisp.h"
-#include "systime.h"
-#include "character.h"
-#include "coding.h"
-#include "termopts.h"
-#include "sysselect.h"
-
-extern int frame_garbaged;
-
-extern EMACS_TIME timer_check ();
-extern int timers_run;
-
-Lisp_Object QCtype, QCname;
-
-Lisp_Object Qeuid, Qegid, Qcomm, Qstate, Qppid, Qpgrp, Qsess, Qttname, Qtpgid;
-Lisp_Object Qminflt, Qmajflt, Qcminflt, Qcmajflt, Qutime, Qstime, Qcstime;
-Lisp_Object Qcutime, Qpri, Qnice, Qthcount, Qstart, Qvsize, Qrss, Qargs;
-Lisp_Object Quser, Qgroup, Qetime, Qpcpu, Qpmem, Qtime, Qctime;
-
-/* As described above, except assuming that there are no subprocesses:
-
- Wait for timeout to elapse and/or keyboard input to be available.
-
- time_limit is:
- timeout in seconds, or
- zero for no limit, or
- -1 means gobble data immediately available but don't wait for any.
-
- read_kbd is a Lisp_Object:
- 0 to ignore keyboard input, or
- 1 to return when input is available, or
- -1 means caller will actually read the input, so don't throw to
- the quit handler.
-
- see full version for other parameters. We know that wait_proc will
- always be NULL, since `subprocesses' isn't defined.
-
- do_display != 0 means redisplay should be done to show subprocess
- output that arrives.
-
- Return true if we received input from any process. */
-
-int
-wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
- wait_for_cell, wait_proc, just_wait_proc)
- int time_limit, microsecs, read_kbd, do_display;
- Lisp_Object wait_for_cell;
- struct Lisp_Process *wait_proc;
- int just_wait_proc;
-{
- register int nfds;
- EMACS_TIME end_time, timeout;
- SELECT_TYPE waitchannels;
- int xerrno;
-
- /* What does time_limit really mean? */
- if (time_limit || microsecs)
- {
- EMACS_GET_TIME (end_time);
- EMACS_SET_SECS_USECS (timeout, time_limit, microsecs);
- EMACS_ADD_TIME (end_time, end_time, timeout);
- }
-
- /* Turn off periodic alarms (in case they are in use)
- and then turn off any other atimers,
- because the select emulator uses alarms. */
- stop_polling ();
- turn_on_atimers (0);
-
- while (1)
- {
- int timeout_reduced_for_timers = 0;
-
- /* 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. */
- if (read_kbd >= 0)
- QUIT;
-
- /* Exit now if the cell we're waiting for became non-nil. */
- if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
- break;
-
- /* Compute time from now till when time limit is up */
- /* Exit if already run out */
- if (time_limit == -1)
- {
- /* -1 specified for timeout means
- gobble output available now
- but don't wait at all. */
-
- EMACS_SET_SECS_USECS (timeout, 0, 0);
- }
- else if (time_limit || microsecs)
- {
- EMACS_GET_TIME (timeout);
- EMACS_SUB_TIME (timeout, end_time, timeout);
- if (EMACS_TIME_NEG_P (timeout))
- break;
- }
- else
- {
- EMACS_SET_SECS_USECS (timeout, 100000, 0);
- }
-
- /* If our caller will not immediately handle keyboard events,
- run timer events directly.
- (Callers that will immediately read keyboard events
- call timer_delay on their own.) */
- if (NILP (wait_for_cell))
- {
- EMACS_TIME timer_delay;
-
- do
- {
- int old_timers_run = timers_run;
- timer_delay = timer_check (1);
- if (timers_run != old_timers_run && do_display)
- /* We must retry, since a timer may have requeued itself
- and that could alter the time delay. */
- redisplay_preserve_echo_area (14);
- else
- break;
- }
- while (!detect_input_pending ());
-
- /* If there is unread keyboard input, also return. */
- if (read_kbd != 0
- && requeued_events_pending_p ())
- break;
-
- if (! EMACS_TIME_NEG_P (timer_delay) && time_limit != -1)
- {
- EMACS_TIME difference;
- EMACS_SUB_TIME (difference, timer_delay, timeout);
- if (EMACS_TIME_NEG_P (difference))
- {
- timeout = timer_delay;
- timeout_reduced_for_timers = 1;
- }
- }
- }
-
- /* Cause C-g and alarm signals to take immediate action,
- and cause input available signals to zero out timeout. */
- if (read_kbd < 0)
- set_waiting_for_input (&timeout);