X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/322b7dab59b98b5d8625d2cd29e48f1ce605f769..011ba6eaacfa50cc9871d0cfea34e8f0a7a5bc43:/src/process.c diff --git a/src/process.c b/src/process.c index 6bd168d884..a808832214 100644 --- a/src/process.c +++ b/src/process.c @@ -58,6 +58,17 @@ along with GNU Emacs. If not, see . */ #include #endif /* HAVE_NET_IF_H */ +#if defined(HAVE_IFADDRS_H) +/* Must be after net/if.h */ +#include + +/* We only use structs from this header when we use getifaddrs. */ +#if defined(HAVE_NET_IF_DL_H) +#include +#endif + +#endif + #ifdef NEED_BSDTTY #include #endif @@ -245,7 +256,7 @@ static void create_pty (Lisp_Object); /* 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 @@ -1632,7 +1643,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object 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 */ @@ -1652,7 +1662,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) 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); @@ -1667,6 +1677,10 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) 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; { @@ -1808,7 +1822,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) 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); @@ -1900,7 +1914,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) #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) @@ -3557,46 +3571,53 @@ format; see the description of ADDRESS in `make-network-process'. */) (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), @@ -3605,6 +3626,7 @@ format; see the description of ADDRESS in `make-network-process'. */) res); } + xfree (buf); return res; } #endif /* SIOCGIFCONF */ @@ -3642,8 +3664,13 @@ static const struct ifflag_def ifflag_table[] = { { 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 @@ -3696,6 +3723,10 @@ FLAGS is the current flags of the interface. */) 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); @@ -3714,6 +3745,12 @@ FLAGS is the current flags of the interface. */) 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++) { @@ -3747,7 +3784,38 @@ FLAGS is the current flags of the interface. */) 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; @@ -5093,6 +5161,9 @@ read_process_output (Lisp_Object proc, register int channel) 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))),