[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[commits] r3799 - in /fsf/trunk/libc: ./ intl/ libio/ nscd/ time/
- To: commits@xxxxxxxxxx
- Subject: [commits] r3799 - in /fsf/trunk/libc: ./ intl/ libio/ nscd/ time/
- From: eglibc@xxxxxxxxxx
- Date: Sun, 14 Oct 2007 07:03:35 -0000
Author: eglibc
Date: Sun Oct 14 00:03:34 2007
New Revision: 3799
Log:
Import glibc-mainline for 2007-10-14
Added:
fsf/trunk/libc/libio/tst-ext2.c
Modified:
fsf/trunk/libc/ChangeLog
fsf/trunk/libc/intl/dcigettext.c
fsf/trunk/libc/libio/Makefile
fsf/trunk/libc/libio/__freading.c
fsf/trunk/libc/nscd/nscd_getai.c
fsf/trunk/libc/nscd/nscd_getgr_r.c
fsf/trunk/libc/nscd/nscd_gethst_r.c
fsf/trunk/libc/nscd/nscd_getpw_r.c
fsf/trunk/libc/nscd/nscd_getserv_r.c
fsf/trunk/libc/nscd/nscd_helper.c
fsf/trunk/libc/time/tzfile.c
Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Sun Oct 14 00:03:34 2007
@@ -1,3 +1,46 @@
+2007-10-14 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ [BZ #1140]
+ * time/tzfile.c (__tzfile_compute): Compute tzname[] values based
+ on the specified time and not the last entries in the file. Move
+ code to determine tzname[] to...
+ (find_transition): ...here. Add ugly guess for times before the
+ first transition.
+
+2007-10-13 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ [BZ #3195]
+ * nscd/nscd_getai.c (__nscd_getai): Set errno to 0 in case we found
+ no entry.
+ * nscd/nscd_getgr.c (nscd_getgr_r): Likewise.
+ * nscd/nscd_gethst_r.c (nscd_gethst_r): Likewise.
+ * nscd/nscd_getpw_r.c (nscd_getpw_r): Likewise.
+ * nscd/nscd_getserv_r.c (nscd_getserv_r): Likewise.
+
+ * nscd/nscd_getgr_r.c (nscd_getgr_r): Optimize a bit: use simpler
+ read mechanism when there are no group members and avoid no-op
+ read syscall in this case.
+
+ [BZ #3242]
+ * nscd/nscd_helper.c (wait_on_socket): Take timeout as parameter.
+ (__readall): If reading failed due to EAGAIN error wait a bit
+ and possibly try again.
+ (__readvall): Likewise.
+
+2007-10-13 Bruno Haible <bruno@xxxxxxxxx>
+
+ * intl/dcigettext.c (_nl_find_msg): Unlock the conversions_lock
+ when we cannot recode the message.
+
+2007-10-13 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ [BZ #4359]
+ * libio/__freading.c (__freading): Don't return true for
+ write-only streams. For read/write streams, check whether we
+ performed a read operation already.
+ * libio/Makefile (tests): Add tst-ext2.
+ * libio/tst-ext2.c: New file.
+
2007-10-12 Ulrich Drepper <drepper@xxxxxxxxxx>
* locale/programs/repertoire.c (repertoire_read): Always free
Modified: fsf/trunk/libc/intl/dcigettext.c
==============================================================================
--- fsf/trunk/libc/intl/dcigettext.c (original)
+++ fsf/trunk/libc/intl/dcigettext.c Sun Oct 14 00:03:34 2007
@@ -974,6 +974,7 @@
translation at all. */
if (__builtin_expect (r != __GCONV_NULCONV, 1))
{
+ __libc_rwlock_unlock (domain->conversions_lock);
free ((char *) encoding);
return NULL;
}
Modified: fsf/trunk/libc/libio/Makefile
==============================================================================
--- fsf/trunk/libc/libio/Makefile (original)
+++ fsf/trunk/libc/libio/Makefile Sun Oct 14 00:03:34 2007
@@ -1,4 +1,4 @@
-# Copyright (C) 1995-2002,2003,2004,2006 Free Software Foundation, Inc.
+# Copyright (C) 1995-2002,2003,2004,2006,2007 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
@@ -48,7 +48,7 @@
libc_fatal fmemopen
tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \
- tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-fopenloc \
+ tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-ext2 tst-fopenloc \
tst-fgetws tst-ungetwc1 tst-ungetwc2 tst-swscanf tst-sscanf \
tst-mmap-setvbuf bug-ungetwc1 bug-ungetwc2 tst-atime tst-eof \
tst-freopen bug-rewind bug-rewind2 bug-ungetc bug-fseek \
Modified: fsf/trunk/libc/libio/__freading.c
==============================================================================
--- fsf/trunk/libc/libio/__freading.c (original)
+++ fsf/trunk/libc/libio/__freading.c Sun Oct 14 00:03:34 2007
@@ -21,7 +21,7 @@
int
__freading (FILE *fp)
{
- return (((fp->_flags & _IO_NO_WRITES)
- || (fp->_flags & _IO_CURRENTLY_PUTTING) == 0)
- && (fp->_flags & _IO_NO_READS) == 0);
+ return ((fp->_flags & _IO_NO_WRITES)
+ || ((fp->_flags & (_IO_CURRENTLY_PUTTING | _IO_NO_READS)) == 0
+ && fp->_IO_read_base != NULL));
}
Added: fsf/trunk/libc/libio/tst-ext2.c
==============================================================================
--- fsf/trunk/libc/libio/tst-ext2.c (added)
+++ fsf/trunk/libc/libio/tst-ext2.c Sun Oct 14 00:03:34 2007
@@ -1,0 +1,58 @@
+#include <stdio.h>
+#include <stdio_ext.h>
+
+
+static char *fname;
+
+#define PREPARE(argc, argv) \
+ do { \
+ int fd = create_temp_file ("tst-ext2", &fname); \
+ if (fd == -1) \
+ { \
+ puts ("cannot create temporary file"); \
+ exit (1); \
+ } \
+ close (fd); \
+ } while (0)
+
+
+static int
+do_test (void)
+{
+ int res = 0;
+
+ FILE *fp;
+
+ fp = fopen (fname, "w");
+ printf ("Initial state for write-only stream: %d %d\n",
+ __freading (fp) != 0, __fwriting (fp) != 0);
+ res |= ((__freading (fp) != 0) != 0
+ || (__fwriting (fp) != 0) != 1);
+ fclose (fp);
+
+ fp = fopen (fname, "r");
+ printf ("Initial state for read-only stream: %d %d\n",
+ __freading (fp) != 0, __fwriting (fp) != 0);
+ res |= ((__freading (fp) != 0) != 1
+ || (__fwriting (fp) != 0) != 0);
+ fclose (fp);
+
+ fp = fopen (fname, "r+");
+ printf ("Initial state for read-write stream: %d %d\n",
+ __freading (fp) != 0, __fwriting (fp) != 0);
+ res |= ((__freading (fp) != 0) != 0
+ || (__fwriting (fp) != 0) != 0);
+ fclose (fp);
+
+ fp = fopen (fname, "w+");
+ printf ("Initial state for read-write stream: %d %d\n",
+ __freading (fp) != 0, __fwriting (fp) != 0);
+ res |= ((__freading (fp) != 0) != 0
+ || (__fwriting (fp) != 0) != 0);
+ fclose (fp);
+
+ return res;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
Modified: fsf/trunk/libc/nscd/nscd_getai.c
==============================================================================
--- fsf/trunk/libc/nscd/nscd_getai.c (original)
+++ fsf/trunk/libc/nscd/nscd_getai.c Sun Oct 14 00:03:34 2007
@@ -168,8 +168,8 @@
/* Store the error number. */
*h_errnop = ai_resp.error;
- /* The `errno' to some value != ERANGE. */
- __set_errno (ENOENT);
+ /* Set errno to 0 to indicate no error, just no found record. */
+ __set_errno (0);
/* Even though we have not found anything, the result is zero. */
retval = 0;
}
Modified: fsf/trunk/libc/nscd/nscd_getgr_r.c
==============================================================================
--- fsf/trunk/libc/nscd/nscd_getgr_r.c (original)
+++ fsf/trunk/libc/nscd/nscd_getgr_r.c Sun Oct 14 00:03:34 2007
@@ -190,26 +190,37 @@
/* Read the length information, group name, and password. */
if (gr_name == NULL)
{
- /* Allocate array to store lengths. */
- if (lensize == 0)
- {
- lensize = gr_resp.gr_mem_cnt * sizeof (uint32_t);
- len = (uint32_t *) alloca (lensize);
- }
- else if (gr_resp.gr_mem_cnt * sizeof (uint32_t) > lensize)
- len = extend_alloca (len, lensize,
- gr_resp.gr_mem_cnt * sizeof (uint32_t));
-
- vec[0].iov_base = (void *) len;
- vec[0].iov_len = gr_resp.gr_mem_cnt * sizeof (uint32_t);
- vec[1].iov_base = resultbuf->gr_name;
- vec[1].iov_len = gr_resp.gr_name_len + gr_resp.gr_passwd_len;
- total_len = vec[0].iov_len + vec[1].iov_len;
-
- /* Get this data. */
- size_t n = __readvall (sock, vec, 2);
- if (__builtin_expect (n != total_len, 0))
- goto out_close;
+ /* Handle a simple, usual case: no group members. */
+ if (__builtin_expect (gr_resp.gr_mem_cnt == 0, 1))
+ {
+ size_t n = gr_resp.gr_name_len + gr_resp.gr_passwd_len;
+ if (__builtin_expect (__readall (sock, resultbuf->gr_name, n)
+ != (ssize_t) n, 0))
+ goto out_close;
+ }
+ else
+ {
+ /* Allocate array to store lengths. */
+ if (lensize == 0)
+ {
+ lensize = gr_resp.gr_mem_cnt * sizeof (uint32_t);
+ len = (uint32_t *) alloca (lensize);
+ }
+ else if (gr_resp.gr_mem_cnt * sizeof (uint32_t) > lensize)
+ len = extend_alloca (len, lensize,
+ gr_resp.gr_mem_cnt * sizeof (uint32_t));
+
+ vec[0].iov_base = (void *) len;
+ vec[0].iov_len = gr_resp.gr_mem_cnt * sizeof (uint32_t);
+ vec[1].iov_base = resultbuf->gr_name;
+ vec[1].iov_len = gr_resp.gr_name_len + gr_resp.gr_passwd_len;
+ total_len = vec[0].iov_len + vec[1].iov_len;
+
+ /* Get this data. */
+ size_t n = __readvall (sock, vec, 2);
+ if (__builtin_expect (n != total_len, 0))
+ goto out_close;
+ }
}
else
/* We already have the data. Just copy the group name and
@@ -251,43 +262,48 @@
}
retval = 0;
- if (gr_name == NULL)
- {
- size_t n = __readall (sock, resultbuf->gr_mem[0], total_len);
- if (__builtin_expect (n != total_len, 0))
- {
- /* The `errno' to some value != ERANGE. */
- __set_errno (ENOENT);
- retval = ENOENT;
+
+ /* If there are no group members TOTAL_LEN is zero. */
+ if (total_len > 0)
+ {
+ if (gr_name == NULL)
+ {
+ size_t n = __readall (sock, resultbuf->gr_mem[0], total_len);
+ if (__builtin_expect (n != total_len, 0))
+ {
+ /* The `errno' to some value != ERANGE. */
+ __set_errno (ENOENT);
+ retval = ENOENT;
+ }
+ else
+ *result = resultbuf;
}
else
- *result = resultbuf;
- }
- else
- {
- /* Copy the group member names. */
- memcpy (resultbuf->gr_mem[0], gr_name + gr_name_len, total_len);
-
- /* Try to detect corrupt databases. */
- if (resultbuf->gr_name[gr_name_len - 1] != '\0'
- || resultbuf->gr_passwd[gr_resp.gr_passwd_len - 1] != '\0'
- || ({for (cnt = 0; cnt < gr_resp.gr_mem_cnt; ++cnt)
- if (resultbuf->gr_mem[cnt][len[cnt] - 1] != '\0')
- break;
- cnt < gr_resp.gr_mem_cnt; }))
- {
- /* We cannot use the database. */
- retval = mapped->head->gc_cycle != gc_cycle ? -2 : -1;
- goto out_close;
- }
-
- *result = resultbuf;
+ {
+ /* Copy the group member names. */
+ memcpy (resultbuf->gr_mem[0], gr_name + gr_name_len, total_len);
+
+ /* Try to detect corrupt databases. */
+ if (resultbuf->gr_name[gr_name_len - 1] != '\0'
+ || resultbuf->gr_passwd[gr_resp.gr_passwd_len - 1] != '\0'
+ || ({for (cnt = 0; cnt < gr_resp.gr_mem_cnt; ++cnt)
+ if (resultbuf->gr_mem[cnt][len[cnt] - 1] != '\0')
+ break;
+ cnt < gr_resp.gr_mem_cnt; }))
+ {
+ /* We cannot use the database. */
+ retval = mapped->head->gc_cycle != gc_cycle ? -2 : -1;
+ goto out_close;
+ }
+
+ *result = resultbuf;
+ }
}
}
else
{
- /* The `errno' to some value != ERANGE. */
- __set_errno (ENOENT);
+ /* Set errno to 0 to indicate no error, just no found record. */
+ __set_errno (0);
/* Even though we have not found anything, the result is zero. */
retval = 0;
}
Modified: fsf/trunk/libc/nscd/nscd_gethst_r.c
==============================================================================
--- fsf/trunk/libc/nscd/nscd_gethst_r.c (original)
+++ fsf/trunk/libc/nscd/nscd_gethst_r.c Sun Oct 14 00:03:34 2007
@@ -379,8 +379,8 @@
/* Store the error number. */
*h_errnop = hst_resp.error;
- /* The `errno' to some value != ERANGE. */
- __set_errno (ENOENT);
+ /* Set errno to 0 to indicate no error, just no found record. */
+ __set_errno (0);
/* Even though we have not found anything, the result is zero. */
retval = 0;
}
Modified: fsf/trunk/libc/nscd/nscd_getpw_r.c
==============================================================================
--- fsf/trunk/libc/nscd/nscd_getpw_r.c (original)
+++ fsf/trunk/libc/nscd/nscd_getpw_r.c Sun Oct 14 00:03:34 2007
@@ -211,8 +211,8 @@
}
else
{
- /* The `errno' to some value != ERANGE. */
- __set_errno (ENOENT);
+ /* Set errno to 0 to indicate no error, just no found record. */
+ __set_errno (0);
/* Even though we have not found anything, the result is zero. */
retval = 0;
}
Modified: fsf/trunk/libc/nscd/nscd_getserv_r.c
==============================================================================
--- fsf/trunk/libc/nscd/nscd_getserv_r.c (original)
+++ fsf/trunk/libc/nscd/nscd_getserv_r.c Sun Oct 14 00:03:34 2007
@@ -301,8 +301,8 @@
}
else
{
- /* The `errno' to some value != ERANGE. */
- __set_errno (ENOENT);
+ /* Set errno to 0 to indicate no error, just no found record. */
+ __set_errno (0);
/* Even though we have not found anything, the result is zero. */
retval = 0;
}
Modified: fsf/trunk/libc/nscd/nscd_helper.c
==============================================================================
--- fsf/trunk/libc/nscd/nscd_helper.c (original)
+++ fsf/trunk/libc/nscd/nscd_helper.c Sun Oct 14 00:03:34 2007
@@ -38,6 +38,45 @@
#include "nscd-client.h"
+/* Extra time we wait if the socket is still receiving data. This
+ value is in milliseconds. Note that the other side is nscd on the
+ local machine and it is already transmitting data. So the wait
+ time need not be long. */
+#define EXTRA_RECEIVE_TIME 200
+
+
+static int
+wait_on_socket (int sock, long int usectmo)
+{
+ struct pollfd fds[1];
+ fds[0].fd = sock;
+ fds[0].events = POLLIN | POLLERR | POLLHUP;
+ int n = __poll (fds, 1, usectmo);
+ if (n == -1 && __builtin_expect (errno == EINTR, 0))
+ {
+ /* Handle the case where the poll() call is interrupted by a
+ signal. We cannot just use TEMP_FAILURE_RETRY since it might
+ lead to infinite loops. */
+ struct timeval now;
+ (void) __gettimeofday (&now, NULL);
+ long int end = now.tv_sec * 1000 + usectmo + (now.tv_usec + 500) / 1000;
+ long int timeout = usectmo;
+ while (1)
+ {
+ n = __poll (fds, 1, timeout);
+ if (n != -1 || errno != EINTR)
+ break;
+
+ /* Recompute the timeout time. */
+ (void) __gettimeofday (&now, NULL);
+ timeout = end - (now.tv_sec * 1000 + (now.tv_usec + 500) / 1000);
+ }
+ }
+
+ return n;
+}
+
+
ssize_t
__readall (int fd, void *buf, size_t len)
{
@@ -45,9 +84,17 @@
ssize_t ret;
do
{
+ again:
ret = TEMP_FAILURE_RETRY (__read (fd, buf, n));
if (ret <= 0)
- break;
+ {
+ if (__builtin_expect (ret < 0 && errno == EAGAIN, 0)
+ /* The socket is still receiving data. Wait a bit more. */
+ && wait_on_socket (fd, EXTRA_RECEIVE_TIME) > 0)
+ goto again;
+
+ break;
+ }
buf = (char *) buf + ret;
n -= ret;
}
@@ -61,7 +108,15 @@
{
ssize_t ret = TEMP_FAILURE_RETRY (__readv (fd, iov, iovcnt));
if (ret <= 0)
- return ret;
+ {
+ if (__builtin_expect (ret == 0 || errno != EAGAIN, 1))
+ /* A genuine error or no data to read. */
+ return ret;
+
+ /* The data has not all yet been received. Do as if we have not
+ read anything yet. */
+ ret = 0;
+ }
size_t total = 0;
for (int i = 0; i < iovcnt; ++i)
@@ -83,9 +138,17 @@
}
iovp->iov_base = (char *) iovp->iov_base + r;
iovp->iov_len -= r;
+ again:
r = TEMP_FAILURE_RETRY (__readv (fd, iovp, iovcnt));
if (r <= 0)
- break;
+ {
+ if (__builtin_expect (r < 0 && errno == EAGAIN, 0)
+ /* The socket is still receiving data. Wait a bit more. */
+ && wait_on_socket (fd, EXTRA_RECEIVE_TIME) > 0)
+ goto again;
+
+ break;
+ }
ret += r;
}
while (ret < total);
@@ -187,36 +250,6 @@
}
-static int
-wait_on_socket (int sock)
-{
- struct pollfd fds[1];
- fds[0].fd = sock;
- fds[0].events = POLLIN | POLLERR | POLLHUP;
- int n = __poll (fds, 1, 5 * 1000);
- if (n == -1 && __builtin_expect (errno == EINTR, 0))
- {
- /* Handle the case where the poll() call is interrupted by a
- signal. We cannot just use TEMP_FAILURE_RETRY since it might
- lead to infinite loops. */
- struct timeval now;
- (void) __gettimeofday (&now, NULL);
- long int end = (now.tv_sec + 5) * 1000 + (now.tv_usec + 500) / 1000;
- while (1)
- {
- long int timeout = end - (now.tv_sec * 1000
- + (now.tv_usec + 500) / 1000);
- n = __poll (fds, 1, timeout);
- if (n != -1 || errno != EINTR)
- break;
- (void) __gettimeofday (&now, NULL);
- }
- }
-
- return n;
-}
-
-
/* Try to get a file descriptor for the shared meory segment
containing the database. */
static struct mapped_database *
@@ -265,7 +298,7 @@
msg.msg_controllen = cmsg->cmsg_len;
- if (wait_on_socket (sock) <= 0)
+ if (wait_on_socket (sock, 5 * 1000) <= 0)
goto out_close2;
# ifndef MSG_CMSG_CLOEXEC
@@ -497,7 +530,7 @@
if (sock >= 0)
{
/* Wait for data. */
- if (wait_on_socket (sock) > 0)
+ if (wait_on_socket (sock, 5 * 1000) > 0)
{
ssize_t nbytes = TEMP_FAILURE_RETRY (__read (sock, response,
responselen));
Modified: fsf/trunk/libc/time/tzfile.c
==============================================================================
--- fsf/trunk/libc/time/tzfile.c (original)
+++ fsf/trunk/libc/time/tzfile.c Sun Oct 14 00:03:34 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-1993,1995-2001,2003,2004,2006
+/* Copyright (C) 1991-1993,1995-2001,2003,2004,2006, 2007
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -50,7 +50,6 @@
long int change; /* Seconds of correction to apply. */
};
-static struct ttinfo *find_transition (time_t timer) internal_function;
static void compute_tzname_max (size_t) internal_function;
static size_t num_transitions;
@@ -537,6 +536,9 @@
{
size_t i;
+ __tzname[0] = NULL;
+ __tzname[1] = NULL;
+
if (num_transitions == 0 || timer < transitions[0])
{
/* TIMER is before any transition (or there are no transitions).
@@ -544,12 +546,34 @@
(or the first if they're all DST types). */
i = 0;
while (i < num_types && types[i].isdst)
- ++i;
+ {
+ if (__tzname[1] == NULL)
+ __tzname[1] = __tzstring (&zone_names[types[i].idx]);
+
+ ++i;
+ }
+
if (i == num_types)
i = 0;
+ __tzname[0] = __tzstring (&zone_names[types[i].idx]);
+ if (__tzname[1] == NULL)
+ {
+ size_t j = i;
+ while (j < num_types)
+ if (types[j].isdst)
+ {
+ __tzname[1] = __tzstring (&zone_names[types[j].idx]);
+ break;
+ }
+ else
+ ++j;
+ }
}
else if (timer >= transitions[num_transitions - 1])
- i = type_idxs[num_transitions - 1];
+ {
+ i = num_transitions - 1;
+ goto found;
+ }
else
{
/* Find the first transition after TIMER, and
@@ -602,6 +626,26 @@
found:
/* assert (timer >= transitions[i - 1] && timer < transitions[i]); */
+ __tzname[types[type_idxs[i - 1]].isdst]
+ = __tzstring (&zone_names[types[type_idxs[i - 1]].idx]);
+ size_t j = i;
+ while (j < num_transitions)
+ {
+ int type = type_idxs[j];
+ int dst = types[type].isdst;
+ int idx = types[type].idx;
+
+ if (__tzname[dst] == NULL)
+ {
+ __tzname[dst] = __tzstring (&zone_names[idx]);
+
+ if (__tzname[1 - dst] != NULL)
+ break;
+ }
+
+ ++j;
+ }
+
i = type_idxs[i - 1];
}
@@ -620,22 +664,7 @@
struct ttinfo *info = find_transition (timer);
__daylight = rule_stdoff != rule_dstoff;
__timezone = -rule_stdoff;
- __tzname[0] = NULL;
- __tzname[1] = NULL;
- for (i = num_transitions; i > 0; )
- {
- int type = type_idxs[--i];
- int dst = types[type].isdst;
- int idx = types[type].idx;
-
- if (__tzname[dst] == NULL)
- {
- __tzname[dst] = __tzstring (&zone_names[idx]);
-
- if (__tzname[1 - dst] != NULL)
- break;
- }
- }
+
if (__tzname[0] == NULL)
{
/* This should only happen if there are no transition rules.
@@ -647,7 +676,8 @@
/* There is no daylight saving time. */
__tzname[1] = __tzname[0];
tp->tm_isdst = info->isdst;
- tp->tm_zone = __tzstring (&zone_names[info->idx]);
+ assert (strcmp (&zone_names[info->idx], __tzname[tp->tm_isdst]) == 0);
+ tp->tm_zone = __tzname[tp->tm_isdst];
tp->tm_gmtoff = info->offset;
}