#endif
#include <sys/ioctl.h>
-#if defined(HAVE_NET_IF_H)
+#if defined (HAVE_NET_IF_H)
#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
/* 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. */
-#if defined(HAVE_WINDOW_SYSTEM) && !defined(USE_ASYNC_EVENTS)
+#if defined (HAVE_WINDOW_SYSTEM) && !defined (USE_ASYNC_EVENTS)
#define POLL_FOR_INPUT
#endif
{
register Lisp_Object val, tem, name1;
register struct Lisp_Process *p;
- char suffix[10];
- register int i;
+ char suffix[sizeof "<>" + INT_STRLEN_BOUND (printmax_t)];
+ printmax_t i;
p = allocate_process ();
p->gnutls_initstage = GNUTLS_STAGE_EMPTY;
p->gnutls_log_level = 0;
p->gnutls_p = 0;
+ p->gnutls_state = NULL;
+ p->gnutls_x509_cred = NULL;
+ p->gnutls_anon_cred = NULL;
#endif
/* If name is already in use, modify it until it is unused. */
{
tem = Fget_process (name1);
if (NILP (tem)) break;
- sprintf (suffix, "<%d>", i);
+ sprintf (suffix, "<%"pMd">", i);
name1 = concat2 (name, build_string (suffix));
}
name = name1;
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 */
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;
{
{
/* Don't support network sockets when non-blocking mode is
not available, since a blocked Emacs is not useful. */
-#if !defined(O_NONBLOCK) && !defined(O_NDELAY)
+#if !defined (O_NONBLOCK) && !defined (O_NDELAY)
error ("Network servers not supported");
#else
is_server = 1;
tem = Fplist_get (contact, QCfamily);
if (NILP (tem))
{
-#if defined(HAVE_GETADDRINFO) && defined(AF_INET6)
+#if defined (HAVE_GETADDRINFO) && defined (AF_INET6)
family = AF_UNSPEC;
#else
family = AF_INET;
}
\f
-#if defined(HAVE_NET_IF_H)
+#if defined (HAVE_NET_IF_H)
#ifdef SIOCGIFCONF
DEFUN ("network-interface-list", Fnetwork_interface_list, Snetwork_interface_list, 0, 0, 0,
(void)
{
struct ifconf ifconf;
- struct ifreq *ifreqs = NULL;
- ptrdiff_t 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:
- ifreqs = xpalloc (ifreqs, &ifaces, 25,
- INT_MAX / sizeof *ifreqs, sizeof *ifreqs);
- buf_size = ifaces * sizeof (ifreqs[0]);
- ifconf.ifc_len = buf_size;
- ifconf.ifc_req = ifreqs;
- if (ioctl (s, SIOCGIFCONF, &ifconf))
+ do
{
- 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 */
-#if defined(SIOCGIFADDR) || defined(SIOCGIFHWADDR) || defined(SIOCGIFFLAGS)
+#if defined (SIOCGIFADDR) || defined (SIOCGIFHWADDR) || defined (SIOCGIFFLAGS)
struct ifflag_def {
int flag_bit;
{ 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);
return Qnil;
elt = Qnil;
-#if defined(SIOCGIFFLAGS) && defined(HAVE_STRUCT_IFREQ_IFR_FLAGS)
+#if defined (SIOCGIFFLAGS) && defined (HAVE_STRUCT_IFREQ_IFR_FLAGS)
if (ioctl (s, SIOCGIFFLAGS, &rq) == 0)
{
int flags = rq.ifr_flags;
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++)
{
res = Fcons (elt, res);
elt = Qnil;
-#if defined(SIOCGIFHWADDR) && defined(HAVE_STRUCT_IFREQ_IFR_HWADDR)
+#if defined (SIOCGIFHWADDR) && defined (HAVE_STRUCT_IFREQ_IFR_HWADDR)
if (ioctl (s, SIOCGIFHWADDR, &rq) == 0)
{
Lisp_Object hwaddr = Fmake_vector (make_number (6), Qnil);
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;
-#if defined(SIOCGIFNETMASK) && (defined(HAVE_STRUCT_IFREQ_IFR_NETMASK) || defined(HAVE_STRUCT_IFREQ_IFR_ADDR))
+#if defined (SIOCGIFNETMASK) && (defined (HAVE_STRUCT_IFREQ_IFR_NETMASK) || defined (HAVE_STRUCT_IFREQ_IFR_ADDR))
if (ioctl (s, SIOCGIFNETMASK, &rq) == 0)
{
any = 1;
res = Fcons (elt, res);
elt = Qnil;
-#if defined(SIOCGIFBRDADDR) && defined(HAVE_STRUCT_IFREQ_IFR_BROADADDR)
+#if defined (SIOCGIFBRDADDR) && defined (HAVE_STRUCT_IFREQ_IFR_BROADADDR)
if (ioctl (s, SIOCGIFBRDADDR, &rq) == 0)
{
any = 1;
res = Fcons (elt, res);
elt = Qnil;
-#if defined(SIOCGIFADDR) && defined(HAVE_STRUCT_IFREQ_IFR_ADDR)
+#if defined (SIOCGIFADDR) && defined (HAVE_STRUCT_IFREQ_IFR_ADDR)
if (ioctl (s, SIOCGIFADDR, &rq) == 0)
{
any = 1;
return any ? res : Qnil;
}
#endif
-#endif /* defined(HAVE_NET_IF_H) */
+#endif /* defined (HAVE_NET_IF_H) */
/* Turn off input and output for process PROC. */
register int inchannel, outchannel;
register struct Lisp_Process *p = XPROCESS (proc);
+#ifdef HAVE_GNUTLS
+ /* Delete GnuTLS structures in PROC, if any. */
+ emacs_gnutls_deinit (proc);
+#endif /* HAVE_GNUTLS */
+
inchannel = p->infd;
outchannel = p->outfd;
It can't hurt. */
else if (nread == -1 && errno == EIO)
{
- /* Clear the descriptor now, so we only raise the
- signal once. Don't do this if `process' is only
- a pty. */
- if (XPROCESS (proc)->pid != -2)
- {
- FD_CLR (channel, &input_wait_mask);
- FD_CLR (channel, &non_keyboard_wait_mask);
+ /* Clear the descriptor now, so we only raise the signal once. */
+ FD_CLR (channel, &input_wait_mask);
+ FD_CLR (channel, &non_keyboard_wait_mask);
- kill (getpid (), SIGCHLD);
- }
+ kill (getpid (), SIGCHLD);
}
#endif /* HAVE_PTYS */
/* If we can detect process termination, don't consider the process
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_GETSOCKNAME
ADD_SUBFEATURE (QCservice, Qt);
#endif
-#if defined(O_NONBLOCK) || defined(O_NDELAY)
+#if defined (O_NONBLOCK) || defined (O_NDELAY)
ADD_SUBFEATURE (QCserver, Qt);
#endif
defsubr (&Sset_network_process_option);
defsubr (&Smake_network_process);
defsubr (&Sformat_network_address);
-#if defined(HAVE_NET_IF_H)
+#if defined (HAVE_NET_IF_H)
#ifdef SIOCGIFCONF
defsubr (&Snetwork_interface_list);
#endif
-#if defined(SIOCGIFADDR) || defined(SIOCGIFHWADDR) || defined(SIOCGIFFLAGS)
+#if defined (SIOCGIFADDR) || defined (SIOCGIFHWADDR) || defined (SIOCGIFFLAGS)
defsubr (&Snetwork_interface_info);
#endif
-#endif /* defined(HAVE_NET_IF_H) */
+#endif /* defined (HAVE_NET_IF_H) */
#ifdef DATAGRAM_SOCKETS
defsubr (&Sprocess_datagram_address);
defsubr (&Sset_process_datagram_address);