Mercurial > emacs
comparison src/process.c @ 52503:256a27a47af1
[HAVE_SOCKETS]: Include sys/ioctl.h and net/if.h.
(Fnetwork_interface_list, Fget_network_interface_info): New defuns.
(syms_of_process): Defsubr them.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Sat, 13 Sep 2003 23:34:33 +0000 |
parents | 695cf19ef79e |
children | 0ca23eb697b9 |
comparison
equal
deleted
inserted
replaced
52502:9afe1154d52b | 52503:256a27a47af1 |
---|---|
94 #undef O_NONBLOCK | 94 #undef O_NONBLOCK |
95 #endif /* BROKEN_O_NONBLOCK */ | 95 #endif /* BROKEN_O_NONBLOCK */ |
96 | 96 |
97 #ifdef NEED_BSDTTY | 97 #ifdef NEED_BSDTTY |
98 #include <bsdtty.h> | 98 #include <bsdtty.h> |
99 #endif | |
100 | |
101 /* Can we use SIOCGIFCONF and/or SIOCGIFADDR */ | |
102 #ifdef HAVE_SOCKETS | |
103 #if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_NET_IF_H) | |
104 /* sys/ioctl.h may have been included already */ | |
105 #ifndef SIOCGIFADDR | |
106 #include <sys/ioctl.h> | |
107 #endif | |
108 #include <net/if.h> | |
109 #endif | |
99 #endif | 110 #endif |
100 | 111 |
101 #ifdef IRIS | 112 #ifdef IRIS |
102 #include <sys/sysmacros.h> /* for "minor" */ | 113 #include <sys/sysmacros.h> /* for "minor" */ |
103 #endif /* not IRIS */ | 114 #endif /* not IRIS */ |
3352 ? Qnil : Qt); | 3363 ? Qnil : Qt); |
3353 | 3364 |
3354 UNGCPRO; | 3365 UNGCPRO; |
3355 return proc; | 3366 return proc; |
3356 } | 3367 } |
3368 #endif /* HAVE_SOCKETS */ | |
3369 | |
3370 | |
3371 #ifdef HAVE_SOCKETS | |
3372 | |
3373 #ifdef SIOCGIFCONF | |
3374 DEFUN ("network-interface-list", Fnetwork_interface_list, Snetwork_interface_list, 0, 0, 0, | |
3375 doc: /* Return an alist of all network interfaces and their network address. | |
3376 Each element is a cons, the car of which is a string containing the | |
3377 interface name, and the cdr is the network address in internal | |
3378 format; see the description of ADDRESS in 'make-network-process'. */) | |
3379 () | |
3380 { | |
3381 struct ifconf ifconf; | |
3382 struct ifreq *ifreqs = NULL; | |
3383 int ifaces = 0; | |
3384 int buf_size, s; | |
3385 Lisp_Object res; | |
3386 | |
3387 s = socket (AF_INET, SOCK_STREAM, 0); | |
3388 if (s < 0) | |
3389 return Qnil; | |
3390 | |
3391 again: | |
3392 ifaces += 25; | |
3393 buf_size = ifaces * sizeof(ifreqs[0]); | |
3394 ifreqs = (struct ifreq *)xrealloc(ifreqs, buf_size); | |
3395 if (!ifreqs) | |
3396 { | |
3397 close (s); | |
3398 return Qnil; | |
3399 } | |
3400 | |
3401 ifconf.ifc_len = buf_size; | |
3402 ifconf.ifc_req = ifreqs; | |
3403 if (ioctl (s, SIOCGIFCONF, &ifconf)) | |
3404 { | |
3405 close (s); | |
3406 return Qnil; | |
3407 } | |
3408 | |
3409 if (ifconf.ifc_len == buf_size) | |
3410 goto again; | |
3411 | |
3412 close (s); | |
3413 ifaces = ifconf.ifc_len / sizeof (ifreqs[0]); | |
3414 | |
3415 res = Qnil; | |
3416 while (--ifaces >= 0) | |
3417 { | |
3418 struct ifreq *ifq = &ifreqs[ifaces]; | |
3419 char namebuf[sizeof (ifq->ifr_name) + 1]; | |
3420 if (ifq->ifr_addr.sa_family != AF_INET) | |
3421 continue; | |
3422 bcopy (ifq->ifr_name, namebuf, sizeof (ifq->ifr_name)); | |
3423 namebuf[sizeof (ifq->ifr_name)] = 0; | |
3424 res = Fcons (Fcons (build_string (namebuf), | |
3425 conv_sockaddr_to_lisp (&ifq->ifr_addr, | |
3426 sizeof (struct sockaddr))), | |
3427 res); | |
3428 } | |
3429 | |
3430 return res; | |
3431 } | |
3432 #endif | |
3433 | |
3434 #if defined(SIOCGIFADDR) || defined(SIOCGIFHWADDR) || defined(SIOCGIFFLAGS) | |
3435 | |
3436 struct ifflag_def { | |
3437 int flag_bit; | |
3438 char *flag_sym; | |
3439 }; | |
3440 | |
3441 static struct ifflag_def ifflag_table[] = { | |
3442 #ifdef IFF_UP | |
3443 { IFF_UP, "up" }, | |
3444 #endif | |
3445 #ifdef IFF_BROADCAST | |
3446 { IFF_BROADCAST, "broadcast" }, | |
3447 #endif | |
3448 #ifdef IFF_DEBUG | |
3449 { IFF_DEBUG, "debug" }, | |
3450 #endif | |
3451 #ifdef IFF_LOOPBACK | |
3452 { IFF_LOOPBACK, "loopback" }, | |
3453 #endif | |
3454 #ifdef IFF_POINTOPOINT | |
3455 { IFF_POINTOPOINT, "pointopoint" }, | |
3456 #endif | |
3457 #ifdef IFF_RUNNING | |
3458 { IFF_RUNNING, "running" }, | |
3459 #endif | |
3460 #ifdef IFF_NOARP | |
3461 { IFF_NOARP, "noarp" }, | |
3462 #endif | |
3463 #ifdef IFF_PROMISC | |
3464 { IFF_PROMISC, "promisc" }, | |
3465 #endif | |
3466 #ifdef IFF_NOTRAILERS | |
3467 { IFF_NOTRAILERS, "notrailers" }, | |
3468 #endif | |
3469 #ifdef IFF_ALLMULTI | |
3470 { IFF_ALLMULTI, "allmulti" }, | |
3471 #endif | |
3472 #ifdef IFF_MASTER | |
3473 { IFF_MASTER, "master" }, | |
3474 #endif | |
3475 #ifdef IFF_SLAVE | |
3476 { IFF_SLAVE, "slave" }, | |
3477 #endif | |
3478 #ifdef IFF_MULTICAST | |
3479 { IFF_MULTICAST, "multicast" }, | |
3480 #endif | |
3481 #ifdef IFF_PORTSEL | |
3482 { IFF_PORTSEL, "portsel" }, | |
3483 #endif | |
3484 #ifdef IFF_AUTOMEDIA | |
3485 { IFF_AUTOMEDIA, "automedia" }, | |
3486 #endif | |
3487 #ifdef IFF_DYNAMIC | |
3488 { IFF_DYNAMIC, "dynamic" }, | |
3489 #endif | |
3490 { 0, 0 } | |
3491 }; | |
3492 | |
3493 DEFUN ("get-network-interface-info", Fget_network_interface_info, Sget_network_interface_info, 1, 1, 0, | |
3494 doc: /* Return information about network interface named IFNAME. | |
3495 The return value is a list (ADDR BCAST NETMASK HWADDR FLAGS), | |
3496 where ADDR is the layer 3 address, BCAST is the layer 3 broadcast address, | |
3497 NETMASK is the layer 3 network mask, HWADDR is the layer 2 addres, and | |
3498 FLAGS is the current flags of the interface. */) | |
3499 (ifname) | |
3500 Lisp_Object ifname; | |
3501 { | |
3502 struct ifreq rq; | |
3503 Lisp_Object res = Qnil; | |
3504 Lisp_Object elt; | |
3505 int s; | |
3506 int any = 0; | |
3507 | |
3508 CHECK_STRING (ifname); | |
3509 | |
3510 bzero (rq.ifr_name, sizeof rq.ifr_name); | |
3511 strncpy (rq.ifr_name, SDATA (ifname), sizeof (rq.ifr_name)); | |
3512 | |
3513 s = socket (AF_INET, SOCK_STREAM, 0); | |
3514 if (s < 0) | |
3515 return Qnil; | |
3516 | |
3517 elt = Qnil; | |
3518 #ifdef SIOCGIFFLAGS | |
3519 if (ioctl (s, SIOCGIFFLAGS, &rq) == 0) | |
3520 { | |
3521 int flags = rq.ifr_flags; | |
3522 struct ifflag_def *fp; | |
3523 int fnum; | |
3524 | |
3525 any++; | |
3526 for (fp = ifflag_table; flags != 0 && fp; fp++) | |
3527 { | |
3528 if (flags & fp->flag_bit) | |
3529 { | |
3530 elt = Fcons (intern (fp->flag_sym), elt); | |
3531 flags -= fp->flag_bit; | |
3532 } | |
3533 } | |
3534 for (fnum = 0; flags && fnum < 32; fnum++) | |
3535 { | |
3536 if (flags & (1 << fnum)) | |
3537 { | |
3538 elt = Fcons (make_number (fnum), elt); | |
3539 } | |
3540 } | |
3541 } | |
3542 #endif | |
3543 res = Fcons (elt, res); | |
3544 | |
3545 elt = Qnil; | |
3546 #ifdef SIOCGIFHWADDR | |
3547 if (ioctl (s, SIOCGIFHWADDR, &rq) == 0) | |
3548 { | |
3549 Lisp_Object hwaddr = Fmake_vector (6, Qnil); | |
3550 register struct Lisp_Vector *p = XVECTOR (hwaddr); | |
3551 int n; | |
3552 | |
3553 any++; | |
3554 for (n = 0; n < 6; n++) | |
3555 p->contents[n] = make_number (((unsigned char *)&rq.ifr_hwaddr.sa_data[0])[n]); | |
3556 elt = Fcons (XINT (rq.ifr_hwaddr.sa_family), hwaddr); | |
3557 } | |
3558 #endif | |
3559 res = Fcons (elt, res); | |
3560 | |
3561 elt = Qnil; | |
3562 #ifdef SIOCGIFNETMASK | |
3563 if (ioctl (s, SIOCGIFNETMASK, &rq) == 0) | |
3564 { | |
3565 any++; | |
3566 elt = conv_sockaddr_to_lisp (&rq.ifr_netmask, sizeof (rq.ifr_netmask)); | |
3567 } | |
3568 #endif | |
3569 res = Fcons (elt, res); | |
3570 | |
3571 elt = Qnil; | |
3572 #ifdef SIOCGIFBRDADDR | |
3573 if (ioctl (s, SIOCGIFBRDADDR, &rq) == 0) | |
3574 { | |
3575 any++; | |
3576 elt = conv_sockaddr_to_lisp (&rq.ifr_broadaddr, sizeof (rq.ifr_broadaddr)); | |
3577 } | |
3578 #endif | |
3579 res = Fcons (elt, res); | |
3580 | |
3581 elt = Qnil; | |
3582 #ifdef SIOCGIFADDR | |
3583 if (ioctl (s, SIOCGIFADDR, &rq) == 0) | |
3584 { | |
3585 any++; | |
3586 elt = conv_sockaddr_to_lisp (&rq.ifr_addr, sizeof (rq.ifr_addr)); | |
3587 } | |
3588 #endif | |
3589 res = Fcons (elt, res); | |
3590 | |
3591 close (s); | |
3592 | |
3593 return any ? res : Qnil; | |
3594 } | |
3595 #endif | |
3357 #endif /* HAVE_SOCKETS */ | 3596 #endif /* HAVE_SOCKETS */ |
3358 | 3597 |
3359 void | 3598 void |
3360 deactivate_process (proc) | 3599 deactivate_process (proc) |
3361 Lisp_Object proc; | 3600 Lisp_Object proc; |
6465 defsubr (&Sstart_process); | 6704 defsubr (&Sstart_process); |
6466 #ifdef HAVE_SOCKETS | 6705 #ifdef HAVE_SOCKETS |
6467 defsubr (&Sset_network_process_options); | 6706 defsubr (&Sset_network_process_options); |
6468 defsubr (&Smake_network_process); | 6707 defsubr (&Smake_network_process); |
6469 defsubr (&Sformat_network_address); | 6708 defsubr (&Sformat_network_address); |
6709 #ifdef SIOCGIFCONF | |
6710 defsubr (&Snetwork_interface_list); | |
6711 #endif | |
6712 #if defined(SIOCGIFADDR) || defined(SIOCGIFHWADDR) || defined(SIOCGIFFLAGS) | |
6713 defsubr (&Sget_network_interface_info); | |
6714 #endif | |
6470 #endif /* HAVE_SOCKETS */ | 6715 #endif /* HAVE_SOCKETS */ |
6471 #ifdef DATAGRAM_SOCKETS | 6716 #ifdef DATAGRAM_SOCKETS |
6472 defsubr (&Sprocess_datagram_address); | 6717 defsubr (&Sprocess_datagram_address); |
6473 defsubr (&Sset_process_datagram_address); | 6718 defsubr (&Sset_process_datagram_address); |
6474 #endif | 6719 #endif |