-#define ADD_SUBFEATURE(key, val) \
- subfeatures = Fcons (Fcons (key, Fcons (val, Qnil)), subfeatures)
-
-#ifdef NON_BLOCKING_CONNECT
- ADD_SUBFEATURE (QCnowait, Qt);
-#endif
-#ifdef DATAGRAM_SOCKETS
- ADD_SUBFEATURE (QCtype, Qdatagram);
-#endif
-#ifdef HAVE_LOCAL_SOCKETS
- ADD_SUBFEATURE (QCfamily, Qlocal);
-#endif
- ADD_SUBFEATURE (QCfamily, Qipv4);
-#ifdef AF_INET6
- ADD_SUBFEATURE (QCfamily, Qipv6);
-#endif
-#ifdef HAVE_GETSOCKNAME
- ADD_SUBFEATURE (QCservice, Qt);
-#endif
-#if defined(O_NONBLOCK) || defined(O_NDELAY)
- ADD_SUBFEATURE (QCserver, Qt);
-#endif
-
- for (sopt = socket_options; sopt->name; sopt++)
- subfeatures = Fcons (intern (sopt->name), subfeatures);
-
- Fprovide (intern ("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 ("processp");
- staticpro (&Qprocessp);
- Qrun = intern ("run");
- staticpro (&Qrun);
- Qstop = intern ("stop");
- staticpro (&Qstop);
- Qsignal = intern ("signal");
- staticpro (&Qsignal);
-
- /* Qexit is already staticpro'd by syms_of_eval; don't staticpro it
- here again.
-
- Qexit = intern ("exit");
- staticpro (&Qexit); */
-
- Qopen = intern ("open");
- staticpro (&Qopen);
- Qclosed = intern ("closed");
- staticpro (&Qclosed);
- Qconnect = intern ("connect");
- staticpro (&Qconnect);
- Qfailed = intern ("failed");
- staticpro (&Qfailed);
- Qlisten = intern ("listen");
- staticpro (&Qlisten);
- Qlocal = intern ("local");
- staticpro (&Qlocal);
- Qipv4 = intern ("ipv4");
- staticpro (&Qipv4);
-#ifdef AF_INET6
- Qipv6 = intern ("ipv6");
- staticpro (&Qipv6);
-#endif
- Qdatagram = intern ("datagram");
- staticpro (&Qdatagram);
-
- QCport = intern (":port");
- staticpro (&QCport);
- QCspeed = intern (":speed");
- staticpro (&QCspeed);
- QCprocess = intern (":process");
- staticpro (&QCprocess);
-
- QCbytesize = intern (":bytesize");
- staticpro (&QCbytesize);
- QCstopbits = intern (":stopbits");
- staticpro (&QCstopbits);
- QCparity = intern (":parity");
- staticpro (&QCparity);
- Qodd = intern ("odd");
- staticpro (&Qodd);
- Qeven = intern ("even");
- staticpro (&Qeven);
- QCflowcontrol = intern (":flowcontrol");
- staticpro (&QCflowcontrol);
- Qhw = intern ("hw");
- staticpro (&Qhw);
- Qsw = intern ("sw");
- staticpro (&Qsw);
- QCsummary = intern (":summary");
- staticpro (&QCsummary);
-
- Qreal = intern ("real");
- staticpro (&Qreal);
- Qnetwork = intern ("network");
- staticpro (&Qnetwork);
- Qserial = intern ("serial");
- staticpro (&Qserial);
-
- QCname = intern (":name");
- staticpro (&QCname);
- QCbuffer = intern (":buffer");
- staticpro (&QCbuffer);
- QChost = intern (":host");
- staticpro (&QChost);
- QCservice = intern (":service");
- staticpro (&QCservice);
- QCtype = intern (":type");
- staticpro (&QCtype);
- QClocal = intern (":local");
- staticpro (&QClocal);
- QCremote = intern (":remote");
- staticpro (&QCremote);
- QCcoding = intern (":coding");
- staticpro (&QCcoding);
- QCserver = intern (":server");
- staticpro (&QCserver);
- QCnowait = intern (":nowait");
- staticpro (&QCnowait);
- QCsentinel = intern (":sentinel");
- staticpro (&QCsentinel);
- QClog = intern (":log");
- staticpro (&QClog);
- QCnoquery = intern (":noquery");
- staticpro (&QCnoquery);
- QCstop = intern (":stop");
- staticpro (&QCstop);
- QCoptions = intern (":options");
- staticpro (&QCoptions);
- QCplist = intern (":plist");
- staticpro (&QCplist);
-
- Qlast_nonmenu_event = intern ("last-nonmenu-event");
- staticpro (&Qlast_nonmenu_event);
-
- staticpro (&Vprocess_alist);
-#ifdef SIGCHLD
- staticpro (&deleted_pid_list);
-#endif
-
- Qeuid = intern ("euid");
- staticpro (&Qeuid);
- Qegid = intern ("egid");
- staticpro (&Qegid);
- Quser = intern ("user");
- staticpro (&Quser);
- Qgroup = intern ("group");
- staticpro (&Qgroup);
- Qcomm = intern ("comm");
- staticpro (&Qcomm);
- Qstate = intern ("state");
- staticpro (&Qstate);
- Qppid = intern ("ppid");
- staticpro (&Qppid);
- Qpgrp = intern ("pgrp");
- staticpro (&Qpgrp);
- Qsess = intern ("sess");
- staticpro (&Qsess);
- Qttname = intern ("ttname");
- staticpro (&Qttname);
- Qtpgid = intern ("tpgid");
- staticpro (&Qtpgid);
- Qminflt = intern ("minflt");
- staticpro (&Qminflt);
- Qmajflt = intern ("majflt");
- staticpro (&Qmajflt);
- Qcminflt = intern ("cminflt");
- staticpro (&Qcminflt);
- Qcmajflt = intern ("cmajflt");
- staticpro (&Qcmajflt);
- Qutime = intern ("utime");
- staticpro (&Qutime);
- Qstime = intern ("stime");
- staticpro (&Qstime);
- Qtime = intern ("time");
- staticpro (&Qtime);
- Qcutime = intern ("cutime");
- staticpro (&Qcutime);
- Qcstime = intern ("cstime");
- staticpro (&Qcstime);
- Qctime = intern ("ctime");
- staticpro (&Qctime);
- Qpri = intern ("pri");
- staticpro (&Qpri);
- Qnice = intern ("nice");
- staticpro (&Qnice);
- Qthcount = intern ("thcount");
- staticpro (&Qthcount);
- Qstart = intern ("start");
- staticpro (&Qstart);
- Qvsize = intern ("vsize");
- staticpro (&Qvsize);
- Qrss = intern ("rss");
- staticpro (&Qrss);
- Qetime = intern ("etime");
- staticpro (&Qetime);
- Qpcpu = intern ("pcpu");
- staticpro (&Qpcpu);
- Qpmem = intern ("pmem");
- staticpro (&Qpmem);
- Qargs = intern ("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>
-#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 ());