diff options
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 94 |
1 files changed, 82 insertions, 12 deletions
diff --git a/src/process.c b/src/process.c index 236c27e5c3a..b3c295cecde 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -58,6 +58,17 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 58 | #include <net/if.h> | 58 | #include <net/if.h> |
| 59 | #endif /* HAVE_NET_IF_H */ | 59 | #endif /* HAVE_NET_IF_H */ |
| 60 | 60 | ||
| 61 | #if defined(HAVE_IFADDRS_H) | ||
| 62 | /* Must be after net/if.h */ | ||
| 63 | #include <ifaddrs.h> | ||
| 64 | |||
| 65 | /* We only use structs from this header when we use getifaddrs. */ | ||
| 66 | #if defined(HAVE_NET_IF_DL_H) | ||
| 67 | #include <net/if_dl.h> | ||
| 68 | #endif | ||
| 69 | |||
| 70 | #endif | ||
| 71 | |||
| 61 | #ifdef NEED_BSDTTY | 72 | #ifdef NEED_BSDTTY |
| 62 | #include <bsdtty.h> | 73 | #include <bsdtty.h> |
| 63 | #endif | 74 | #endif |
| @@ -3557,9 +3568,9 @@ format; see the description of ADDRESS in `make-network-process'. */) | |||
| 3557 | (void) | 3568 | (void) |
| 3558 | { | 3569 | { |
| 3559 | struct ifconf ifconf; | 3570 | struct ifconf ifconf; |
| 3560 | struct ifreq *ifreqs = NULL; | 3571 | struct ifreq *ifreq; |
| 3561 | int ifaces = 0; | 3572 | void *buf = NULL; |
| 3562 | int buf_size, s; | 3573 | int buf_size = 512, s, i; |
| 3563 | Lisp_Object res; | 3574 | Lisp_Object res; |
| 3564 | 3575 | ||
| 3565 | s = socket (AF_INET, SOCK_STREAM, 0); | 3576 | s = socket (AF_INET, SOCK_STREAM, 0); |
| @@ -3567,20 +3578,19 @@ format; see the description of ADDRESS in `make-network-process'. */) | |||
| 3567 | return Qnil; | 3578 | return Qnil; |
| 3568 | 3579 | ||
| 3569 | again: | 3580 | again: |
| 3570 | ifaces += 25; | 3581 | buf_size *= 2; |
| 3571 | buf_size = ifaces * sizeof (ifreqs[0]); | 3582 | buf = xrealloc(buf, buf_size); |
| 3572 | ifreqs = (struct ifreq *)xrealloc(ifreqs, buf_size); | 3583 | if (!buf) |
| 3573 | if (!ifreqs) | ||
| 3574 | { | 3584 | { |
| 3575 | close (s); | 3585 | close (s); |
| 3576 | return Qnil; | 3586 | return Qnil; |
| 3577 | } | 3587 | } |
| 3578 | 3588 | ||
| 3579 | ifconf.ifc_len = buf_size; | 3589 | ifconf.ifc_buf = buf; |
| 3580 | ifconf.ifc_req = ifreqs; | ||
| 3581 | if (ioctl (s, SIOCGIFCONF, &ifconf)) | 3590 | if (ioctl (s, SIOCGIFCONF, &ifconf)) |
| 3582 | { | 3591 | { |
| 3583 | close (s); | 3592 | close (s); |
| 3593 | xfree (buf); | ||
| 3584 | return Qnil; | 3594 | return Qnil; |
| 3585 | } | 3595 | } |
| 3586 | 3596 | ||
| @@ -3588,15 +3598,29 @@ format; see the description of ADDRESS in `make-network-process'. */) | |||
| 3588 | goto again; | 3598 | goto again; |
| 3589 | 3599 | ||
| 3590 | close (s); | 3600 | close (s); |
| 3591 | ifaces = ifconf.ifc_len / sizeof (ifreqs[0]); | ||
| 3592 | 3601 | ||
| 3593 | res = Qnil; | 3602 | res = Qnil; |
| 3594 | while (--ifaces >= 0) | 3603 | for (ifreq = ifconf.ifc_req; |
| 3604 | (char *) ifreq < (char *) (ifconf.ifc_req) + ifconf.ifc_len; | ||
| 3605 | ) | ||
| 3595 | { | 3606 | { |
| 3596 | struct ifreq *ifq = &ifreqs[ifaces]; | 3607 | struct ifreq *ifq = ifreq; |
| 3608 | #ifdef HAVE_STRUCT_IFREQ_IFR_ADDR_SA_LEN | ||
| 3609 | #define SIZEOF_IFREQ(sif) \ | ||
| 3610 | ((sif)->ifr_addr.sa_len < sizeof(struct sockaddr) ? \ | ||
| 3611 | sizeof((*sif)) : sizeof ((sif)->ifr_name) + sif->ifr_addr.sa_len) | ||
| 3612 | |||
| 3613 | int len = SIZEOF_IFREQ (ifq); | ||
| 3614 | #else | ||
| 3615 | int len = sizeof (*ifreq); | ||
| 3616 | #endif | ||
| 3597 | char namebuf[sizeof (ifq->ifr_name) + 1]; | 3617 | char namebuf[sizeof (ifq->ifr_name) + 1]; |
| 3618 | i += len; | ||
| 3619 | ifreq = (struct ifreq*) ((char*) ifreq + len); | ||
| 3620 | |||
| 3598 | if (ifq->ifr_addr.sa_family != AF_INET) | 3621 | if (ifq->ifr_addr.sa_family != AF_INET) |
| 3599 | continue; | 3622 | continue; |
| 3623 | |||
| 3600 | memcpy (namebuf, ifq->ifr_name, sizeof (ifq->ifr_name)); | 3624 | memcpy (namebuf, ifq->ifr_name, sizeof (ifq->ifr_name)); |
| 3601 | namebuf[sizeof (ifq->ifr_name)] = 0; | 3625 | namebuf[sizeof (ifq->ifr_name)] = 0; |
| 3602 | res = Fcons (Fcons (build_string (namebuf), | 3626 | res = Fcons (Fcons (build_string (namebuf), |
| @@ -3605,6 +3629,7 @@ format; see the description of ADDRESS in `make-network-process'. */) | |||
| 3605 | res); | 3629 | res); |
| 3606 | } | 3630 | } |
| 3607 | 3631 | ||
| 3632 | xfree (buf); | ||
| 3608 | return res; | 3633 | return res; |
| 3609 | } | 3634 | } |
| 3610 | #endif /* SIOCGIFCONF */ | 3635 | #endif /* SIOCGIFCONF */ |
| @@ -3642,8 +3667,13 @@ static const struct ifflag_def ifflag_table[] = { | |||
| 3642 | { IFF_PROMISC, "promisc" }, | 3667 | { IFF_PROMISC, "promisc" }, |
| 3643 | #endif | 3668 | #endif |
| 3644 | #ifdef IFF_NOTRAILERS | 3669 | #ifdef IFF_NOTRAILERS |
| 3670 | #ifdef NS_IMPL_COCOA | ||
| 3671 | /* Really means smart, notrailers is obsolete */ | ||
| 3672 | { IFF_NOTRAILERS, "smart" }, | ||
| 3673 | #else | ||
| 3645 | { IFF_NOTRAILERS, "notrailers" }, | 3674 | { IFF_NOTRAILERS, "notrailers" }, |
| 3646 | #endif | 3675 | #endif |
| 3676 | #endif | ||
| 3647 | #ifdef IFF_ALLMULTI | 3677 | #ifdef IFF_ALLMULTI |
| 3648 | { IFF_ALLMULTI, "allmulti" }, | 3678 | { IFF_ALLMULTI, "allmulti" }, |
| 3649 | #endif | 3679 | #endif |
| @@ -3696,6 +3726,9 @@ FLAGS is the current flags of the interface. */) | |||
| 3696 | Lisp_Object elt; | 3726 | Lisp_Object elt; |
| 3697 | int s; | 3727 | int s; |
| 3698 | int any = 0; | 3728 | int any = 0; |
| 3729 | #if defined(HAVE_GETIFADDRS) | ||
| 3730 | struct ifaddrs *ifap; | ||
| 3731 | #endif | ||
| 3699 | 3732 | ||
| 3700 | CHECK_STRING (ifname); | 3733 | CHECK_STRING (ifname); |
| 3701 | 3734 | ||
| @@ -3714,6 +3747,12 @@ FLAGS is the current flags of the interface. */) | |||
| 3714 | const struct ifflag_def *fp; | 3747 | const struct ifflag_def *fp; |
| 3715 | int fnum; | 3748 | int fnum; |
| 3716 | 3749 | ||
| 3750 | /* If flags is smaller than int (i.e. short) it may have the high bit set | ||
| 3751 | due to IFF_MULTICAST. In that case, sign extending it into | ||
| 3752 | an int is wrong. */ | ||
| 3753 | if (flags < 0 && sizeof (rq.ifr_flags) < sizeof (flags)) | ||
| 3754 | flags = (unsigned short) rq.ifr_flags; | ||
| 3755 | |||
| 3717 | any = 1; | 3756 | any = 1; |
| 3718 | for (fp = ifflag_table; flags != 0 && fp->flag_sym; fp++) | 3757 | for (fp = ifflag_table; flags != 0 && fp->flag_sym; fp++) |
| 3719 | { | 3758 | { |
| @@ -3747,7 +3786,38 @@ FLAGS is the current flags of the interface. */) | |||
| 3747 | p->contents[n] = make_number (((unsigned char *)&rq.ifr_hwaddr.sa_data[0])[n]); | 3786 | p->contents[n] = make_number (((unsigned char *)&rq.ifr_hwaddr.sa_data[0])[n]); |
| 3748 | elt = Fcons (make_number (rq.ifr_hwaddr.sa_family), hwaddr); | 3787 | elt = Fcons (make_number (rq.ifr_hwaddr.sa_family), hwaddr); |
| 3749 | } | 3788 | } |
| 3789 | #elif defined(HAVE_GETIFADDRS) && defined(LLADDR) | ||
| 3790 | if (getifaddrs (&ifap) != -1) | ||
| 3791 | { | ||
| 3792 | Lisp_Object hwaddr = Fmake_vector (make_number (6), Qnil); | ||
| 3793 | register struct Lisp_Vector *p = XVECTOR (hwaddr); | ||
| 3794 | struct ifaddrs *it; | ||
| 3795 | |||
| 3796 | for (it = ifap; it != NULL; it = it->ifa_next) | ||
| 3797 | { | ||
| 3798 | struct sockaddr_dl *sdl = (struct sockaddr_dl*) it->ifa_addr; | ||
| 3799 | unsigned char linkaddr[6]; | ||
| 3800 | int n; | ||
| 3801 | |||
| 3802 | if (it->ifa_addr->sa_family != AF_LINK | ||
| 3803 | || strcmp (it->ifa_name, SSDATA (ifname)) != 0 | ||
| 3804 | || sdl->sdl_alen != 6) | ||
| 3805 | continue; | ||
| 3806 | |||
| 3807 | memcpy (linkaddr, LLADDR(sdl), sdl->sdl_alen); | ||
| 3808 | for (n = 0; n < 6; n++) | ||
| 3809 | p->contents[n] = make_number (linkaddr[n]); | ||
| 3810 | |||
| 3811 | elt = Fcons (make_number (it->ifa_addr->sa_family), hwaddr); | ||
| 3812 | break; | ||
| 3813 | } | ||
| 3814 | } | ||
| 3815 | #ifdef HAVE_FREEIFADDRS | ||
| 3816 | freeifaddrs (ifap); | ||
| 3750 | #endif | 3817 | #endif |
| 3818 | |||
| 3819 | #endif /* HAVE_GETIFADDRS && LLADDR */ | ||
| 3820 | |||
| 3751 | res = Fcons (elt, res); | 3821 | res = Fcons (elt, res); |
| 3752 | 3822 | ||
| 3753 | elt = Qnil; | 3823 | elt = Qnil; |