about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-07-12 15:12:29 +0000
committerJakub Jelinek <jakub@redhat.com>2007-07-12 15:12:29 +0000
commite046ba1d02eeb862753adc01fcacfc072ddf0a44 (patch)
tree64e21e2ff70ed709b5ae2d6b40d0f06aedf31ec2
parentbdaa36ac5f0b620fbf2be08df8af7d85f055c17c (diff)
downloadglibc-e046ba1d02eeb862753adc01fcacfc072ddf0a44.tar.gz
glibc-e046ba1d02eeb862753adc01fcacfc072ddf0a44.tar.xz
glibc-e046ba1d02eeb862753adc01fcacfc072ddf0a44.zip
2007-04-25 Jakub Jelinek <jakub@redhat.com>
	* sysdeps/unix/sysv/linux/check_pf.c (make_request): Return -1 instead
	of 0 after the out_fail label.

2007-03-18  Jakub Jelinek  <jakub@redhat.com>

	* nscd/gai.c: Include alloca.h.
	(__libc_use_alloca): Define.

2007-03-15  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/unix/sysv/linux/ifaddrs.c (__netlink_request): Never
	reallocate the buffer, instead fail for MSG_TRUNC or for EBUSY
	NLMSG_ERR.  Instead use a page sized buffer.
	* sysdeps/unix/sysv/linux/check_pf.c (make_request): Use page sized
	buffer.

2007-03-02  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/unix/sysv/linux/ifaddrs.c (__netlink_request): Retry with
	a new netlink socket if NLMSG_ERR -EBUSY is seen after some MSG_TRUNC
	message.

2007-02-27  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/unix/sysv/linux/ifaddrs.c (__netlink_request): Fix
	memory reallocation.
-rw-r--r--ChangeLog29
-rw-r--r--nscd/gai.c3
-rw-r--r--sysdeps/unix/sysv/linux/check_pf.c40
-rw-r--r--sysdeps/unix/sysv/linux/ifaddrs.c73
4 files changed, 82 insertions, 63 deletions
diff --git a/ChangeLog b/ChangeLog
index 02b50e6bf9..35781a7eb5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,34 @@
 2007-04-25  Jakub Jelinek  <jakub@redhat.com>
 
+	* sysdeps/unix/sysv/linux/check_pf.c (make_request): Return -1 instead
+	of 0 after the out_fail label.
+
+2007-03-18  Jakub Jelinek  <jakub@redhat.com>
+
+	* nscd/gai.c: Include alloca.h.
+	(__libc_use_alloca): Define.
+
+2007-03-15  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/ifaddrs.c (__netlink_request): Never
+	reallocate the buffer, instead fail for MSG_TRUNC or for EBUSY
+	NLMSG_ERR.  Instead use a page sized buffer.
+	* sysdeps/unix/sysv/linux/check_pf.c (make_request): Use page sized
+	buffer.
+
+2007-03-02  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/ifaddrs.c (__netlink_request): Retry with
+	a new netlink socket if NLMSG_ERR -EBUSY is seen after some MSG_TRUNC
+	message.
+
+2007-02-27  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/ifaddrs.c (__netlink_request): Fix
+	memory reallocation.
+
+2007-04-25  Jakub Jelinek  <jakub@redhat.com>
+
 	* libio/bits/stdio.h (fgetc_unlocked): Add extern inline optimized
 	version.
 
diff --git a/nscd/gai.c b/nscd/gai.c
index 2e706bdfe7..652a1885c9 100644
--- a/nscd/gai.c
+++ b/nscd/gai.c
@@ -15,6 +15,7 @@
    along with this program; if not, write to the Free Software Foundation,
    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
+#include <alloca.h>
 /* This file uses the getaddrinfo code but it compiles it without NSCD
    support.  We just need a few symbol renames.  */
 #define __getservbyname_r getservbyname_r
@@ -26,6 +27,8 @@
 #define __sendto sendto
 #define __strchrnul strchrnul
 #define __getline getline
+/* nscd uses 1MB or 2MB thread stacks.  */
+#define __libc_use_alloca(size) (size <= __MAX_ALLOCA_CUTOFF)
 
 #include <getaddrinfo.c>
 
diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c
index 13ccd7acb4..2683d108f3 100644
--- a/sysdeps/unix/sysv/linux/check_pf.c
+++ b/sysdeps/unix/sysv/linux/check_pf.c
@@ -71,17 +71,38 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
   memset (&nladdr, '\0', sizeof (nladdr));
   nladdr.nl_family = AF_NETLINK;
 
