1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-01 10:06:57 +03:00
2005-06-13  Ulrich Drepper  <drepper@redhat.com>
	* sysdeps/unix/clock_gettime.c (clock_gettime): Implement case
	where HANDLED_REALTIME is not defined.  [BZ #966]

2005-06-13  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/unix/sysv/linux/netlinkaccess.h (__netlink_sendreq,
	__netlink_receive): Remove prototypes.
	(__netlink_request): New prototype.
	* sysdeps/unix/sysv/linux/ifaddrs.c: Include <alloca.h> and
	<stdint.h>.
	(__netlink_sendreq): Make static.
	(__netlink_receive): Rename to...
	(__netlink_request): ... this.  Add type argument, call
	__netlink_sendreq.  If MSG_TRUNC is set after recvmsg, retry
	with a bigger buffer.  Don't record buffers that contain no
	messages we are expecting.
	(getifaddrs): Use __netlink_request instead of __netlink_sendreq
	and __netlink_receive pairs.  Formatting.
	* sysdeps/unix/sysv/linux/if_index.c (if_nameindex_netlink): Use
	__netlink_request instead of __netlink_sendreq and __netlink_receive
	pair.

2005-06-13  Thorsten Kukuk  <kukuk@suse.de>

	* sysdeps/unix/sysv/linux/netinet/if_tr.h: Don't include kernel
	headers, instead copy important structs/defines.

2005-06-13  Jakub Jelinek  <jakub@redhat.com>

	* elf/rtld.c (dl_main): Move DT_DEBUG setup before first
	_dl_debug_state call.
This commit is contained in:
Ulrich Drepper
2005-06-14 00:56:49 +00:00
parent 74780cf659
commit c63d8f809b
7 changed files with 259 additions and 88 deletions

View File

@ -1,5 +1,5 @@
/* getifaddrs -- get names and addresses of all network interfaces
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
Copyright (C) 2003, 2004, 2005 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
@ -17,6 +17,7 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <alloca.h>
#include <assert.h>
#include <errno.h>
#include <ifaddrs.h>
@ -24,6 +25,7 @@
#include <netinet/in.h>
#include <netpacket/packet.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
@ -84,7 +86,7 @@ __netlink_free_handle (struct netlink_handle *h)
}
int
static int
__netlink_sendreq (struct netlink_handle *h, int type)
{
struct
@ -114,15 +116,39 @@ __netlink_sendreq (struct netlink_handle *h, int type)
int
__netlink_receive (struct netlink_handle *h)
__netlink_request (struct netlink_handle *h, int type)
{
struct netlink_res *nlm_next;
char buf[4096];
struct iovec iov = { buf, sizeof (buf) };
struct netlink_res **new_nlm_list;
static volatile size_t buf_size = 4096;
char *buf;
struct sockaddr_nl nladdr;
struct nlmsghdr *nlmh;
int read_len;
ssize_t read_len;
bool done = false;
bool use_malloc = false;
if (__netlink_sendreq (h, type) < 0)
return -1;
size_t this_buf_size = buf_size;
if (__libc_use_alloca (this_buf_size))
buf = alloca (this_buf_size);
else
{
buf = malloc (this_buf_size);
if (buf != NULL)
use_malloc = true;
else
goto out_fail;
}
struct iovec iov = { buf, this_buf_size };
if (h->nlm_list != NULL)
new_nlm_list = &h->end_ptr->next;
else
new_nlm_list = &h->nlm_list;
while (! done)
{
@ -136,33 +162,66 @@ __netlink_receive (struct netlink_handle *h)
read_len = TEMP_FAILURE_RETRY (__recvmsg (h->fd, &msg, 0));
if (read_len < 0)
return -1;
goto out_fail;
if (msg.msg_flags & MSG_TRUNC)
return -1;
if (nladdr.nl_pid != 0)
continue;
nlm_next = (struct netlink_res *) malloc (sizeof (struct netlink_res)
+ read_len);
if (nlm_next == NULL)
return -1;
nlm_next->next = NULL;
nlm_next->nlh = memcpy (nlm_next + 1, buf, read_len);
nlm_next->size = read_len;
nlm_next->seq = h->seq;
if (h->nlm_list == NULL)
h->nlm_list = nlm_next;
else
h->end_ptr->next = nlm_next;
h->end_ptr = nlm_next;
for (nlmh = (struct nlmsghdr *) buf;
NLMSG_OK (nlmh, (size_t) read_len);
nlmh = (struct nlmsghdr *) NLMSG_NEXT (nlmh, read_len))
if (__builtin_expect (msg.msg_flags & MSG_TRUNC, 0))
{
if (nladdr.nl_pid != 0 || (pid_t) nlmh->nlmsg_pid != h->pid
if (this_buf_size >= SIZE_MAX / 2)
goto out_fail;
nlm_next = *new_nlm_list;
while (nlm_next != NULL)
{
struct netlink_res *tmpptr;
tmpptr = nlm_next->next;
free (nlm_next);
nlm_next = tmpptr;
}
*new_nlm_list = NULL;
if (__libc_use_alloca (2 * this_buf_size))
buf = extend_alloca (buf, this_buf_size, 2 * this_buf_size);
else
{
this_buf_size *= 2;
char *new_buf = realloc (use_malloc ? buf : NULL, this_buf_size);
if (new_buf == NULL)
goto out_fail;
new_buf = buf;
use_malloc = true;
}
buf_size = this_buf_size;
iov.iov_base = buf;
iov.iov_len = this_buf_size;
/* Increase sequence number, so that we can distinguish
between old and new request messages. */
h->seq++;
if (__netlink_sendreq (h, type) < 0)
goto out_fail;
continue;
}
size_t count = 0;
size_t remaining_len = read_len;
for (nlmh = (struct nlmsghdr *) buf;
NLMSG_OK (nlmh, remaining_len);
nlmh = (struct nlmsghdr *) NLMSG_NEXT (nlmh, remaining_len))
{
if ((pid_t) nlmh->nlmsg_pid != h->pid
|| nlmh->nlmsg_seq != h->seq)
continue;
++count;
if (nlmh->nlmsg_type == NLMSG_DONE)
{
/* We found the end, leave the loop. */
@ -176,11 +235,38 @@ __netlink_receive (struct netlink_handle *h)
errno = EIO;
else
errno = -nlerr->error;
return -1;
goto out_fail;
}
}
/* If there was nothing with the expected nlmsg_pid and nlmsg_seq,
there is no point to record it. */
if (count == 0)
continue;
nlm_next = (struct netlink_res *) malloc (sizeof (struct netlink_res)
+ read_len);
if (nlm_next == NULL)
goto out_fail;
nlm_next->next = NULL;
nlm_next->nlh = memcpy (nlm_next + 1, buf, read_len);
nlm_next->size = read_len;
nlm_next->seq = h->seq;
if (h->nlm_list == NULL)
h->nlm_list = nlm_next;
else
h->end_ptr->next = nlm_next;
h->end_ptr = nlm_next;
}
if (use_malloc)
free (buf);
return 0;
out_fail:
if (use_malloc)
free (buf);
return -1;
}
@ -268,7 +354,7 @@ getifaddrs (struct ifaddrs **ifap)
unsigned int i, newlink, newaddr, newaddr_idx;
int *map_newlink_data;
size_t ifa_data_size = 0; /* Size to allocate for all ifa_data. */
char *ifa_data_ptr; /* Pointer to the unused part of memory for
char *ifa_data_ptr; /* Pointer to the unused part of memory for
ifa_data. */
int result = 0;
@ -288,28 +374,20 @@ getifaddrs (struct ifaddrs **ifap)
#endif
/* Tell the kernel that we wish to get a list of all
active interfaces. */
if (__netlink_sendreq (&nh, RTM_GETLINK) < 0)
{
result = -1;
goto exit_close;
}
/* Collect all data for every interface. */
if (__netlink_receive (&nh) < 0)
active interfaces, collect all data for every interface. */
if (__netlink_request (&nh, RTM_GETLINK) < 0)
{
result = -1;
goto exit_free;
}
/* Now ask the kernel for all addresses which are assigned
to an interface. Since we store the addresses after the
interfaces in the list, we will later always find the
interface before the corresponding addresses. */
to an interface and collect all data for every interface.
Since we store the addresses after the interfaces in the
list, we will later always find the interface before the
corresponding addresses. */
++nh.seq;
if (__netlink_sendreq (&nh, RTM_GETADDR) < 0
/* Collect all data for every interface. */
|| __netlink_receive (&nh) < 0)
if (__netlink_request (&nh, RTM_GETADDR) < 0)
{
result = -1;
goto exit_free;
@ -327,7 +405,7 @@ getifaddrs (struct ifaddrs **ifap)
continue;
/* Walk through all entries we got from the kernel and look, which
message type they contain. */
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. */
@ -423,7 +501,7 @@ getifaddrs (struct ifaddrs **ifap)
/* Interfaces are stored in the first "newlink" entries
of our list, starting in the order as we got from the
kernel. */
ifa_index = map_newlink (ifim->ifi_index - 1, ifas,
ifa_index = map_newlink (ifim->ifi_index - 1, ifas,
map_newlink_data, newlink);
ifas[ifa_index].ifa.ifa_flags = ifim->ifi_flags;
@ -767,8 +845,6 @@ getifaddrs (struct ifaddrs **ifap)
exit_free:
__netlink_free_handle (&nh);
exit_close:
__netlink_close (&nh);
return result;