summaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2006-04-24 08:55:46 +0000
committerJakub Jelinek <jakub@redhat.com>2006-04-24 08:55:46 +0000
commitd0145e03799e484f3a53d79de3b3f34162ee9d3c (patch)
treed8c51a0952204f9015de0db3319d4c820e8646e0 /sysdeps
parentf5ce81c94cc27035f44d37bffa7f7e08dbce7631 (diff)
Updated to fedora-glibc-20060424T0820
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/generic/unwind-dw2-fde.c4
-rw-r--r--sysdeps/generic/unwind-dw2.c8
-rw-r--r--sysdeps/posix/getaddrinfo.c184
-rw-r--r--sysdeps/posix/sigset.c23
-rw-r--r--sysdeps/posix/tempname.c10
-rw-r--r--sysdeps/powerpc/fpu/bits/mathinline.h6
-rw-r--r--sysdeps/powerpc/fpu/e_sqrt.c4
-rw-r--r--sysdeps/powerpc/fpu/e_sqrtf.c4
-rw-r--r--sysdeps/powerpc/powerpc32/bits/atomic.h15
-rw-r--r--sysdeps/unix/sysv/linux/Versions3
-rw-r--r--sysdeps/unix/sysv/linux/alpha/bits/fcntl.h33
-rw-r--r--sysdeps/unix/sysv/linux/bits/socket.h12
-rw-r--r--sysdeps/unix/sysv/linux/check_pf.c82
-rw-r--r--sysdeps/unix/sysv/linux/getcwd.c2
-rw-r--r--sysdeps/unix/sysv/linux/getsourcefilter.c28
-rw-r--r--sysdeps/unix/sysv/linux/i386/bits/fcntl.h33
-rw-r--r--sysdeps/unix/sysv/linux/i386/sync_file_range.S72
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h4
-rw-r--r--sysdeps/unix/sysv/linux/ia64/bits/fcntl.h33
-rw-r--r--sysdeps/unix/sysv/linux/kernel-features.h6
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h33
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S6
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S6
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/sys/procfs.h2
-rw-r--r--sysdeps/unix/sysv/linux/readlinkat.c2
-rw-r--r--sysdeps/unix/sysv/linux/s390/bits/fcntl.h33
-rw-r--r--sysdeps/unix/sysv/linux/setsourcefilter.c9
-rw-r--r--sysdeps/unix/sysv/linux/sh/bits/fcntl.h33
-rw-r--r--sysdeps/unix/sysv/linux/sparc/bits/fcntl.h33
-rw-r--r--sysdeps/unix/sysv/linux/sync_file_range.c46
-rw-r--r--sysdeps/unix/sysv/linux/syscalls.list2
-rw-r--r--sysdeps/unix/sysv/linux/ttyname.c30
-rw-r--r--sysdeps/unix/sysv/linux/ttyname_r.c31
-rw-r--r--sysdeps/unix/sysv/linux/wordsize-64/syscalls.list1
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h33
35 files changed, 743 insertions, 123 deletions
diff --git a/sysdeps/generic/unwind-dw2-fde.c b/sysdeps/generic/unwind-dw2-fde.c
index 1f03d17279..13945b9719 100644
--- a/sysdeps/generic/unwind-dw2-fde.c
+++ b/sysdeps/generic/unwind-dw2-fde.c
@@ -1,5 +1,5 @@
/* Subroutines needed for unwinding stack frames for exception handling. */
-/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2006
Free Software Foundation, Inc.
Contributed by Jason Merrill <jason@cygnus.com>.
@@ -595,7 +595,7 @@ end_fde_sort (struct object *ob, struct fde_accumulator *accu, size_t count)
{
fde_compare_t fde_compare;
- if (accu->linear && accu->linear->count != count)
+ if (accu->linear->count != count)
abort ();
if (ob->s.b.mixed_encoding)
diff --git a/sysdeps/generic/unwind-dw2.c b/sysdeps/generic/unwind-dw2.c
index 301b53176e..5ecf2846f3 100644
--- a/sysdeps/generic/unwind-dw2.c
+++ b/sysdeps/generic/unwind-dw2.c
@@ -1,5 +1,5 @@
/* DWARF2 exception handling and frame unwind runtime interface routines.
- Copyright (C) 1997,1998,1999,2000,2001,2002,2003,2005
+ Copyright (C) 1997,1998,1999,2000,2001,2002,2003,2005,2006
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -897,12 +897,16 @@ execute_cfa_program (const unsigned char *insn_ptr,
break;
case DW_CFA_GNU_window_save:
- /* ??? Hardcoded for SPARC register window configuration. */
+ /* ??? Hardcoded for SPARC register window configuration.
+ At least do not do anything for archs which explicitly
+ define a lower register number. */
+#if DWARF_FRAME_REGISTERS >= 32
for (reg = 16; reg < 32; ++reg)
{
fs->regs.reg[reg].how = REG_SAVED_OFFSET;
fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
}
+#endif
break;
case DW_CFA_GNU_args_size:
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 46c66a8f7e..843e60bba3 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -68,7 +68,7 @@ extern int __idna_to_unicode_lzlz (const char *input, char **output,
#define GAIH_EAI ~(GAIH_OKIFUNSPEC)
#ifndef UNIX_PATH_MAX
-#define UNIX_PATH_MAX 108
+# define UNIX_PATH_MAX 108
#endif
struct gaih_service
@@ -177,9 +177,9 @@ gaih_local (const char *name, const struct gaih_service *service,
if (! tp->name[0])
{
if (req->ai_socktype)
- return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE);
+ return GAIH_OKIFUNSPEC | -EAI_SOCKTYPE;
else
- return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
+ return GAIH_OKIFUNSPEC | -EAI_SERVICE;
}
}
@@ -249,9 +249,10 @@ gaih_local (const char *name, const struct gaih_service *service,
}
#endif /* 0 */
+
static int
gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
- const struct addrinfo *req, struct gaih_servtuple *st)
+ const struct addrinfo *req, struct gaih_servtuple *st)
{
struct servent *s;
size_t tmpbuflen = 1024;
@@ -362,6 +363,7 @@ typedef enum nss_status (*nss_getcanonname_r)
int *errnop, int *h_errnop);
extern service_user *__nss_hosts_database attribute_hidden;
+
static int
gaih_inet (const char *name, const struct gaih_service *service,
const struct addrinfo *req, struct addrinfo **pai,
@@ -389,9 +391,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
if (! tp->name[0])
{
if (req->ai_socktype)
- return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE);
+ return GAIH_OKIFUNSPEC | -EAI_SOCKTYPE;
else
- return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
+ return GAIH_OKIFUNSPEC | -EAI_SERVICE;
}
}
@@ -399,7 +401,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
if (service != NULL)
{
if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
- return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
+ return GAIH_OKIFUNSPEC | -EAI_SERVICE;
if (service->num < 0)
{
@@ -443,7 +445,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
pst = &(newp->next);
}
if (st == (struct gaih_servtuple *) &nullserv)
- return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
+ return GAIH_OKIFUNSPEC | -EAI_SERVICE;
}
}
else
@@ -538,16 +540,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
else
return -EAI_ADDRFAMILY;
- dupname:
if (req->ai_flags & AI_CANONNAME)
- {
- canon = strdup (name);
- if (canon == NULL)
- return -EAI_MEMORY;
- }
+ canon = name;
}
-
- if (at->family == AF_UNSPEC)
+ else if (at->family == AF_UNSPEC)
{
char *namebuf = (char *) name;
char *scope_delim = strchr (name, SCOPE_DELIMITER);
@@ -595,7 +591,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
}
}
- goto dupname;
+ if (req->ai_flags & AI_CANONNAME)
+ canon = name;
}
}
@@ -689,7 +686,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
}
/* We made requests but they turned out no data.
The name is known, though. */
- return (GAIH_OKIFUNSPEC | -EAI_NODATA);
+ return GAIH_OKIFUNSPEC | -EAI_NODATA;
}
goto process_list;
@@ -756,7 +753,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
free (air);
if (at->family == AF_UNSPEC)
- return (GAIH_OKIFUNSPEC | -EAI_NONAME);
+ return GAIH_OKIFUNSPEC | -EAI_NONAME;
goto process_list;
}
@@ -898,13 +895,13 @@ gaih_inet (const char *name, const struct gaih_service *service,
/* We made requests but they turned out no data. The name
is known, though. */
- return (GAIH_OKIFUNSPEC | -EAI_NODATA);
+ return GAIH_OKIFUNSPEC | -EAI_NODATA;
}
}
process_list:
if (at->family == AF_UNSPEC)
- return (GAIH_OKIFUNSPEC | -EAI_NONAME);
+ return GAIH_OKIFUNSPEC | -EAI_NONAME;
}
else
{
@@ -1098,6 +1095,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
return 0;
}
+#if 0
static const struct gaih gaih[] =
{
{ PF_INET6, gaih_inet },
@@ -1107,6 +1105,7 @@ static const struct gaih gaih[] =
#endif
{ PF_UNSPEC, NULL }
};
+#endif
struct sort_result
{
@@ -1114,6 +1113,7 @@ struct sort_result
struct sockaddr_storage source_addr;
uint8_t source_addr_len;
bool got_source_addr;
+ uint8_t source_addr_flags;
};
@@ -1204,7 +1204,7 @@ static const struct prefixlist default_precedence[] =
96, 20 },
{ { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0xffff, 0x0000, 0x0000 } } },
- 96, 10 },
+ 96, 100 },
{ { .in6_u = { .u6_addr16 = { 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000 } } },
0, 40 }
@@ -1336,8 +1336,16 @@ rfc3484_sort (const void *p1, const void *p2)
}
- /* Rule 3: Avoid deprecated addresses.
- That's something only the kernel could decide. */
+ /* Rule 3: Avoid deprecated addresses. */
+ if (a1->got_source_addr)
+ {
+ if (!(a1->source_addr_flags & in6ai_deprecated)
+ && (a2->source_addr_flags & in6ai_deprecated))
+ return -1;
+ if ((a1->source_addr_flags & in6ai_deprecated)
+ && !(a2->source_addr_flags & in6ai_deprecated))
+ return 1;
+ }
/* Rule 4: Prefer home addresses.
Another thing only the kernel can decide. */
@@ -1372,8 +1380,18 @@ rfc3484_sort (const void *p1, const void *p2)
return 1;
- /* Rule 7: Prefer native transport.
- XXX How to recognize tunnels? */
+ /* Rule 7: Prefer native transport. */
+ if (a1->got_source_addr)
+ {
+ if (!(a1->source_addr_flags & in6ai_temporary)
+ && (a1->source_addr_flags & in6ai_temporary))
+ return -1;
+ if ((a1->source_addr_flags & in6ai_temporary)
+ && !(a1->source_addr_flags & in6ai_temporary))
+ return -1;
+
+ /* XXX Do we need to check anything beside temporary addresses? */
+ }
/* Rule 8: Prefer smaller scope. */
@@ -1454,15 +1472,23 @@ rfc3484_sort (const void *p1, const void *p2)
}
+static int
+in6aicmp (const void *p1, const void *p2)
+{
+ struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
+ struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
+
+ return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
+}
+
+
int
getaddrinfo (const char *name, const char *service,
const struct addrinfo *hints, struct addrinfo **pai)
{
- int i = 0, j = 0, last_i = 0;
+ int i = 0, last_i = 0;
int nresults = 0;
- struct addrinfo *p = NULL, **end;
- const struct gaih *g = gaih;
- const struct gaih *pg = NULL;
+ struct addrinfo *p = NULL;
struct gaih_service gaih_service, *pservice;
struct addrinfo local_hints;
@@ -1490,15 +1516,23 @@ getaddrinfo (const char *name, const char *service,
if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
return EAI_BADFLAGS;
+ struct in6addrinfo *in6ai;
+ size_t in6ailen;
+ bool seen_ipv4 = false;
+ bool seen_ipv6 = false;
+ /* We might need information about what kind of interfaces are available.
+ But even if AI_ADDRCONFIG is not used, if the user requested IPv6
+ addresses we have to know whether an address is deprecated or
+ temporary. */
+ if ((hints->ai_flags & AI_ADDRCONFIG) || hints->ai_family == PF_UNSPEC
+ || hints->ai_family == PF_INET6)
+ /* Determine whether we have IPv4 or IPv6 interfaces or both. We
+ cannot cache the results since new interfaces could be added at
+ any time. */
+ __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
+
if (hints->ai_flags & AI_ADDRCONFIG)
{
- /* Determine whether we have IPv4 or IPv6 interfaces or both.
- We cannot cache the results since new interfaces could be
- added at any time. */
- bool seen_ipv4;
- bool seen_ipv6;
- __check_pf (&seen_ipv4, &seen_ipv6);
-
/* Now make a decision on what we return, if anything. */
if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
{
@@ -1513,8 +1547,11 @@ getaddrinfo (const char *name, const char *service,
}
else if ((hints->ai_family == PF_INET && ! seen_ipv4)
|| (hints->ai_family == PF_INET6 && ! seen_ipv6))
- /* We cannot possibly return a valid answer. */
- return EAI_NONAME;
+ {
+ /* We cannot possibly return a valid answer. */
+ free (in6ai);
+ return EAI_NONAME;
+ }
}
if (service && service[0])
@@ -1525,7 +1562,10 @@ getaddrinfo (const char *name, const char *service,
if (*c != '\0')
{
if (hints->ai_flags & AI_NUMERICSERV)
- return EAI_NONAME;
+ {
+ free (in6ai);
+ return EAI_NONAME;
+ }
gaih_service.num = -1;
}
@@ -1535,12 +1575,21 @@ getaddrinfo (const char *name, const char *service,
else
pservice = NULL;
+ struct addrinfo **end;
if (pai)
end = &p;
else
end = NULL;
unsigned int naddrs = 0;
+#if 0
+ /* If we would support more protocols than just IPv4 and IPv6 we
+ would iterate over a table with appropriate callback functions.
+ Since we currently only handle IPv4 and IPv6 this is not
+ necessary. */
+ const struct gaih *g = gaih;
+ const struct gaih *pg = NULL;
+ int j = 0;
while (g->gaih)
{
if (hints->ai_family == g->family || hints->ai_family == AF_UNSPEC)
@@ -1564,6 +1613,7 @@ getaddrinfo (const char *name, const char *service,
}
freeaddrinfo (p);
+ free (in6ai);
return -(i & GAIH_EAI);
}
@@ -1579,7 +1629,35 @@ getaddrinfo (const char *name, const char *service,
}
if (j == 0)
- return EAI_FAMILY;
+ {
+ free (in6ai);
+ return EAI_FAMILY;
+ }
+#else
+ if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
+ || hints->ai_family == AF_INET6)
+ {
+ last_i = gaih_inet (name, pservice, hints, end, &naddrs);
+ if (last_i != 0)
+ {
+ freeaddrinfo (p);
+ free (in6ai);
+
+ return -(i & GAIH_EAI);
+ }
+ if (end)
+ while (*end)
+ {
+ end = &((*end)->ai_next);
+ ++nresults;
+ }
+ }
+ else
+ {
+ free (in6ai);
+ return EAI_FAMILY;
+ }
+#endif
if (naddrs > 1)
{
@@ -1589,6 +1667,11 @@ getaddrinfo (const char *name, const char *service,
struct addrinfo *last = NULL;
char *canonname = NULL;
+ /* If we have information about deprecated and temporary address
+ sort the array now. */
+ if (in6ai != NULL)
+ qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
+
for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
{
results[i].dest_addr = q;
@@ -1603,9 +1686,12 @@ getaddrinfo (const char *name, const char *service,
results[i - 1].source_addr_len);
results[i].source_addr_len = results[i - 1].source_addr_len;
results[i].got_source_addr = results[i - 1].got_source_addr;
+ results[i].source_addr_flags = results[i - 1].source_addr_flags;
}
else
{
+ results[i].source_addr_flags = 0;
+
/* We overwrite the type with SOCK_DGRAM since we do not
want connect() to connect to the other side. If we
cannot determine the source address remember this
@@ -1620,6 +1706,20 @@ getaddrinfo (const char *name, const char *service,
{
results[i].source_addr_len = sl;
results[i].got_source_addr = true;
+
+ if (q->ai_family == PF_INET6 && in6ai != NULL)
+ {
+ /* See whether the address is the list of deprecated
+ or temporary addresses. */
+ struct in6addrinfo tmp;
+ memcpy (tmp.addr, q->ai_addr, IN6ADDRSZ);
+
+ struct in6addrinfo *found
+ = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
+ in6aicmp);
+ if (found != NULL)
+ results[i].source_addr_flags = found->flags;
+ }
}
else
/* Just make sure that if we have to process the same
@@ -1653,6 +1753,8 @@ getaddrinfo (const char *name, const char *service,
p->ai_canonname = canonname;
}
+ free (in6ai);
+
if (p)
{
*pai = p;
diff --git a/sysdeps/posix/sigset.c b/sysdeps/posix/sigset.c
index 31e39d78b5..8f96e3d610 100644
--- a/sysdeps/posix/sigset.c
+++ b/sysdeps/posix/sigset.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 2000, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000, 2005, 2006 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
@@ -29,8 +29,10 @@ sigset (sig, disp)
int sig;
__sighandler_t disp;
{
- struct sigaction act, oact;
+ struct sigaction act;
+ struct sigaction oact;
sigset_t set;
+ sigset_t oset;
#ifdef SIG_HOLD
/* Handle SIG_HOLD first. */
@@ -45,10 +47,18 @@ sigset (sig, disp)
return SIG_ERR;
/* Add the signal set to the current signal mask. */
- if (__sigprocmask (SIG_BLOCK, &set, NULL) < 0)
+ if (__sigprocmask (SIG_BLOCK, &set, &oset) < 0)
return SIG_ERR;
- return SIG_HOLD;
+ /* If the signal was already blocked signal this to the caller. */
+ if (__sigismember (&oset, sig))
+ return SIG_HOLD;
+
+ /* We need to determine whether a specific handler is installed. */
+ if (__sigaction (sig, NULL, &oact) < 0)
+ return SIG_ERR;
+
+ return oact.sa_handler;
}
#endif /* SIG_HOLD */
@@ -75,8 +85,9 @@ sigset (sig, disp)
return SIG_ERR;
/* Remove the signal set from the current signal mask. */
- if (__sigprocmask (SIG_UNBLOCK, &set, NULL) < 0)
+ if (__sigprocmask (SIG_UNBLOCK, &set, &oset) < 0)
return SIG_ERR;
- return oact.sa_handler;
+ /* If the signal was already blocked return SIG_HOLD. */
+ return __sigismember (&oset, sig) ? SIG_HOLD : oact.sa_handler;
}
diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
index 0d4bbc418a..c8973a0852 100644
--- a/sysdeps/posix/tempname.c
+++ b/sysdeps/posix/tempname.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-1999, 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1991-1999, 2000, 2001, 2006 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
@@ -242,11 +242,15 @@ __gen_tempname (char *tmpl, int kind)
necessary to try all these combinations. Instead if a reasonable
number of names is tried (we define reasonable as 62**3) fail to
give the system administrator the chance to remove the problems. */
- unsigned int attempts_min = 62 * 62 * 62;
+#define ATTEMPTS_MIN (62 * 62 * 62)
/* The number of times to attempt to generate a temporary file. To
conform to POSIX, this must be no smaller than TMP_MAX. */
- unsigned int attempts = attempts_min < TMP_MAX ? TMP_MAX : attempts_min;
+#if ATTEMPTS_MIN < TMP_MAX
+ unsigned int attempts = TMP_MAX;
+#else
+ unsigned int attempts = ATTEMPTS_MIN;
+#endif
len = strlen (tmpl);
if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
diff --git a/sysdeps/powerpc/fpu/bits/mathinline.h b/sysdeps/powerpc/fpu/bits/mathinline.h
index 15da56384e..aed899e882 100644
--- a/sysdeps/powerpc/fpu/bits/mathinline.h
+++ b/sysdeps/powerpc/fpu/bits/mathinline.h
@@ -129,7 +129,7 @@ __NTH (fdimf (float __x, float __y))
#include <ldsodefs.h>
#include <dl-procinfo.h>
-# if __WORDSIZE == 64
+# if __WORDSIZE == 64 || defined _ARCH_PWR4
# define __CPU_HAS_FSQRT 1
# else
# define __CPU_HAS_FSQRT ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0)
@@ -141,7 +141,7 @@ __NTH (__ieee754_sqrt (double __x))
{
double __z;
- /* If the CPU is 64-bit we can use the optional FP instructions we. */
+ /* If the CPU is 64-bit we can use the optional FP instructions. */
if (__CPU_HAS_FSQRT)
{
/* Volatile is required to prevent the compiler from moving the
@@ -163,7 +163,7 @@ __NTH (__ieee754_sqrtf (float __x))
{
float __z;
- /* If the CPU is 64-bit we can use the optional FP instructions we. */
+ /* If the CPU is 64-bit we can use the optional FP instructions. */
if (__CPU_HAS_FSQRT)
{
/* Volatile is required to prevent the compiler from moving the
diff --git a/sysdeps/powerpc/fpu/e_sqrt.c b/sysdeps/powerpc/fpu/e_sqrt.c
index e6ba1f979f..540b924656 100644
--- a/sysdeps/powerpc/fpu/e_sqrt.c
+++ b/sysdeps/powerpc/fpu/e_sqrt.c
@@ -169,8 +169,8 @@ __ieee754_sqrt (x)
{
double z;
- /* If the CPU is 64-bit we can use the optional FP instructions we. */
- if ((GLRO (dl_hwcap) & PPC_FEATURE_64) != 0)
+ /* If the CPU is 64-bit we can use the optional FP instructions. */
+ if (__CPU_HAS_FSQRT)
{
/* Volatile is required to prevent the compiler from moving the
fsqrt instruction above the branch. */
diff --git a/sysdeps/powerpc/fpu/e_sqrtf.c b/sysdeps/powerpc/fpu/e_sqrtf.c
index 335935bb18..b63d31472b 100644
--- a/sysdeps/powerpc/fpu/e_sqrtf.c
+++ b/sysdeps/powerpc/fpu/e_sqrtf.c
@@ -146,8 +146,8 @@ __ieee754_sqrtf (x)
{
double z;
- /* If the CPU is 64-bit we can use the optional FP instructions we. */
- if ((GLRO (dl_hwcap) & PPC_FEATURE_64) != 0)
+ /* If the CPU is 64-bit we can use the optional FP instructions. */
+ if (__CPU_HAS_FSQRT)
{
/* Volatile is required to prevent the compiler from moving the
fsqrt instruction above the branch. */
diff --git a/sysdeps/powerpc/powerpc32/bits/atomic.h b/sysdeps/powerpc/powerpc32/bits/atomic.h
index 0f1a72335f..6fcc669fb1 100644
--- a/sysdeps/powerpc/powerpc32/bits/atomic.h
+++ b/sysdeps/powerpc/powerpc32/bits/atomic.h
@@ -89,12 +89,27 @@
# define __arch_atomic_decrement_if_positive_64(mem) \
({ abort (); (*mem)--; })
+#ifdef _ARCH_PWR4
+/*
+ * Newer powerpc64 processors support the new "light weight" sync (lwsync)
+ * So if the build is using -mcpu=[power4,power5,power5+,970] we can
+ * safely use lwsync.
+ */
+# define atomic_read_barrier() __asm ("lwsync" ::: "memory")
+/*
+ * "light weight" sync can also be used for the release barrier.
+ */
+# ifndef UP
+# define __ARCH_REL_INSTR "lwsync"
+# endif
+#else
/*
* Older powerpc32 processors don't support the new "light weight"
* sync (lwsync). So the only safe option is to use normal sync
* for all powerpc32 applications.
*/
# define atomic_read_barrier() __asm ("sync" ::: "memory")
+#endif
/*
* Include the rest of the atomic ops macros which are common to both
diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
index fed28f2db0..ad7a8701fd 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -123,6 +123,9 @@ libc {
#errlist-compat 132
_sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
}
+ GLIBC_2.5 {
+ splice; sync_file_range; tee;
+ }
GLIBC_PRIVATE {
# functions used in other libraries
__syscall_rt_sigqueueinfo;
diff --git a/sysdeps/unix/sysv/linux/alpha/bits/fcntl.h b/sysdeps/unix/sysv/linux/alpha/bits/fcntl.h
index c4a9b77e2e..6898fe8743 100644
--- a/sysdeps/unix/sysv/linux/alpha/bits/fcntl.h
+++ b/sysdeps/unix/sysv/linux/alpha/bits/fcntl.h
@@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux.
- Copyright (C) 1995-1999, 2000, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1995-2000, 2004, 2005, 2006 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
@@ -173,10 +173,41 @@ struct flock64
# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
#endif
+
+#ifdef __USE_GNU
+# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
+ in the range before performing the
+ write. */
+# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
+ dirty pages in the range which are
+ not presently under writeback. */
+# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
+ the range after performing the
+ write. */
+#endif
+
__BEGIN_DECLS
+#ifdef __USE_GNU
+
/* Provide kernel hint to read ahead. */
extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
__THROW;
+
+/* Selective file content synch'ing. */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+ unsigned int __flags);
+
+
+/* Splice two files together. */
+extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+/* In-kernel implementation of tee for pipe buffers. */
+extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+#endif
+
__END_DECLS
diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h
index 77e9b83c92..356a2ece74 100644
--- a/sysdeps/unix/sysv/linux/bits/socket.h
+++ b/sysdeps/unix/sysv/linux/bits/socket.h
@@ -1,5 +1,5 @@
/* System-specific socket constants and types. Linux version.
- Copyright (C) 1991,1992,1994-2001, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1991,1992,1994-2001,2004,2006 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
@@ -221,7 +221,10 @@ struct msghdr
size_t msg_iovlen; /* Number of elements in the vector. */
void *msg_control; /* Ancillary data (eg BSD filedesc passing). */
- size_t msg_controllen; /* Ancillary data buffer length. */
+ size_t msg_controllen; /* Ancillary data buffer length.
+ !! The type should be socklen_t but the
+ definition of the kernel is incompatible
+ with this. */
int msg_flags; /* Flags on received message. */
};
@@ -230,7 +233,10 @@ struct msghdr
struct cmsghdr
{
size_t cmsg_len; /* Length of data in cmsg_data plus length
- of cmsghdr structure. */
+ of cmsghdr structure.
+ !! The type should be socklen_t but the
+ definition of the kernel is incompatible
+ with this. */
int cmsg_level; /* Originating protocol. */
int cmsg_type; /* Protocol specific type. */
#if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L
diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c
index ae6f71d89c..f186182cf6 100644
--- a/sysdeps/unix/sysv/linux/check_pf.c
+++ b/sysdeps/unix/sysv/linux/check_pf.c
@@ -29,11 +29,18 @@
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
+#include <not-cancel.h>
#include <kernel-features.h>
+#ifndef IFA_F_TEMPORARY
+# define IFA_F_TEMPORARY IFA_F_SECONDARY
+#endif
+
+
static int
-make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6)
+make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
+ struct in6addrinfo **in6ai, size_t *in6ailen)
{
struct
{
@@ -63,6 +70,12 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6)
bool done = false;
char buf[4096];
struct iovec iov = { buf, sizeof (buf) };
+ struct in6ailist
+ {
+ struct in6addrinfo info;
+ struct in6ailist *next;
+ } *in6ailist = NULL;
+ size_t in6ailistlen = 0;
do
{
@@ -101,6 +114,42 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6)
break;
case AF_INET6:
*seen_ipv6 = true;
+
+ if (ifam->ifa_flags & (IFA_F_DEPRECATED | IFA_F_TEMPORARY))
+ {
+ struct rtattr *rta = IFA_RTA (ifam);
+ size_t len = (nlmh->nlmsg_len
+ - NLMSG_LENGTH (sizeof (*ifam)));
+ void *local = NULL;
+ void *address = NULL;
+ while (RTA_OK (rta, len))
+ {
+ switch (rta->rta_type)
+ {
+ case IFA_LOCAL:
+ local = RTA_DATA (rta);
+ break;
+
+ case IFA_ADDRESS:
+ address = RTA_DATA (rta);
+ break;
+ }
+
+ rta = RTA_NEXT (rta, len);
+ }
+
+ struct in6ailist *newp = alloca (sizeof (*newp));
+ newp->info.flags = (((ifam->ifa_flags & IFA_F_DEPRECATED)
+ ? in6ai_deprecated : 0)
+ | ((ifam->ifa_flags
+ & IFA_F_TEMPORARY)
+ ? in6ai_temporary : 0));
+ memcpy (newp->info.addr, address ?: local,
+ sizeof (newp->info.addr));
+ newp->next = in6ailist;
+ in6ailist = newp;
+ ++in6ailistlen;
+ }
break;
default:
/* Ignore. */
@@ -110,12 +159,27 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6)
else if (nlmh->nlmsg_type == NLMSG_DONE)
/* We found the end, leave the loop. */
done = true;
- else ;
}
}
while (! done);
- __close (fd);
+ close_not_cancel_no_status (fd);
+
+ if (in6ailist != NULL)
+ {
+ *in6ai = malloc (in6ailistlen * sizeof (**in6ai));
+ if (*in6ai == NULL)
+ return -1;
+
+ *in6ailen = in6ailistlen;
+
+ do
+ {
+ (*in6ai)[--in6ailistlen] = in6ailist->info;
+ in6ailist = in6ailist->next;
+ }
+ while (in6ailist != NULL);
+ }
return 0;
}
@@ -133,8 +197,12 @@ extern int __no_netlink_support attribute_hidden;
void
attribute_hidden
-__check_pf (bool *seen_ipv4, bool *seen_ipv6)
+__check_pf (bool *seen_ipv4, bool *seen_ipv6,
+ struct in6addrinfo **in6ai, size_t *in6ailen)
{
+ *in6ai = NULL;
+ *in6ailen = 0;
+
if (! __no_netlink_support)
{
int fd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
@@ -148,7 +216,8 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6)
if (fd >= 0
&& __bind (fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) == 0
&& __getsockname (fd, (struct sockaddr *) &nladdr, &addr_len) == 0
- && make_request (fd, nladdr.nl_pid, seen_ipv4, seen_ipv6) == 0)
+ && make_request (fd, nladdr.nl_pid, seen_ipv4, seen_ipv6,
+ in6ai, in6ailen) == 0)
/* It worked. */
return;
@@ -178,9 +247,6 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6)
return;
}
- *seen_ipv4 = false;
- *seen_ipv6 = false;
-
struct ifaddrs *runp;
for (runp = ifa; runp != NULL; runp = runp->ifa_next)
if (runp->ifa_addr->sa_family == PF_INET)
diff --git a/sysdeps/unix/sysv/linux/getcwd.c b/sysdeps/unix/sysv/linux/getcwd.c
index 1a308ca38f..911d85f43d 100644
--- a/sysdeps/unix/sysv/linux/getcwd.c
+++ b/sysdeps/unix/sysv/linux/getcwd.c
@@ -87,7 +87,7 @@ __getcwd (char *buf, size_t size)
return NULL;
}
- alloc_size = PATH_MAX;
+ alloc_size = MAX (PATH_MAX, __getpagesize ());
}
if (buf == NULL)
diff --git a/sysdeps/unix/sysv/linux/getsourcefilter.c b/sysdeps/unix/sysv/linux/getsourcefilter.c
index fdcf8d6130..a6f89a3cc9 100644
--- a/sysdeps/unix/sysv/linux/getsourcefilter.c
+++ b/sysdeps/unix/sysv/linux/getsourcefilter.c
@@ -1,5 +1,5 @@
/* Get source filter. Linux version.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
@@ -112,23 +112,27 @@ getsourcefilter (int s, uint32_t interface, const struct sockaddr *group,
gf->gf_numsrc = *numsrc;
/* We need to provide the appropriate socket level value. */
+ int result;
int sol = __get_sol (group->sa_family, grouplen);
if (sol == -1)
{
__set_errno (EINVAL);
- return -1;
+ result = -1;
}
-
- int result = __getsockopt (s, sol, MCAST_MSFILTER, gf, &needed);
-
- /* If successful, copy the results to the places the caller wants
- them in. */
- if (result == 0)
+ else
{
- *fmode = gf->gf_fmode;
- memcpy (slist, gf->gf_slist,
- MIN (*numsrc, gf->gf_numsrc) * sizeof (struct sockaddr_storage));
- *numsrc = gf->gf_numsrc;
+ result = __getsockopt (s, sol, MCAST_MSFILTER, gf, &needed);
+
+ /* If successful, copy the results to the places the caller wants
+ them in. */
+ if (result == 0)
+ {
+ *fmode = gf->gf_fmode;
+ memcpy (slist, gf->gf_slist,
+ MIN (*numsrc, gf->gf_numsrc)
+ * sizeof (struct sockaddr_storage));
+ *numsrc = gf->gf_numsrc;
+ }
}
if (! use_alloca)
diff --git a/sysdeps/unix/sysv/linux/i386/bits/fcntl.h b/sysdeps/unix/sysv/linux/i386/bits/fcntl.h
index 9065825b98..a375888106 100644
--- a/sysdeps/unix/sysv/linux/i386/bits/fcntl.h
+++ b/sysdeps/unix/sysv/linux/i386/bits/fcntl.h
@@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux.
- Copyright (C) 1995, 1996, 1997, 1998, 2000, 2004
+ Copyright (C) 1995, 1996, 1997, 1998, 2000, 2004, 2006
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -180,10 +180,41 @@ struct flock64
# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
#endif
+
+#ifdef __USE_GNU
+# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
+ in the range before performing the
+ write. */
+# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
+ dirty pages in the range which are
+ not presently under writeback. */
+# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
+ the range after performing the
+ write. */
+#endif
+
__BEGIN_DECLS
+#ifdef __USE_GNU
+
/* Provide kernel hint to read ahead. */
extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
__THROW;
+
+/* Selective file content synch'ing. */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+ unsigned int __flags);
+
+
+/* Splice two files together. */
+extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+/* In-kernel implementation of tee for pipe buffers. */
+extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+#endif
+
__END_DECLS
diff --git a/sysdeps/unix/sysv/linux/i386/sync_file_range.S b/sysdeps/unix/sysv/linux/i386/sync_file_range.S
new file mode 100644
index 0000000000..f39e8a00d7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/sync_file_range.S
@@ -0,0 +1,72 @@
+/* Selective file content synch'ing.
+ Copyright (C) 2006 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. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+
+ .text
+ENTRY (sync_file_range)
+#ifdef __NR_sync_file_range
+ pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ pushl %ebp
+ cfi_adjust_cfa_offset (4)
+
+ movl 20(%esp), %ebx
+ cfi_rel_offset (ebx, 12)
+ movl 24(%esp), %ecx
+ movl 28(%esp), %edx
+ movl 32(%esp), %esi
+ cfi_rel_offset (esi, 8)
+ movl 36(%esp), %edi
+ cfi_rel_offset (edi, 4)
+ movl 40(%esp), %ebp
+ cfi_rel_offset (ebp, 0)
+
+ movl $SYS_ify(sync_file_range), %eax
+ ENTER_KERNEL
+
+ popl %ebp
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebp)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+
+ cmpl $-4095, %eax
+ jae SYSCALL_ERROR_LABEL
+L(pseudo_end):
+ ret
+#else
+ movl $-ENOSYS, %eax
+ jmp SYSCALL_ERROR_LABEL
+#endif
+PSEUDO_END (sync_file_range)
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index cb5767955c..90423d8434 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992,1993,1995,1996,1997,1998,1999,2000,2002,2003,2004,2005
+/* Copyright (C) 1992,1993,1995-2000,2002-2005,2006
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper, <drepper@gnu.org>, August 1995.
@@ -447,7 +447,7 @@ asm (".L__X'%ebx = 1\n\t"
#define LOADARGS_0
#ifdef __PIC__
-# if defined I386_USE_SYSENTER
+# if defined I386_USE_SYSENTER && defined SHARED
# define LOADARGS_1 \
"bpushl .L__X'%k3, %k3\n\t"
# define LOADARGS_5 \
diff --git a/sysdeps/unix/sysv/linux/ia64/bits/fcntl.h b/sysdeps/unix/sysv/linux/ia64/bits/fcntl.h
index d330954d48..63a771ddb9 100644
--- a/sysdeps/unix/sysv/linux/ia64/bits/fcntl.h
+++ b/sysdeps/unix/sysv/linux/ia64/bits/fcntl.h
@@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux/IA64.
- Copyright (C) 1999, 2000, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2004, 2006 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
@@ -174,10 +174,41 @@ struct flock64
# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
#endif
+
+#ifdef __USE_GNU
+# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
+ in the range before performing the
+ write. */
+# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
+ dirty pages in the range which are
+ not presently under writeback. */
+# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
+ the range after performing the
+ write. */
+#endif
+
__BEGIN_DECLS
+#ifdef __USE_GNU
+
/* Provide kernel hint to read ahead. */
extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
__THROW;
+
+/* Selective file content synch'ing. */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+ unsigned int __flags);
+
+
+/* Splice two files together. */
+extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+/* In-kernel implementation of tee for pipe buffers. */
+extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+#endif
+
__END_DECLS
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index 37d25b1a5c..139e3d5a72 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -85,6 +85,12 @@
# define __ASSUME_SENDFILE 1
#endif
+/* Only very old kernels had no real symlinks for terminal descriptors
+ in /proc/self/fd. */
+#if __LINUX_KERNEL_VERSION >= 131584
+# define __ASSUME_PROC_SELF_FD_SYMLINK 1
+#endif
+
/* On x86 another `getrlimit' syscall was added in 2.3.25. */
#if __LINUX_KERNEL_VERSION >= 131865 && defined __i386__
# define __ASSUME_NEW_GETRLIMIT_SYSCALL 1
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
index 19649c01c7..2219271a1b 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
@@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux/PowerPC.
- Copyright (C) 1995, 1996, 1997, 1998, 2000, 2003, 2004
+ Copyright (C) 1995, 1996, 1997, 1998, 2000, 2003, 2004, 2006
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -180,10 +180,41 @@ struct flock64
# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
#endif
+
+#ifdef __USE_GNU
+# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
+ in the range before performing the
+ write. */
+# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
+ dirty pages in the range which are
+ not presently under writeback. */
+# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
+ the range after performing the
+ write. */
+#endif
+
__BEGIN_DECLS
+#ifdef __USE_GNU
+
/* Provide kernel hint to read ahead. */
extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
__THROW;
+
+/* Selective file content synch'ing. */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+ unsigned int __flags);
+
+
+/* Splice two files together. */
+extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+/* In-kernel implementation of tee for pipe buffers. */
+extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+#endif
+
__END_DECLS
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S
index f4c92ad7c7..37b777799c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S
@@ -84,6 +84,10 @@ ENTRY (BP_SYM (__clone))
mr r6,r8
mr r7,r9
+ /* End FDE now, because in the child the unwind info will be
+ wrong. */
+ cfi_endproc
+
/* Do the call. */
DO_CALL(SYS_ify(clone))
@@ -138,6 +142,8 @@ L(parent):
L(badargs):
li r3,EINVAL
b __syscall_error@local
+
+ cfi_startproc
END (BP_SYM (__clone))
weak_alias (BP_SYM (__clone), BP_SYM (clone))
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
index 366206d286..f1a55e64db 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
@@ -81,6 +81,10 @@ ENTRY (BP_SYM (__clone))
mr r6,r8
mr r7,r9
+ /* End FDE now, because in the child the unwind info will be
+ wrong. */
+ cfi_endproc
+
/* Do the call. */
DO_CALL(SYS_ify(clone))
@@ -132,6 +136,8 @@ L(parent):
L(badargs):
li r3,EINVAL
b JUMPTARGET(__syscall_error)
+
+ cfi_startproc
END (BP_SYM (__clone))
weak_alias (BP_SYM (__clone), BP_SYM (clone))
diff --git a/sysdeps/unix/sysv/linux/powerpc/sys/procfs.h b/sysdeps/unix/sysv/linux/powerpc/sys/procfs.h
index d2d5972411..577689f18d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sys/procfs.h
+++ b/sysdeps/unix/sysv/linux/powerpc/sys/procfs.h
@@ -35,7 +35,7 @@ __BEGIN_DECLS
/* These definitions are normally provided by ucontext.h via
asm/sigcontext.h, asm/ptrace.h, and asm/elf.h. Otherwise we define
them here. */
-#ifndef __PPC64_ELF_H
+#if !defined __PPC64_ELF_H && !defined _ASM_POWERPC_ELF_H
#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
#define ELF_NFPREG 33 /* includes fpscr */
#if __WORDSIZE == 32
diff --git a/sysdeps/unix/sysv/linux/readlinkat.c b/sysdeps/unix/sysv/linux/readlinkat.c
index c2f21ee4ca..9b4a730c0e 100644
--- a/sysdeps/unix/sysv/linux/readlinkat.c
+++ b/sysdeps/unix/sysv/linux/readlinkat.c
@@ -29,7 +29,7 @@
/* Read the contents of the symbolic link PATH relative to FD into no
more than LEN bytes of BUF. */
-int
+ssize_t
readlinkat (fd, path, buf, len)
int fd;
const char *path;
diff --git a/sysdeps/unix/sysv/linux/s390/bits/fcntl.h b/sysdeps/unix/sysv/linux/s390/bits/fcntl.h
index 8c47077580..ad3ef420a1 100644
--- a/sysdeps/unix/sysv/linux/s390/bits/fcntl.h
+++ b/sysdeps/unix/sysv/linux/s390/bits/fcntl.h
@@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux.
- Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2004, 2006 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
@@ -199,10 +199,41 @@ struct flock64
# endif
#endif
+
+#ifdef __USE_GNU
+# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
+ in the range before performing the
+ write. */
+# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
+ dirty pages in the range which are
+ not presently under writeback. */
+# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
+ the range after performing the
+ write. */
+#endif
+
__BEGIN_DECLS
+#ifdef __USE_GNU
+
/* Provide kernel hint to read ahead. */
extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
__THROW;
+
+/* Selective file content synch'ing. */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+ unsigned int __flags);
+
+
+/* Splice two files together. */
+extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+/* In-kernel implementation of tee for pipe buffers. */
+extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+#endif
+
__END_DECLS
diff --git a/sysdeps/unix/sysv/linux/setsourcefilter.c b/sysdeps/unix/sysv/linux/setsourcefilter.c
index f5c4d9786f..dc223de844 100644
--- a/sysdeps/unix/sysv/linux/setsourcefilter.c
+++ b/sysdeps/unix/sysv/linux/setsourcefilter.c
@@ -1,5 +1,5 @@
/* Set source filter. Linux version.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
@@ -57,14 +57,15 @@ setsourcefilter (int s, uint32_t interface, const struct sockaddr *group,
memcpy (gf->gf_slist, slist, numsrc * sizeof (struct sockaddr_storage));
/* We need to provide the appropriate socket level value. */
+ int result;
int sol = __get_sol (group->sa_family, grouplen);
if (sol == -1)
{
__set_errno (EINVAL);
- return -1;
+ result = -1;
}
-
- int result = __setsockopt (s, sol, MCAST_MSFILTER, gf, needed);
+ else
+ result = __setsockopt (s, sol, MCAST_MSFILTER, gf, needed);
if (! use_alloca)
{
diff --git a/sysdeps/unix/sysv/linux/sh/bits/fcntl.h b/sysdeps/unix/sysv/linux/sh/bits/fcntl.h
index 9065825b98..a375888106 100644
--- a/sysdeps/unix/sysv/linux/sh/bits/fcntl.h
+++ b/sysdeps/unix/sysv/linux/sh/bits/fcntl.h
@@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux.
- Copyright (C) 1995, 1996, 1997, 1998, 2000, 2004
+ Copyright (C) 1995, 1996, 1997, 1998, 2000, 2004, 2006
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -180,10 +180,41 @@ struct flock64
# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
#endif
+
+#ifdef __USE_GNU
+# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
+ in the range before performing the
+ write. */
+# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
+ dirty pages in the range which are
+ not presently under writeback. */
+# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
+ the range after performing the
+ write. */
+#endif
+
__BEGIN_DECLS
+#ifdef __USE_GNU
+
/* Provide kernel hint to read ahead. */
extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
__THROW;
+
+/* Selective file content synch'ing. */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+ unsigned int __flags);
+
+
+/* Splice two files together. */
+extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+/* In-kernel implementation of tee for pipe buffers. */
+extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+#endif
+
__END_DECLS
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h b/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h
index 5dc8bf32f0..b3788f0daf 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h
@@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux/SPARC.
- Copyright (C) 1995, 1996, 1997, 1998, 2000, 2003, 2004
+ Copyright (C) 1995, 1996, 1997, 1998, 2000, 2003, 2004, 2006
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -199,10 +199,41 @@ struct flock64
# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
#endif
+
+#ifdef __USE_GNU
+# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
+ in the range before performing the
+ write. */
+# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
+ dirty pages in the range which are
+ not presently under writeback. */
+# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
+ the range after performing the
+ write. */
+#endif
+
__BEGIN_DECLS
+#ifdef __USE_GNU
+
/* Provide kernel hint to read ahead. */
extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
__THROW;
+
+/* Selective file content synch'ing. */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+ unsigned int __flags);
+
+
+/* Splice two files together. */
+extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+/* In-kernel implementation of tee for pipe buffers. */
+extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+#endif
+
__END_DECLS
diff --git a/sysdeps/unix/sysv/linux/sync_file_range.c b/sysdeps/unix/sysv/linux/sync_file_range.c
new file mode 100644
index 0000000000..aabe192341
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sync_file_range.c
@@ -0,0 +1,46 @@
+/* Selective file content synch'ing.
+ Copyright (C) 2006 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. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+
+#ifdef __NR_sync_file_range
+int
+sync_file_range (int fd, __off64_t from, __off64_t to, int flags)
+{
+ return INLINE_SYSCALL (sync_file_range, 6, fd, (off_t) (from >> 32),
+ (off_t) (from & 0xffffffff), (off_t) (to >> 32),
+ (off_t) (to & 0xffffffff), flags);
+}
+#else
+int
+sync_file_range (int fd, __off64_t from, __off64_t to, int flags)
+{
+ __set_errno (ENOSYS);
+ return -1;
+}
+stub_warning (sync_file_range)
+
+# include <stub-tag.h>
+#endif
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index 053d7e0ccf..6bfccd26aa 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -70,9 +70,11 @@ setfsgid EXTRA setfsgid i:i setfsgid
setfsuid EXTRA setfsuid i:i setfsuid
setpgid - setpgid i:ii __setpgid setpgid
sigaltstack - sigaltstack i:PP __sigaltstack sigaltstack
+splice EXTRA splice i:iiii splice
sysinfo EXTRA sysinfo i:p sysinfo
swapon - swapon i:si __swapon swapon
swapoff - swapoff i:s __swapoff swapoff
+tee EXTRA tee i:iiii tee
unshare EXTRA unshare i:i unshare
uselib EXTRA uselib i:s uselib
wait4 - wait4 i:iWiP __wait4 wait4
diff --git a/sysdeps/unix/sysv/linux/ttyname.c b/sysdeps/unix/sysv/linux/ttyname.c
index 68d24f195e..aed0fd8e0a 100644
--- a/sysdeps/unix/sysv/linux/ttyname.c
+++ b/sysdeps/unix/sysv/linux/ttyname.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,92,93,1996-2001,2002 Free Software Foundation, Inc.
+/* Copyright (C) 1991,92,93,1996-2002,2006 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
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <stdio-common/_itoa.h>
+#include <kernel-features.h>
#if 0
/* Is this used anywhere? It is not exported. */
@@ -41,7 +42,7 @@ static char *getttyname (const char *dev, dev_t mydev,
libc_freeres_ptr (static char *getttyname_name);
static char *
-internal_function
+internal_function attribute_compat_text_section
getttyname (const char *dev, dev_t mydev, ino64_t myino, int save, int *dostat)
{
static size_t namelen;
@@ -117,10 +118,12 @@ ttyname (int fd)
int dostat = 0;
char *name;
int save = errno;
- int len;
- if (!__isatty (fd))
- return NULL;
+ if (__builtin_expect (!__isatty (fd), 0))
+ {
+ __set_errno (ENOTTY);
+ return NULL;
+ }
/* We try using the /proc filesystem. */
*_fitoa_word (fd, __stpcpy (procname, "/proc/self/fd/"), 10, 0) = '\0';
@@ -136,10 +139,19 @@ ttyname (int fd)
}
}
- len = __readlink (procname, ttyname_buf, buflen);
- if (len != -1
- /* This is for Linux 2.0. */
- && ttyname_buf[0] != '[')
+ ssize_t len = __readlink (procname, ttyname_buf, buflen);
+ if (__builtin_expect (len == -1 && errno == ENOENT, 0))
+ {
+ __set_errno (EBADF);
+ return NULL;
+ }
+
+ if (__builtin_expect (len != -1
+#ifndef __ASSUME_PROC_SELF_FD_SYMLINK
+ /* This is for Linux 2.0. */
+ && ttyname_buf[0] != '['
+#endif
+ , 1))
{
if ((size_t) len >= buflen)
return NULL;
diff --git a/sysdeps/unix/sysv/linux/ttyname_r.c b/sysdeps/unix/sysv/linux/ttyname_r.c
index eee4d862b2..bd415f167b 100644
--- a/sysdeps/unix/sysv/linux/ttyname_r.c
+++ b/sysdeps/unix/sysv/linux/ttyname_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,92,93,1995-2001, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1991,92,93,1995-2001,2003,2006 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
@@ -27,13 +27,14 @@
#include <stdlib.h>
#include <stdio-common/_itoa.h>
+#include <kernel-features.h>
static int getttyname_r (char *buf, size_t buflen,
dev_t mydev, ino64_t myino, int save,
int *dostat) internal_function;
static int
-internal_function
+internal_function attribute_compat_text_section
getttyname_r (char *buf, size_t buflen, dev_t mydev, ino64_t myino,
int save, int *dostat)
{
@@ -99,7 +100,6 @@ __ttyname_r (int fd, char *buf, size_t buflen)
struct stat64 st, st1;
int dostat = 0;
int save = errno;
- int ret;
/* Test for the absolute minimal size. This makes life easier inside
the loop. */
@@ -115,29 +115,34 @@ __ttyname_r (int fd, char *buf, size_t buflen)
return ERANGE;
}
+ if (__builtin_expect (!__isatty (fd), 0))
+ {
+ __set_errno (ENOTTY);
+ return ENOTTY;
+ }
+
/* We try using the /proc filesystem. */
*_fitoa_word (fd, __stpcpy (procname, "/proc/self/fd/"), 10, 0) = '\0';
- ret = __readlink (procname, buf, buflen - 1);
- if (ret == -1 && errno == ENOENT)
+ ssize_t ret = __readlink (procname, buf, buflen - 1);
+ if (__builtin_expect (ret == -1 && errno == ENOENT, 0))
{
__set_errno (EBADF);
return EBADF;
}
- if (!__isatty (fd))
- {
- __set_errno (ENOTTY);
- return ENOTTY;
- }
-
- if (ret == -1 && errno == ENAMETOOLONG)
+ if (__builtin_expect (ret == -1 && errno == ENAMETOOLONG, 0))
{
__set_errno (ERANGE);
return ERANGE;
}
- if (ret != -1 && buf[0] != '[')
+ if (__builtin_expect (ret != -1
+#ifndef __ASSUME_PROC_SELF_FD_SYMLINK
+ /* This is for Linux 2.0. */
+ && buf[0] != '['
+#endif
+ , 1))
{
buf[ret] = '\0';
return 0;
diff --git a/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list b/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list
index 58904fc4d4..d377db9687 100644
--- a/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list
+++ b/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list
@@ -14,3 +14,4 @@ getrlimit - getrlimit i:ip __getrlimit getrlimit getrlimit64
setrlimit - setrlimit i:ip __setrlimit setrlimit setrlimit64
readahead - readahead i:iii __readahead readahead
sendfile - sendfile i:iipi sendfile sendfile64
+sync_file_range - sync_file_range i:iiii sync_file_range
diff --git a/sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h b/sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h
index 9198c70bd4..2351737f7c 100644
--- a/sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h
+++ b/sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h
@@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux/x86-64.
- Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2004, 2006 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
@@ -194,10 +194,41 @@ struct flock64
# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
#endif
+
+#ifdef __USE_GNU
+# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
+ in the range before performing the
+ write. */
+# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
+ dirty pages in the range which are
+ not presently under writeback. */
+# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
+ the range after performing the
+ write. */
+#endif
+
__BEGIN_DECLS
+#ifdef __USE_GNU
+
/* Provide kernel hint to read ahead. */
extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
__THROW;
+
+/* Selective file content synch'ing. */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+ unsigned int __flags);
+
+
+/* Splice two files together. */
+extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+/* In-kernel implementation of tee for pipe buffers. */
+extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+ __THROW;
+
+#endif
+
__END_DECLS