+#ifdef PAGE_SIZE
+  /* Help the compiler optimize out the malloc call if PAGE_SIZE
+     is constant and smaller or equal to PTHREAD_STACK_MIN/4.  */
+  const size_t buf_size = PAGE_SIZE;
+#else
+  const size_t buf_size = __getpagesize ();
+#endif
+  bool use_malloc = false;
+  char *buf;
+
+  if (__libc_use_alloca (buf_size))
+    buf = alloca (buf_size);
+  else
+    {
+      buf = malloc (buf_size);
+      if (buf != NULL)
+	use_malloc = true;
+      else
+	goto out_fail;
+    }
+
+  struct iovec iov = { buf, buf_size };
+
   if (TEMP_FAILURE_RETRY (__sendto (fd, (void *) &req, sizeof (req), 0,
 				    (struct sockaddr *) &nladdr,
 				    sizeof (nladdr))) < 0)
-    return -1;
+    goto out_fail;
 
   *seen_ipv4 = false;
   *seen_ipv6 = false;
 
   bool done = false;
-  char buf[4096];
-  struct iovec iov = { buf, sizeof (buf) };
   struct in6ailist
   {
     struct in6addrinfo info;
@@ -101,10 +122,10 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
 
       ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0));
       if (read_len < 0)
-	return -1;
+	goto out_fail;
 
       if (msg.msg_flags & MSG_TRUNC)
-	return -1;
+	goto out_fail;
 
       struct nlmsghdr *nlmh;
       for (nlmh = (struct nlmsghdr *) buf;
@@ -186,7 +207,7 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
     {
       *in6ai = malloc (in6ailistlen * sizeof (**in6ai));
       if (*in6ai == NULL)
-	return -1;
+	goto out_fail;
 
       *in6ailen = in6ailistlen;
 
@@ -198,7 +219,14 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
       while (in6ailist != NULL);
     }
 
+  if (use_malloc)
+    free (buf);
   return 0;
+
+out_fail:
+  if (use_malloc)
+    free (buf);
+  return -1;
 }
 
 
diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c
index 82495de03e..5196adcdfe 100644
--- a/sysdeps/unix/sysv/linux/ifaddrs.c
+++ b/sysdeps/unix/sysv/linux/ifaddrs.c
@@ -122,36 +122,36 @@ int
 __netlink_request (struct netlink_handle *h, int type)
 {
   struct netlink_res *nlm_next;
-  struct netlink_res **new_nlm_list;
-  static volatile size_t buf_size = 4096;
-  char *buf;
   struct sockaddr_nl nladdr;
   struct nlmsghdr *nlmh;
   ssize_t read_len;
   bool done = false;
-  bool use_malloc = false;
 
-  if (__netlink_sendreq (h, type) < 0)
-    return -1;
+#ifdef PAGE_SIZE
+  /* Help the compiler optimize out the malloc call if PAGE_SIZE
+     is constant and smaller or equal to PTHREAD_STACK_MIN/4.  */
+  const size_t buf_size = PAGE_SIZE;
+#else
+  const size_t buf_size = __getpagesize ();
+#endif
+  bool use_malloc = false;
+  char *buf;
 
-  size_t this_buf_size = buf_size;
-  if (__libc_use_alloca (this_buf_size))
-    buf = alloca (this_buf_size);
+  if (__libc_use_alloca (buf_size))
+    buf = alloca (buf_size);
   else
     {
-      buf = malloc (this_buf_size);
+      buf = malloc (buf_size);
       if (buf != NULL)
 	use_malloc = true;
       else
 	goto out_fail;
     }
 
-  struct iovec iov = { buf, this_buf_size };
+  struct iovec iov = { buf, buf_size };
 
-  if (h->nlm_list != NULL)
-    new_nlm_list = &h->end_ptr->next;
-  else
-    new_nlm_list = &h->nlm_list;
+  if (__netlink_sendreq (h, type) < 0)
+    goto out_fail;
 
   while (! done)
     {
@@ -171,48 +171,7 @@ __netlink_request (struct netlink_handle *h, int type)
 	continue;
 
       if (__builtin_expect (msg.msg_flags & MSG_TRUNC, 0))
-	{
-	  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;
-	}
+	goto out_fail;
 
       size_t count = 0;
       size_t remaining_len = read_len;