diff options
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 93 |
1 files changed, 83 insertions, 10 deletions
diff --git a/src/process.c b/src/process.c index f2c2bfd81c5..887090df26c 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,10 @@ 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 | ptrdiff_t ifaces = 0; | 3572 | void *buf = NULL; |
| 3562 | int buf_size, s; | 3573 | ptrdiff_t buf_size = 512; |
| 3574 | int s, i; | ||
| 3563 | Lisp_Object res; | 3575 | Lisp_Object res; |
| 3564 | 3576 | ||
| 3565 | s = socket (AF_INET, SOCK_STREAM, 0); | 3577 | s = socket (AF_INET, SOCK_STREAM, 0); |
| @@ -3567,14 +3579,14 @@ format; see the description of ADDRESS in `make-network-process'. */) | |||
| 3567 | return Qnil; | 3579 | return Qnil; |
| 3568 | 3580 | ||
| 3569 | again: | 3581 | again: |
| 3570 | ifreqs = xpalloc (ifreqs, &ifaces, 25, | 3582 | |
| 3571 | INT_MAX / sizeof *ifreqs, sizeof *ifreqs); | 3583 | buf = xpalloc (buf, &buf_size, sizeof *ifreq, INT_MAX, 1); |
| 3572 | buf_size = ifaces * sizeof (ifreqs[0]); | 3584 | ifconf.ifc_buf = buf; |
| 3573 | ifconf.ifc_len = buf_size; | 3585 | ifconf.ifc_len = buf_size; |
| 3574 | ifconf.ifc_req = ifreqs; | ||
| 3575 | if (ioctl (s, SIOCGIFCONF, &ifconf)) | 3586 | if (ioctl (s, SIOCGIFCONF, &ifconf)) |
| 3576 | { | 3587 | { |
| 3577 | close (s); | 3588 | close (s); |
| 3589 | xfree (buf); | ||
| 3578 | return Qnil; | 3590 | return Qnil; |
| 3579 | } | 3591 | } |
| 3580 | 3592 | ||
| @@ -3582,15 +3594,29 @@ format; see the description of ADDRESS in `make-network-process'. */) | |||
| 3582 | goto again; | 3594 | goto again; |
| 3583 | 3595 | ||
| 3584 | close (s); | 3596 | close (s); |
| 3585 | ifaces = ifconf.ifc_len / sizeof (ifreqs[0]); | ||
| 3586 | 3597 | ||
| 3587 | res = Qnil; | 3598 | res = Qnil; |
| 3588 | while (--ifaces >= 0) | 3599 | for (ifreq = ifconf.ifc_req; |
| 3600 | (char *) ifreq < (char *) (ifconf.ifc_req) + ifconf.ifc_len; | ||
| 3601 | ) | ||
| 3589 | { | 3602 | { |
| 3590 | struct ifreq *ifq = &ifreqs[ifaces]; | 3603 | struct ifreq *ifq = ifreq; |
| 3604 | #ifdef HAVE_STRUCT_IFREQ_IFR_ADDR_SA_LEN | ||
| 3605 | #define SIZEOF_IFREQ(sif) \ | ||
| 3606 | ((sif)->ifr_addr.sa_len < sizeof(struct sockaddr) ? \ | ||
| 3607 | sizeof((*sif)) : sizeof ((sif)->ifr_name) + sif->ifr_addr.sa_len) | ||
| 3608 | |||
| 3609 | int len = SIZEOF_IFREQ (ifq); | ||
| 3610 | #else | ||
| 3611 | int len = sizeof (*ifreq); | ||
| 3612 | #endif | ||
| 3591 | char namebuf[sizeof (ifq->ifr_name) + 1]; | 3613 | char namebuf[sizeof (ifq->ifr_name) + 1]; |
| 3614 | i += len; | ||
| 3615 | ifreq = (struct ifreq*) ((char*) ifreq + len); | ||
| 3616 | |||
| 3592 | if (ifq->ifr_addr.sa_family != AF_INET) | 3617 | if (ifq->ifr_addr.sa_family != AF_INET) |
| 3593 | continue; | 3618 | continue; |
| 3619 | |||
| 3594 | memcpy (namebuf, ifq->ifr_name, sizeof (ifq->ifr_name)); | 3620 | memcpy (namebuf, ifq->ifr_name, sizeof (ifq->ifr_name)); |
| 3595 | namebuf[sizeof (ifq->ifr_name)] = 0; | 3621 | namebuf[sizeof (ifq->ifr_name)] = 0; |
| 3596 | res = Fcons (Fcons (build_string (namebuf), | 3622 | res = Fcons (Fcons (build_string (namebuf), |
| @@ -3599,6 +3625,7 @@ format; see the description of ADDRESS in `make-network-process'. */) | |||
| 3599 | res); | 3625 | res); |
| 3600 | } | 3626 | } |
| 3601 | 3627 | ||
| 3628 | xfree (buf); | ||
| 3602 | return res; | 3629 | return res; |
| 3603 | } | 3630 | } |
| 3604 | #endif /* SIOCGIFCONF */ | 3631 | #endif /* SIOCGIFCONF */ |
| @@ -3636,8 +3663,13 @@ static const struct ifflag_def ifflag_table[] = { | |||
| 3636 | { IFF_PROMISC, "promisc" }, | 3663 | { IFF_PROMISC, "promisc" }, |
| 3637 | #endif | 3664 | #endif |
| 3638 | #ifdef IFF_NOTRAILERS | 3665 | #ifdef IFF_NOTRAILERS |
| 3666 | #ifdef NS_IMPL_COCOA | ||
| 3667 | /* Really means smart, notrailers is obsolete */ | ||
| 3668 | { IFF_NOTRAILERS, "smart" }, | ||
| 3669 | #else | ||
| 3639 | { IFF_NOTRAILERS, "notrailers" }, | 3670 | { IFF_NOTRAILERS, "notrailers" }, |
| 3640 | #endif | 3671 | #endif |
| 3672 | #endif | ||
| 3641 | #ifdef IFF_ALLMULTI | 3673 | #ifdef IFF_ALLMULTI |
| 3642 | { IFF_ALLMULTI, "allmulti" }, | 3674 | { IFF_ALLMULTI, "allmulti" }, |
| 3643 | #endif | 3675 | #endif |
| @@ -3690,6 +3722,10 @@ FLAGS is the current flags of the interface. */) | |||
| 3690 | Lisp_Object elt; | 3722 | Lisp_Object elt; |
| 3691 | int s; | 3723 | int s; |
| 3692 | int any = 0; | 3724 | int any = 0; |
| 3725 | #if (! (defined SIOCGIFHWADDR && defined HAVE_STRUCT_IFREQ_IFR_HWADDR) \ | ||
| 3726 | && defined HAVE_GETIFADDRS && defined LLADDR) | ||
| 3727 | struct ifaddrs *ifap; | ||
| 3728 | #endif | ||
| 3693 | 3729 | ||
| 3694 | CHECK_STRING (ifname); | 3730 | CHECK_STRING (ifname); |
| 3695 | 3731 | ||
| @@ -3708,6 +3744,12 @@ FLAGS is the current flags of the interface. */) | |||
| 3708 | const struct ifflag_def *fp; | 3744 | const struct ifflag_def *fp; |
| 3709 | int fnum; | 3745 | int fnum; |
| 3710 | 3746 | ||
| 3747 | /* If flags is smaller than int (i.e. short) it may have the high bit set | ||
| 3748 | due to IFF_MULTICAST. In that case, sign extending it into | ||
| 3749 | an int is wrong. */ | ||
| 3750 | if (flags < 0 && sizeof (rq.ifr_flags) < sizeof (flags)) | ||
| 3751 | flags = (unsigned short) rq.ifr_flags; | ||
| 3752 | |||
| 3711 | any = 1; | 3753 | any = 1; |
| 3712 | for (fp = ifflag_table; flags != 0 && fp->flag_sym; fp++) | 3754 | for (fp = ifflag_table; flags != 0 && fp->flag_sym; fp++) |
| 3713 | { | 3755 | { |
| @@ -3741,7 +3783,38 @@ FLAGS is the current flags of the interface. */) | |||
| 3741 | p->contents[n] = make_number (((unsigned char *)&rq.ifr_hwaddr.sa_data[0])[n]); | 3783 | p->contents[n] = make_number (((unsigned char *)&rq.ifr_hwaddr.sa_data[0])[n]); |
| 3742 | elt = Fcons (make_number (rq.ifr_hwaddr.sa_family), hwaddr); | 3784 | elt = Fcons (make_number (rq.ifr_hwaddr.sa_family), hwaddr); |
| 3743 | } | 3785 | } |
| 3786 | #elif defined(HAVE_GETIFADDRS) && defined(LLADDR) | ||
| 3787 | if (getifaddrs (&ifap) != -1) | ||
| 3788 | { | ||
| 3789 | Lisp_Object hwaddr = Fmake_vector (make_number (6), Qnil); | ||
| 3790 | register struct Lisp_Vector *p = XVECTOR (hwaddr); | ||
| 3791 | struct ifaddrs *it; | ||
| 3792 | |||
| 3793 | for (it = ifap; it != NULL; it = it->ifa_next) | ||
| 3794 | { | ||
| 3795 | struct sockaddr_dl *sdl = (struct sockaddr_dl*) it->ifa_addr; | ||
| 3796 | unsigned char linkaddr[6]; | ||
| 3797 | int n; | ||
| 3798 | |||
| 3799 | if (it->ifa_addr->sa_family != AF_LINK | ||
| 3800 | || strcmp (it->ifa_name, SSDATA (ifname)) != 0 | ||
| 3801 | || sdl->sdl_alen != 6) | ||
| 3802 | continue; | ||
| 3803 | |||
| 3804 | memcpy (linkaddr, LLADDR(sdl), sdl->sdl_alen); | ||
| 3805 | for (n = 0; n < 6; n++) | ||
| 3806 | p->contents[n] = make_number (linkaddr[n]); | ||
| 3807 | |||
| 3808 | elt = Fcons (make_number (it->ifa_addr->sa_family), hwaddr); | ||
| 3809 | break; | ||
| 3810 | } | ||
| 3811 | } | ||
| 3812 | #ifdef HAVE_FREEIFADDRS | ||
| 3813 | freeifaddrs (ifap); | ||
| 3744 | #endif | 3814 | #endif |
| 3815 | |||
| 3816 | #endif /* HAVE_GETIFADDRS && LLADDR */ | ||
| 3817 | |||
| 3745 | res = Fcons (elt, res); | 3818 | res = Fcons (elt, res); |
| 3746 | 3819 | ||
| 3747 | elt = Qnil; | 3820 | elt = Qnil; |