mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-18 06:30:05 +00:00
Update.
2004-06-30 Ulrich Drepper <drepper@redhat.com> * include/net/if.h: Handle if_nameindex and if_freenameindex with libc_proto_hidden. * sysdeps/unix/sysv/linux/netlinkaccess.h: New file. * sysdeps/unix/sysv/linux/ifaddrs.c: Export netlink handling functions. * sysdeps/unix/sysv/linux/if_index.c (if_nameindex): Implement using netlink if possible. Fall back on ioctl method if necessary. * include/unistd.h: Declare __truncate. * sysdeps/generic/truncate.c: Also define __truncate. * sysdeps/mach/hurd/truncate.c: Likewise. * sysdeps/unix/common/syscalls.list: Likewise. * sysdeps/unix/sysv/linux/truncate64.c: Use __truncate, not truncate.
This commit is contained in:
parent
606135cf62
commit
f516442913
15
ChangeLog
15
ChangeLog
@ -1,3 +1,18 @@
|
|||||||
|
2004-06-30 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* include/net/if.h: Handle if_nameindex and if_freenameindex with
|
||||||
|
libc_proto_hidden.
|
||||||
|
* sysdeps/unix/sysv/linux/netlinkaccess.h: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/ifaddrs.c: Export netlink handling functions.
|
||||||
|
* sysdeps/unix/sysv/linux/if_index.c (if_nameindex): Implement using
|
||||||
|
netlink if possible. Fall back on ioctl method if necessary.
|
||||||
|
|
||||||
|
* include/unistd.h: Declare __truncate.
|
||||||
|
* sysdeps/generic/truncate.c: Also define __truncate.
|
||||||
|
* sysdeps/mach/hurd/truncate.c: Likewise.
|
||||||
|
* sysdeps/unix/common/syscalls.list: Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/truncate64.c: Use __truncate, not truncate.
|
||||||
|
|
||||||
2004-06-29 Ulrich Drepper <drepper@redhat.com>
|
2004-06-29 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* stdio-common/printf-parsemb.c (__parse_one_specmb): Initialize
|
* stdio-common/printf-parsemb.c (__parse_one_specmb): Initialize
|
||||||
|
@ -49,7 +49,7 @@ CFLAGS-charmap.c = -DCHARMAP_PATH='"$(i18ndir)/charmaps"' \
|
|||||||
CFLAGS-linereader.c = -DNO_TRANSLITERATION
|
CFLAGS-linereader.c = -DNO_TRANSLITERATION
|
||||||
CFLAGS-simple-hash.c = -I../locale
|
CFLAGS-simple-hash.c = -I../locale
|
||||||
|
|
||||||
tests = tst-iconv1 tst-iconv2 tst-iconv3
|
tests = tst-iconv1 tst-iconv2 tst-iconv3 tst-iconv5
|
||||||
|
|
||||||
distribute = gconv_builtin.h gconv_int.h loop.c skeleton.c iconv_prog.h \
|
distribute = gconv_builtin.h gconv_int.h loop.c skeleton.c iconv_prog.h \
|
||||||
iconv_charmap.c dummy-repertoire.c gconv_charset.h strtab.c \
|
iconv_charmap.c dummy-repertoire.c gconv_charset.h strtab.c \
|
||||||
|
158
iconv/tst-iconv5.c
Normal file
158
iconv/tst-iconv5.c
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/* Copyright (C) 2004 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by GOTO Masanori <gotom@debian.or.jp>, 2004
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#include <iconv.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#define SIZE 256 /* enough room for conversion */
|
||||||
|
#define SAMPLESTR "abc"
|
||||||
|
|
||||||
|
struct unalign
|
||||||
|
{
|
||||||
|
char str1[1];
|
||||||
|
char str2[SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct convcode
|
||||||
|
{
|
||||||
|
const char *tocode;
|
||||||
|
const char *fromcode;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* test builtin transformation */
|
||||||
|
struct convcode testcode[] = {
|
||||||
|
{"ASCII", "ASCII"},
|
||||||
|
{"UTF-8", "ASCII"},
|
||||||
|
{"UCS-2BE", "ASCII"},
|
||||||
|
{"UCS-2LE", "ASCII"},
|
||||||
|
{"UCS-4BE", "ASCII"},
|
||||||
|
{"UCS-4LE", "ASCII"},
|
||||||
|
};
|
||||||
|
|
||||||
|
int number = (int) sizeof (testcode) / sizeof (struct convcode);
|
||||||
|
|
||||||
|
int
|
||||||
|
convert (const char *tocode, const char *fromcode, char *inbufp,
|
||||||
|
size_t inbytesleft, char *outbufp, size_t outbytesleft)
|
||||||
|
{
|
||||||
|
iconv_t *ic;
|
||||||
|
size_t outbytes = outbytesleft;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ic = iconv_open (tocode, fromcode);
|
||||||
|
if (ic == (iconv_t *) - 1)
|
||||||
|
{
|
||||||
|
printf ("iconv_open failed: from: %s, to: %s: %s",
|
||||||
|
fromcode, tocode, strerror (errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (inbytesleft > 0)
|
||||||
|
{
|
||||||
|
ret = iconv (ic, &inbufp, &inbytesleft, &outbufp, &outbytes);
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
printf ("iconv failed: from: %s, to: %s: %s",
|
||||||
|
fromcode, tocode, strerror (errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = iconv_close (ic);
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
printf ("iconv_close failed: from: %s, to: %s: %s",
|
||||||
|
fromcode, tocode, strerror (errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return outbytesleft - outbytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
test_unalign (struct convcode *codes, char *str, int len)
|
||||||
|
{
|
||||||
|
struct unalign *inbufp, *outbufp;
|
||||||
|
char *inbuf, *outbuf;
|
||||||
|
size_t inbytesleft, outbytesleft;
|
||||||
|
int retlen;
|
||||||
|
|
||||||
|
/* allocating unaligned buffer for both inbuf and outbuf */
|
||||||
|
inbufp = (struct unalign *) malloc (sizeof (struct unalign));
|
||||||
|
if (!inbufp)
|
||||||
|
{
|
||||||
|
printf ("no memory available\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
inbuf = inbufp->str2;
|
||||||
|
|
||||||
|
outbufp = (struct unalign *) malloc (sizeof (struct unalign));
|
||||||
|
if (!outbufp)
|
||||||
|
{
|
||||||
|
printf ("no memory available\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
outbuf = outbufp->str2;
|
||||||
|
|
||||||
|
/* first iconv phase */
|
||||||
|
memcpy (inbuf, str, len);
|
||||||
|
inbytesleft = len;
|
||||||
|
outbytesleft = sizeof (struct unalign);
|
||||||
|
retlen = convert (codes->tocode, codes->fromcode, inbuf, inbytesleft,
|
||||||
|
outbuf, outbytesleft);
|
||||||
|
if (retlen == -1) /* failed */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* second round trip iconv phase */
|
||||||
|
memcpy (inbuf, outbuf, retlen);
|
||||||
|
inbytesleft = retlen;
|
||||||
|
outbytesleft = sizeof (struct unalign);
|
||||||
|
retlen = convert (codes->fromcode, codes->tocode, inbuf, inbytesleft,
|
||||||
|
outbuf, outbytesleft);
|
||||||
|
if (retlen == -1) /* failed */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
free (inbufp);
|
||||||
|
free (outbufp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < number; i++)
|
||||||
|
{
|
||||||
|
ret = test_unalign (&testcode[i], (char *) SAMPLESTR, sizeof (SAMPLESTR));
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
printf ("iconv: %s <-> %s: ok\n",
|
||||||
|
testcode[i].fromcode, testcode[i].tocode);
|
||||||
|
}
|
||||||
|
printf ("Succeeded.\n");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -4,5 +4,7 @@
|
|||||||
|
|
||||||
libc_hidden_proto (if_nametoindex)
|
libc_hidden_proto (if_nametoindex)
|
||||||
libc_hidden_proto (if_indextoname)
|
libc_hidden_proto (if_indextoname)
|
||||||
|
libc_hidden_proto (if_nameindex)
|
||||||
|
libc_hidden_proto (if_freenameindex)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -130,6 +130,7 @@ extern int __getpagesize (void) __attribute__ ((__const__));
|
|||||||
libc_hidden_proto (__getpagesize)
|
libc_hidden_proto (__getpagesize)
|
||||||
extern int __ftruncate (int __fd, __off_t __length);
|
extern int __ftruncate (int __fd, __off_t __length);
|
||||||
extern int __ftruncate64 (int __fd, __off64_t __length);
|
extern int __ftruncate64 (int __fd, __off64_t __length);
|
||||||
|
extern int __truncate (const char *path, __off_t __length);
|
||||||
extern void *__sbrk (intptr_t __delta);
|
extern void *__sbrk (intptr_t __delta);
|
||||||
libc_hidden_proto (__sbrk)
|
libc_hidden_proto (__sbrk)
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc.
|
/* Copyright (C) 1991, 1995, 1996, 1997, 2004 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -21,13 +21,14 @@
|
|||||||
|
|
||||||
/* Truncate PATH to LENGTH bytes. */
|
/* Truncate PATH to LENGTH bytes. */
|
||||||
int
|
int
|
||||||
truncate (path, length)
|
__truncate (path, length)
|
||||||
const char *path;
|
const char *path;
|
||||||
off_t length;
|
off_t length;
|
||||||
{
|
{
|
||||||
__set_errno (ENOSYS);
|
__set_errno (ENOSYS);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
weak_alias (__truncate, truncate)
|
||||||
|
|
||||||
stub_warning (truncate)
|
stub_warning (truncate)
|
||||||
#include <stub-tag.h>
|
#include <stub-tag.h>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 1991, 92, 93, 94, 95, 97, 98 Free Software Foundation, Inc.
|
/* Copyright (C) 1991,92,93,94,95,97,98,2004 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
/* Truncate FILE_NAME to LENGTH bytes. */
|
/* Truncate FILE_NAME to LENGTH bytes. */
|
||||||
int
|
int
|
||||||
truncate (file_name, length)
|
__truncate (file_name, length)
|
||||||
const char *file_name;
|
const char *file_name;
|
||||||
off_t length;
|
off_t length;
|
||||||
{
|
{
|
||||||
@ -41,3 +41,4 @@ truncate (file_name, length)
|
|||||||
return __hurd_fail (err);
|
return __hurd_fail (err);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
weak_alias (__truncate, truncate)
|
||||||
|
@ -12,5 +12,5 @@ setregid - setregid i:ii __setregid setregid
|
|||||||
setreuid - setreuid i:ii __setreuid setreuid
|
setreuid - setreuid i:ii __setreuid setreuid
|
||||||
sigaction - sigaction i:ipp __sigaction sigaction
|
sigaction - sigaction i:ipp __sigaction sigaction
|
||||||
sys_lstat lxstat lstat i:sp __syscall_lstat
|
sys_lstat lxstat lstat i:sp __syscall_lstat
|
||||||
truncate - truncate i:si truncate
|
truncate - truncate i:si __truncate truncate
|
||||||
vhangup - vhangup i:i vhangup
|
vhangup - vhangup i:i vhangup
|
||||||
|
@ -28,7 +28,8 @@
|
|||||||
#include <bits/libc-lock.h>
|
#include <bits/libc-lock.h>
|
||||||
#include <not-cancel.h>
|
#include <not-cancel.h>
|
||||||
|
|
||||||
#include "kernel-features.h"
|
#include "netlinkaccess.h"
|
||||||
|
|
||||||
|
|
||||||
/* Variable to signal whether SIOCGIFCONF is not available. */
|
/* Variable to signal whether SIOCGIFCONF is not available. */
|
||||||
# if __ASSUME_SIOCGIFNAME == 0
|
# if __ASSUME_SIOCGIFNAME == 0
|
||||||
@ -73,20 +74,18 @@ if_freenameindex (struct if_nameindex *ifn)
|
|||||||
struct if_nameindex *ptr = ifn;
|
struct if_nameindex *ptr = ifn;
|
||||||
while (ptr->if_name || ptr->if_index)
|
while (ptr->if_name || ptr->if_index)
|
||||||
{
|
{
|
||||||
if (ptr->if_name)
|
|
||||||
free (ptr->if_name);
|
free (ptr->if_name);
|
||||||
++ptr;
|
++ptr;
|
||||||
}
|
}
|
||||||
free (ifn);
|
free (ifn);
|
||||||
}
|
}
|
||||||
|
libc_hidden_def (if_freenameindex)
|
||||||
|
|
||||||
struct if_nameindex *
|
|
||||||
if_nameindex (void)
|
#if __ASSUME_NETLINK_SUPPORT == 0
|
||||||
|
static struct if_nameindex *
|
||||||
|
if_nameindex_ioctl (void)
|
||||||
{
|
{
|
||||||
#ifndef SIOCGIFINDEX
|
|
||||||
__set_errno (ENOSYS);
|
|
||||||
return NULL;
|
|
||||||
#else
|
|
||||||
int fd = __opensock ();
|
int fd = __opensock ();
|
||||||
struct ifconf ifc;
|
struct ifconf ifc;
|
||||||
unsigned int nifs, i;
|
unsigned int nifs, i;
|
||||||
@ -174,8 +173,147 @@ if_nameindex (void)
|
|||||||
|
|
||||||
close_not_cancel_no_status (fd);
|
close_not_cancel_no_status (fd);
|
||||||
return idx;
|
return idx;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static struct if_nameindex *
|
||||||
|
if_nameindex_netlink (void)
|
||||||
|
{
|
||||||
|
struct netlink_handle nh = { 0, 0, 0, NULL, NULL };
|
||||||
|
struct if_nameindex *idx = NULL;
|
||||||
|
|
||||||
|
if (__no_netlink_support || __netlink_open (&nh) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
|
||||||
|
/* Tell the kernel that we wish to get a list of all
|
||||||
|
active interfaces. */
|
||||||
|
if (__netlink_sendreq (&nh, RTM_GETLINK) < 0)
|
||||||
|
goto exit_close;
|
||||||
|
|
||||||
|
/* Collect all data for every interface. */
|
||||||
|
if (__netlink_receive (&nh) < 0)
|
||||||
|
goto exit_free;
|
||||||
|
|
||||||
|
/* Count the interfaces. */
|
||||||
|
unsigned int nifs = 0;
|
||||||
|
for (struct netlink_res *nlp = nh.nlm_list; nlp; nlp = nlp->next)
|
||||||
|
{
|
||||||
|
struct nlmsghdr *nlh;
|
||||||
|
size_t size = nlp->size;
|
||||||
|
|
||||||
|
if (nlp->nlh == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Walk through all entries we got from the kernel and look, which
|
||||||
|
message type they contain. */
|
||||||
|
for (nlh = nlp->nlh; NLMSG_OK (nlh, size); nlh = NLMSG_NEXT (nlh, size))
|
||||||
|
{
|
||||||
|
/* Check if the message is what we want. */
|
||||||
|
if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (nlh->nlmsg_type == NLMSG_DONE)
|
||||||
|
break; /* ok */
|
||||||
|
|
||||||
|
if (nlh->nlmsg_type == RTM_NEWLINK)
|
||||||
|
++nifs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
idx = malloc ((nifs + 1) * sizeof (struct if_nameindex));
|
||||||
|
if (idx == NULL)
|
||||||
|
{
|
||||||
|
nomem:
|
||||||
|
__set_errno (ENOBUFS);
|
||||||
|
goto exit_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the interfaces. */
|
||||||
|
nifs = 0;
|
||||||
|
for (struct netlink_res *nlp = nh.nlm_list; nlp; nlp = nlp->next)
|
||||||
|
{
|
||||||
|
struct nlmsghdr *nlh;
|
||||||
|
size_t size = nlp->size;
|
||||||
|
|
||||||
|
if (nlp->nlh == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Walk through all entries we got from the kernel and look, which
|
||||||
|
message type they contain. */
|
||||||
|
for (nlh = nlp->nlh; NLMSG_OK (nlh, size); nlh = NLMSG_NEXT (nlh, size))
|
||||||
|
{
|
||||||
|
/* Check if the message is what we want. */
|
||||||
|
if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (nlh->nlmsg_type == NLMSG_DONE)
|
||||||
|
break; /* ok */
|
||||||
|
|
||||||
|
if (nlh->nlmsg_type == RTM_NEWLINK)
|
||||||
|
{
|
||||||
|
struct ifinfomsg *ifim = (struct ifinfomsg *) NLMSG_DATA (nlh);
|
||||||
|
struct rtattr *rta = IFLA_RTA (ifim);
|
||||||
|
size_t rtasize = IFLA_PAYLOAD (nlh);
|
||||||
|
|
||||||
|
idx[nifs].if_index = ifim->ifi_index;
|
||||||
|
|
||||||
|
while (RTA_OK (rta, rtasize))
|
||||||
|
{
|
||||||
|
char *rta_data = RTA_DATA (rta);
|
||||||
|
size_t rta_payload = RTA_PAYLOAD (rta);
|
||||||
|
|
||||||
|
if (rta->rta_type == IFLA_IFNAME)
|
||||||
|
{
|
||||||
|
idx[nifs].if_name = __strndup (rta_data, rta_payload);
|
||||||
|
if (idx[nifs].if_name == NULL)
|
||||||
|
{
|
||||||
|
idx[nifs].if_index = 0;
|
||||||
|
if_freenameindex (idx);
|
||||||
|
idx = NULL;
|
||||||
|
goto nomem;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rta = RTA_NEXT (rta, rtasize);
|
||||||
|
}
|
||||||
|
|
||||||
|
++nifs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
idx[nifs].if_index = 0;
|
||||||
|
idx[nifs].if_name = NULL;
|
||||||
|
|
||||||
|
exit_free:
|
||||||
|
__netlink_free_handle (&nh);
|
||||||
|
exit_close:
|
||||||
|
__netlink_close (&nh);
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct if_nameindex *
|
||||||
|
if_nameindex (void)
|
||||||
|
{
|
||||||
|
#ifndef SIOCGIFINDEX
|
||||||
|
__set_errno (ENOSYS);
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
|
struct if_nameindex *result = if_nameindex_netlink ();
|
||||||
|
# if __ASSUME_NETLINK_SUPPORT == 0
|
||||||
|
if (__no_netlink_support)
|
||||||
|
result = if_nameindex_ioctl ();
|
||||||
|
# endif
|
||||||
|
return result;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
libc_hidden_def (if_nameindex)
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
if_indextoname (unsigned int ifindex, char *ifname)
|
if_indextoname (unsigned int ifindex, char *ifname)
|
||||||
@ -263,6 +401,7 @@ if_indextoname (unsigned int ifindex, char *ifname)
|
|||||||
}
|
}
|
||||||
libc_hidden_def (if_indextoname)
|
libc_hidden_def (if_indextoname)
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
void
|
void
|
||||||
internal_function
|
internal_function
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* getifaddrs -- get names and addresses of all network interfaces
|
/* getifaddrs -- get names and addresses of all network interfaces
|
||||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -32,11 +32,8 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include "netlinkaccess.h"
|
||||||
#include <linux/netlink.h>
|
|
||||||
#include <linux/rtnetlink.h>
|
|
||||||
|
|
||||||
#include "kernel-features.h"
|
|
||||||
|
|
||||||
/* We don't know if we have NETLINK support compiled in in our
|
/* We don't know if we have NETLINK support compiled in in our
|
||||||
Kernel, so include the old implementation as fallback. */
|
Kernel, so include the old implementation as fallback. */
|
||||||
@ -46,33 +43,9 @@ int __no_netlink_support attribute_hidden;
|
|||||||
# define getifaddrs fallback_getifaddrs
|
# define getifaddrs fallback_getifaddrs
|
||||||
# include "sysdeps/gnu/ifaddrs.c"
|
# include "sysdeps/gnu/ifaddrs.c"
|
||||||
# undef getifaddrs
|
# undef getifaddrs
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
# define __no_netlink_support 0
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct netlink_res
|
|
||||||
{
|
|
||||||
struct netlink_res *next;
|
|
||||||
struct nlmsghdr *nlh;
|
|
||||||
size_t size; /* Size of response. */
|
|
||||||
uint32_t seq; /* sequential number we used. */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct netlink_handle
|
|
||||||
{
|
|
||||||
int fd; /* Netlink file descriptor. */
|
|
||||||
pid_t pid; /* Process ID. */
|
|
||||||
uint32_t seq; /* The sequence number we use currently. */
|
|
||||||
struct netlink_res *nlm_list; /* Pointer to list of responses. */
|
|
||||||
struct netlink_res *end_ptr; /* For faster append of new entries. */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* struct to hold the data for one ifaddrs entry, so we can allocate
|
/* struct to hold the data for one ifaddrs entry, so we can allocate
|
||||||
everything at once. */
|
everything at once. */
|
||||||
struct ifaddrs_storage
|
struct ifaddrs_storage
|
||||||
@ -91,8 +64,8 @@ struct ifaddrs_storage
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
free_netlink_handle (struct netlink_handle *h)
|
__netlink_free_handle (struct netlink_handle *h)
|
||||||
{
|
{
|
||||||
struct netlink_res *ptr;
|
struct netlink_res *ptr;
|
||||||
int saved_errno = errno;
|
int saved_errno = errno;
|
||||||
@ -107,12 +80,12 @@ free_netlink_handle (struct netlink_handle *h)
|
|||||||
ptr = tmpptr;
|
ptr = tmpptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = saved_errno;
|
__set_errno (saved_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
int
|
||||||
netlink_sendreq (struct netlink_handle *h, int type)
|
__netlink_sendreq (struct netlink_handle *h, int type)
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -140,8 +113,8 @@ netlink_sendreq (struct netlink_handle *h, int type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
int
|
||||||
netlink_receive (struct netlink_handle *h)
|
__netlink_receive (struct netlink_handle *h)
|
||||||
{
|
{
|
||||||
struct netlink_res *nlm_next;
|
struct netlink_res *nlm_next;
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
@ -211,8 +184,8 @@ netlink_receive (struct netlink_handle *h)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
netlink_close (struct netlink_handle *h)
|
__netlink_close (struct netlink_handle *h)
|
||||||
{
|
{
|
||||||
/* Don't modify errno. */
|
/* Don't modify errno. */
|
||||||
INTERNAL_SYSCALL_DECL (err);
|
INTERNAL_SYSCALL_DECL (err);
|
||||||
@ -221,21 +194,25 @@ netlink_close (struct netlink_handle *h)
|
|||||||
|
|
||||||
|
|
||||||
/* Open a NETLINK socket. */
|
/* Open a NETLINK socket. */
|
||||||
static int
|
int
|
||||||
netlink_open (struct netlink_handle *h)
|
__netlink_open (struct netlink_handle *h)
|
||||||
{
|
{
|
||||||
struct sockaddr_nl nladdr;
|
struct sockaddr_nl nladdr;
|
||||||
|
|
||||||
h->fd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
h->fd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||||
if (h->fd < 0)
|
if (h->fd < 0)
|
||||||
return -1;
|
goto out;
|
||||||
|
|
||||||
memset (&nladdr, '\0', sizeof (nladdr));
|
memset (&nladdr, '\0', sizeof (nladdr));
|
||||||
nladdr.nl_family = AF_NETLINK;
|
nladdr.nl_family = AF_NETLINK;
|
||||||
if (__bind (h->fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) < 0)
|
if (__bind (h->fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) < 0)
|
||||||
{
|
{
|
||||||
close_and_out:
|
close_and_out:
|
||||||
netlink_close (h);
|
__netlink_close (h);
|
||||||
|
out:
|
||||||
|
#if __ASSUME_NETLINK_SUPPORT == 0
|
||||||
|
__no_netlink_support = 1;
|
||||||
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* Determine the ID the kernel assigned for this netlink connection.
|
/* Determine the ID the kernel assigned for this netlink connection.
|
||||||
@ -298,11 +275,9 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
if (ifap)
|
if (ifap)
|
||||||
*ifap = NULL;
|
*ifap = NULL;
|
||||||
|
|
||||||
if (! __no_netlink_support && netlink_open (&nh) < 0)
|
if (! __no_netlink_support && __netlink_open (&nh) < 0)
|
||||||
{
|
{
|
||||||
#if __ASSUME_NETLINK_SUPPORT == 0
|
#if __ASSUME_NETLINK_SUPPORT != 0
|
||||||
__no_netlink_support = 1;
|
|
||||||
#else
|
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -314,13 +289,13 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
|
|
||||||
/* Tell the kernel that we wish to get a list of all
|
/* Tell the kernel that we wish to get a list of all
|
||||||
active interfaces. */
|
active interfaces. */
|
||||||
if (netlink_sendreq (&nh, RTM_GETLINK) < 0)
|
if (__netlink_sendreq (&nh, RTM_GETLINK) < 0)
|
||||||
{
|
{
|
||||||
result = -1;
|
result = -1;
|
||||||
goto exit_close;
|
goto exit_close;
|
||||||
}
|
}
|
||||||
/* Collect all data for every interface. */
|
/* Collect all data for every interface. */
|
||||||
if (netlink_receive (&nh) < 0)
|
if (__netlink_receive (&nh) < 0)
|
||||||
{
|
{
|
||||||
result = -1;
|
result = -1;
|
||||||
goto exit_free;
|
goto exit_free;
|
||||||
@ -332,9 +307,9 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
interfaces in the list, we will later always find the
|
interfaces in the list, we will later always find the
|
||||||
interface before the corresponding addresses. */
|
interface before the corresponding addresses. */
|
||||||
++nh.seq;
|
++nh.seq;
|
||||||
if (netlink_sendreq (&nh, RTM_GETADDR) < 0
|
if (__netlink_sendreq (&nh, RTM_GETADDR) < 0
|
||||||
/* Collect all data for every interface. */
|
/* Collect all data for every interface. */
|
||||||
|| netlink_receive (&nh) < 0)
|
|| __netlink_receive (&nh) < 0)
|
||||||
{
|
{
|
||||||
result = -1;
|
result = -1;
|
||||||
goto exit_free;
|
goto exit_free;
|
||||||
@ -355,7 +330,7 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
message type they contain. */
|
message type they contain. */
|
||||||
for (nlh = nlp->nlh; NLMSG_OK (nlh, size); nlh = NLMSG_NEXT (nlh, size))
|
for (nlh = nlp->nlh; NLMSG_OK (nlh, size); nlh = NLMSG_NEXT (nlh, size))
|
||||||
{
|
{
|
||||||
/* check if the message is what we want */
|
/* Check if the message is what we want. */
|
||||||
if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
|
if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -791,10 +766,10 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
*ifap = &ifas[0].ifa;
|
*ifap = &ifas[0].ifa;
|
||||||
|
|
||||||
exit_free:
|
exit_free:
|
||||||
free_netlink_handle (&nh);
|
__netlink_free_handle (&nh);
|
||||||
|
|
||||||
exit_close:
|
exit_close:
|
||||||
netlink_close (&nh);
|
__netlink_close (&nh);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
62
sysdeps/unix/sysv/linux/netlinkaccess.h
Normal file
62
sysdeps/unix/sysv/linux/netlinkaccess.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/* Copyright (C) 2004 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#ifndef _NETLINKACCESS_H
|
||||||
|
#define _NETLINKACCESS_H 1
|
||||||
|
|
||||||
|
#include <asm/types.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
|
#include <linux/rtnetlink.h>
|
||||||
|
|
||||||
|
#include "kernel-features.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct netlink_res
|
||||||
|
{
|
||||||
|
struct netlink_res *next;
|
||||||
|
struct nlmsghdr *nlh;
|
||||||
|
size_t size; /* Size of response. */
|
||||||
|
uint32_t seq; /* sequential number we used. */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct netlink_handle
|
||||||
|
{
|
||||||
|
int fd; /* Netlink file descriptor. */
|
||||||
|
pid_t pid; /* Process ID. */
|
||||||
|
uint32_t seq; /* The sequence number we use currently. */
|
||||||
|
struct netlink_res *nlm_list; /* Pointer to list of responses. */
|
||||||
|
struct netlink_res *end_ptr; /* For faster append of new entries. */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if __ASSUME_NETLINK_SUPPORT == 0
|
||||||
|
extern int __no_netlink_support attribute_hidden;
|
||||||
|
#else
|
||||||
|
# define __no_netlink_support 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
extern int __netlink_open (struct netlink_handle *h);
|
||||||
|
extern void __netlink_close (struct netlink_handle *h);
|
||||||
|
extern void __netlink_free_handle (struct netlink_handle *h);
|
||||||
|
extern int __netlink_sendreq (struct netlink_handle *h, int type);
|
||||||
|
extern int __netlink_receive (struct netlink_handle *h);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* netlinkaccess.h */
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 1997, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
|
/* Copyright (C) 1997-2000, 2003, 2004 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -65,7 +65,7 @@ truncate64 (const char *path, off64_t length)
|
|||||||
__set_errno (EINVAL);
|
__set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return truncate (path, (off_t) length);
|
return __truncate (path, (off_t) length);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user