#include <unistd.h>
#include <fcntl.h>
+#include "lisp.h"
+
/* Only MS-DOS does not define `subprocesses'. */
#ifdef subprocesses
#include <net/if.h>
#endif /* HAVE_NET_IF_H */
+#if defined(HAVE_IFADDRS_H)
+/* Must be after net/if.h */
+#include <ifaddrs.h>
+
+/* We only use structs from this header when we use getifaddrs. */
+#if defined(HAVE_NET_IF_DL_H)
+#include <net/if_dl.h>
+#endif
+
+#endif
+
#ifdef NEED_BSDTTY
#include <bsdtty.h>
#endif
#endif /* subprocesses */
-#include "lisp.h"
#include "systime.h"
#include "systty.h"
#include "gnutls.h"
#endif
-#if defined (USE_GTK) || defined (HAVE_GCONF)
+#if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS)
#include "xgselect.h"
-#endif /* defined (USE_GTK) || defined (HAVE_GCONF) */
+#endif
#ifdef HAVE_NS
#include "nsterm.h"
#endif
/* If we support a window system, turn on the code to poll periodically
to detect C-g. It isn't actually used when doing interrupt input. */
-#ifdef HAVE_WINDOW_SYSTEM
+#if defined(HAVE_WINDOW_SYSTEM) && !defined(USE_ASYNC_EVENTS)
#define POLL_FOR_INPUT
#endif
DEFUN ("set-process-buffer", Fset_process_buffer, Sset_process_buffer,
2, 2, 0,
- doc: /* Set buffer associated with PROCESS to BUFFER (a buffer, or nil). */)
+ doc: /* Set buffer associated with PROCESS to BUFFER (a buffer, or nil).
+Return BUFFER. */)
(register Lisp_Object process, Lisp_Object buffer)
{
struct Lisp_Process *p;
if (VECTORP (address)) /* AF_INET or AF_INET6 */
{
register struct Lisp_Vector *p = XVECTOR (address);
- EMACS_UINT size = p->header.size;
+ EMACS_INT size = p->header.size;
Lisp_Object args[10];
int nargs, i;
syntax.
usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
- (size_t nargs, register Lisp_Object *args)
+ (ptrdiff_t nargs, Lisp_Object *args)
{
Lisp_Object buffer, name, program, proc, current_dir, tem;
register unsigned char **new_argv;
- register size_t i;
+ ptrdiff_t i;
int count = SPECPDL_INDEX ();
buffer = args[1];
{
if (EQ (coding_systems, Qt))
{
- args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof args2);
+ args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2);
args2[0] = Qstart_process;
for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
GCPRO2 (proc, current_dir);
XPROCESS (process)->pty_flag = pty_flag;
XPROCESS (process)->status = Qrun;
- setup_process_coding_systems (process);
/* Delay interrupts until we have a chance to store
the new fork's pid in its process structure */
sigaddset (&blocked, SIGHUP ); sigaction (SIGHUP , 0, &sighup_action );
#endif
#endif /* HAVE_WORKING_VFORK */
- sigprocmask (SIG_BLOCK, &blocked, &procmask);
+ pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
FD_SET (inchannel, &input_wait_mask);
FD_SET (inchannel, &non_keyboard_wait_mask);
processes to get their return values scrambled. */
XPROCESS (process)->pid = -1;
+ /* This must be called after the above line because it may signal an
+ error. */
+ setup_process_coding_systems (process);
+
BLOCK_INPUT;
{
signal (SIGPIPE, SIG_DFL);
/* Stop blocking signals in the child. */
- sigprocmask (SIG_SETMASK, &procmask, 0);
+ pthread_sigmask (SIG_SETMASK, &procmask, 0);
if (pty_flag)
child_setup_tty (xforkout);
#endif
#endif /* HAVE_WORKING_VFORK */
/* Stop blocking signals in the parent. */
- sigprocmask (SIG_SETMASK, &procmask, 0);
+ pthread_sigmask (SIG_SETMASK, &procmask, 0);
/* Now generate the error if vfork failed. */
if (pid < 0)
\(serial-process-configure :port "\\\\.\\COM13" :bytesize 7)
usage: (serial-process-configure &rest ARGS) */)
- (size_t nargs, Lisp_Object *args)
+ (ptrdiff_t nargs, Lisp_Object *args)
{
struct Lisp_Process *p;
Lisp_Object contact = Qnil;
\(make-serial-process :port "/dev/tty.BlueConsole-SPP-1" :speed nil)
usage: (make-serial-process &rest ARGS) */)
- (size_t nargs, Lisp_Object *args)
+ (ptrdiff_t nargs, Lisp_Object *args)
{
int fd = -1;
Lisp_Object proc, contact, port;
information, is available via the `process-contact' function.
usage: (make-network-process &rest ARGS) */)
- (size_t nargs, Lisp_Object *args)
+ (ptrdiff_t nargs, Lisp_Object *args)
{
Lisp_Object proc;
Lisp_Object contact;
for (lres = res; lres; lres = lres->ai_next)
{
- size_t optn;
+ ptrdiff_t optn;
int optbits;
#ifdef WINDOWSNT
(void)
{
struct ifconf ifconf;
- struct ifreq *ifreqs = NULL;
- int ifaces = 0;
- int buf_size, s;
+ struct ifreq *ifreq;
+ void *buf = NULL;
+ ptrdiff_t buf_size = 512;
+ int s, i;
Lisp_Object res;
s = socket (AF_INET, SOCK_STREAM, 0);
if (s < 0)
return Qnil;
- again:
- ifaces += 25;
- buf_size = ifaces * sizeof (ifreqs[0]);
- ifreqs = (struct ifreq *)xrealloc(ifreqs, buf_size);
- if (!ifreqs)
+ do
{
- close (s);
- return Qnil;
- }
-
- ifconf.ifc_len = buf_size;
- ifconf.ifc_req = ifreqs;
- if (ioctl (s, SIOCGIFCONF, &ifconf))
- {
- close (s);
- return Qnil;
+ buf = xpalloc (buf, &buf_size, 1, INT_MAX, 1);
+ ifconf.ifc_buf = buf;
+ ifconf.ifc_len = buf_size;
+ if (ioctl (s, SIOCGIFCONF, &ifconf))
+ {
+ close (s);
+ xfree (buf);
+ return Qnil;
+ }
}
-
- if (ifconf.ifc_len == buf_size)
- goto again;
+ while (ifconf.ifc_len == buf_size);
close (s);
- ifaces = ifconf.ifc_len / sizeof (ifreqs[0]);
res = Qnil;
- while (--ifaces >= 0)
+ ifreq = ifconf.ifc_req;
+ while ((char *) ifreq < (char *) ifconf.ifc_req + ifconf.ifc_len)
{
- struct ifreq *ifq = &ifreqs[ifaces];
+ struct ifreq *ifq = ifreq;
+#ifdef HAVE_STRUCT_IFREQ_IFR_ADDR_SA_LEN
+#define SIZEOF_IFREQ(sif) \
+ ((sif)->ifr_addr.sa_len < sizeof (struct sockaddr) \
+ ? sizeof (*(sif)) : sizeof ((sif)->ifr_name) + (sif)->ifr_addr.sa_len)
+
+ int len = SIZEOF_IFREQ (ifq);
+#else
+ int len = sizeof (*ifreq);
+#endif
char namebuf[sizeof (ifq->ifr_name) + 1];
+ i += len;
+ ifreq = (struct ifreq *) ((char *) ifreq + len);
+
if (ifq->ifr_addr.sa_family != AF_INET)
continue;
+
memcpy (namebuf, ifq->ifr_name, sizeof (ifq->ifr_name));
namebuf[sizeof (ifq->ifr_name)] = 0;
res = Fcons (Fcons (build_string (namebuf),
res);
}
+ xfree (buf);
return res;
}
#endif /* SIOCGIFCONF */
{ IFF_PROMISC, "promisc" },
#endif
#ifdef IFF_NOTRAILERS
+#ifdef NS_IMPL_COCOA
+ /* Really means smart, notrailers is obsolete */
+ { IFF_NOTRAILERS, "smart" },
+#else
{ IFF_NOTRAILERS, "notrailers" },
#endif
+#endif
#ifdef IFF_ALLMULTI
{ IFF_ALLMULTI, "allmulti" },
#endif
Lisp_Object elt;
int s;
int any = 0;
+#if (! (defined SIOCGIFHWADDR && defined HAVE_STRUCT_IFREQ_IFR_HWADDR) \
+ && defined HAVE_GETIFADDRS && defined LLADDR)
+ struct ifaddrs *ifap;
+#endif
CHECK_STRING (ifname);
const struct ifflag_def *fp;
int fnum;
+ /* If flags is smaller than int (i.e. short) it may have the high bit set
+ due to IFF_MULTICAST. In that case, sign extending it into
+ an int is wrong. */
+ if (flags < 0 && sizeof (rq.ifr_flags) < sizeof (flags))
+ flags = (unsigned short) rq.ifr_flags;
+
any = 1;
for (fp = ifflag_table; flags != 0 && fp->flag_sym; fp++)
{
p->contents[n] = make_number (((unsigned char *)&rq.ifr_hwaddr.sa_data[0])[n]);
elt = Fcons (make_number (rq.ifr_hwaddr.sa_family), hwaddr);
}
+#elif defined(HAVE_GETIFADDRS) && defined(LLADDR)
+ if (getifaddrs (&ifap) != -1)
+ {
+ Lisp_Object hwaddr = Fmake_vector (make_number (6), Qnil);
+ register struct Lisp_Vector *p = XVECTOR (hwaddr);
+ struct ifaddrs *it;
+
+ for (it = ifap; it != NULL; it = it->ifa_next)
+ {
+ struct sockaddr_dl *sdl = (struct sockaddr_dl*) it->ifa_addr;
+ unsigned char linkaddr[6];
+ int n;
+
+ if (it->ifa_addr->sa_family != AF_LINK
+ || strcmp (it->ifa_name, SSDATA (ifname)) != 0
+ || sdl->sdl_alen != 6)
+ continue;
+
+ memcpy (linkaddr, LLADDR(sdl), sdl->sdl_alen);
+ for (n = 0; n < 6; n++)
+ p->contents[n] = make_number (linkaddr[n]);
+
+ elt = Fcons (make_number (it->ifa_addr->sa_family), hwaddr);
+ break;
+ }
+ }
+#ifdef HAVE_FREEIFADDRS
+ freeifaddrs (ifap);
#endif
+
+#endif /* HAVE_GETIFADDRS && LLADDR */
+
res = Fcons (elt, res);
elt = Qnil;
impossible to step through wait_reading_process_output. */
#ifndef select
-static INLINE int
+static inline int
select_wrapper (int n, fd_set *rfd, fd_set *wfd, fd_set *xfd, struct timeval *tmo)
{
return select (n, rfd, wfd, xfd, tmo);
set_waiting_for_input (&timeout);
}
+ /* Skip the `select' call if input is available and we're
+ waiting for keyboard input or a cell change (which can be
+ triggered by processing X events). In the latter case, set
+ nfds to 1 to avoid breaking the loop. */
no_avail = 0;
- if (read_kbd && detect_input_pending ())
+ if ((read_kbd || !NILP (wait_for_cell))
+ && detect_input_pending ())
{
- nfds = 0;
+ nfds = read_kbd ? 0 : 1;
no_avail = 1;
}
- else
+
+ if (!no_avail)
{
#ifdef ADAPTIVE_READ_BUFFERING
process_output_skip = 0;
}
#endif
-#if defined (USE_GTK) || defined (HAVE_GCONF)
+#if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS)
nfds = xg_select
#elif defined (HAVE_NS)
nfds = ns_select
if (nfds == 0 &&
wait_proc && wait_proc->gnutls_p /* Check for valid process. */
/* Do we have pending data? */
- && gnutls_record_check_pending (wait_proc->gnutls_state) > 0)
+ && emacs_gnutls_record_check_pending (wait_proc->gnutls_state) > 0)
{
nfds = 1;
/* Set to Available. */
}
#ifdef HAVE_GNUTLS
if (XPROCESS (proc)->gnutls_p)
- nbytes = emacs_gnutls_read (channel, XPROCESS (proc),
+ nbytes = emacs_gnutls_read (XPROCESS (proc),
chars + carryover + buffered,
readmax - buffered);
else
p->decoding_carryover = coding->carryover_bytes;
}
if (SBYTES (text) > 0)
+ /* FIXME: It's wrong to wrap or not based on debug-on-error, and
+ sometimes it's simply wrong to wrap (e.g. when called from
+ accept-process-output). */
internal_condition_case_1 (read_process_output_call,
Fcons (outstream,
Fcons (proc, Fcons (text, Qnil))),
{
#ifdef HAVE_GNUTLS
if (XPROCESS (proc)->gnutls_p)
- written = emacs_gnutls_write (outfd,
- XPROCESS (proc),
- buf, this);
+ written = emacs_gnutls_write (XPROCESS (proc),
+ buf, this);
else
#endif
written = emacs_write (outfd, buf, this);
\f
+# ifdef HAVE_GPM
+
void
add_gpm_wait_descriptor (int desc)
{
delete_keyboard_wait_descriptor (desc);
}
+# endif
+
# ifdef SIGIO
/* Return nonzero if *MASK has a bit set
{
#ifdef subprocesses
- 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);
+ DEFSYM (Qprocessp, "processp");
+ DEFSYM (Qrun, "run");
+ DEFSYM (Qstop, "stop");
+ DEFSYM (Qsignal, "signal");
/* 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);
+ DEFSYM (Qopen, "open");
+ DEFSYM (Qclosed, "closed");
+ DEFSYM (Qconnect, "connect");
+ DEFSYM (Qfailed, "failed");
+ DEFSYM (Qlisten, "listen");
+ DEFSYM (Qlocal, "local");
+ DEFSYM (Qipv4, "ipv4");
#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);
- QCbuffer = intern_c_string (":buffer");
- staticpro (&QCbuffer);
- QChost = intern_c_string (":host");
- staticpro (&QChost);
- QCservice = intern_c_string (":service");
- staticpro (&QCservice);
- 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);
+ DEFSYM (Qipv6, "ipv6");
+#endif
+ DEFSYM (Qdatagram, "datagram");
+ DEFSYM (Qseqpacket, "seqpacket");
+
+ DEFSYM (QCport, ":port");
+ DEFSYM (QCspeed, ":speed");
+ DEFSYM (QCprocess, ":process");
+
+ DEFSYM (QCbytesize, ":bytesize");
+ DEFSYM (QCstopbits, ":stopbits");
+ DEFSYM (QCparity, ":parity");
+ DEFSYM (Qodd, "odd");
+ DEFSYM (Qeven, "even");
+ DEFSYM (QCflowcontrol, ":flowcontrol");
+ DEFSYM (Qhw, "hw");
+ DEFSYM (Qsw, "sw");
+ DEFSYM (QCsummary, ":summary");
+
+ DEFSYM (Qreal, "real");
+ DEFSYM (Qnetwork, "network");
+ DEFSYM (Qserial, "serial");
+ DEFSYM (QCbuffer, ":buffer");
+ DEFSYM (QChost, ":host");
+ DEFSYM (QCservice, ":service");
+ DEFSYM (QClocal, ":local");
+ DEFSYM (QCremote, ":remote");
+ DEFSYM (QCcoding, ":coding");
+ DEFSYM (QCserver, ":server");
+ DEFSYM (QCnowait, ":nowait");
+ DEFSYM (QCsentinel, ":sentinel");
+ DEFSYM (QClog, ":log");
+ DEFSYM (QCnoquery, ":noquery");
+ DEFSYM (QCstop, ":stop");
+ DEFSYM (QCoptions, ":options");
+ DEFSYM (QCplist, ":plist");
+
+ DEFSYM (Qlast_nonmenu_event, "last-nonmenu-event");
staticpro (&Vprocess_alist);
#ifdef SIGCHLD
#endif /* subprocesses */
- QCname = intern_c_string (":name");
- staticpro (&QCname);
- QCtype = intern_c_string (":type");
- staticpro (&QCtype);
-
- 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);
+ DEFSYM (QCname, ":name");
+ DEFSYM (QCtype, ":type");
+
+ DEFSYM (Qeuid, "euid");
+ DEFSYM (Qegid, "egid");
+ DEFSYM (Quser, "user");
+ DEFSYM (Qgroup, "group");
+ DEFSYM (Qcomm, "comm");
+ DEFSYM (Qstate, "state");
+ DEFSYM (Qppid, "ppid");
+ DEFSYM (Qpgrp, "pgrp");
+ DEFSYM (Qsess, "sess");
+ DEFSYM (Qttname, "ttname");
+ DEFSYM (Qtpgid, "tpgid");
+ DEFSYM (Qminflt, "minflt");
+ DEFSYM (Qmajflt, "majflt");
+ DEFSYM (Qcminflt, "cminflt");
+ DEFSYM (Qcmajflt, "cmajflt");
+ DEFSYM (Qutime, "utime");
+ DEFSYM (Qstime, "stime");
+ DEFSYM (Qtime, "time");
+ DEFSYM (Qcutime, "cutime");
+ DEFSYM (Qcstime, "cstime");
+ DEFSYM (Qctime, "ctime");
+ DEFSYM (Qpri, "pri");
+ DEFSYM (Qnice, "nice");
+ DEFSYM (Qthcount, "thcount");
+ DEFSYM (Qstart, "start");
+ DEFSYM (Qvsize, "vsize");
+ DEFSYM (Qrss, "rss");
+ DEFSYM (Qetime, "etime");
+ DEFSYM (Qpcpu, "pcpu");
+ DEFSYM (Qpmem, "pmem");
+ DEFSYM (Qargs, "args");
DEFVAR_BOOL ("delete-exited-processes", delete_exited_processes,
doc: /* *Non-nil means delete processes immediately when they exit.