From d0145e03799e484f3a53d79de3b3f34162ee9d3c Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 24 Apr 2006 08:55:46 +0000 Subject: Updated to fedora-glibc-20060424T0820 --- sysdeps/generic/unwind-dw2-fde.c | 4 +- sysdeps/generic/unwind-dw2.c | 8 +- sysdeps/posix/getaddrinfo.c | 184 +++++++++++++++++----- sysdeps/posix/sigset.c | 23 ++- sysdeps/posix/tempname.c | 10 +- sysdeps/powerpc/fpu/bits/mathinline.h | 6 +- sysdeps/powerpc/fpu/e_sqrt.c | 4 +- sysdeps/powerpc/fpu/e_sqrtf.c | 4 +- sysdeps/powerpc/powerpc32/bits/atomic.h | 15 ++ sysdeps/unix/sysv/linux/Versions | 3 + sysdeps/unix/sysv/linux/alpha/bits/fcntl.h | 33 +++- sysdeps/unix/sysv/linux/bits/socket.h | 12 +- sysdeps/unix/sysv/linux/check_pf.c | 82 +++++++++- sysdeps/unix/sysv/linux/getcwd.c | 2 +- sysdeps/unix/sysv/linux/getsourcefilter.c | 28 ++-- sysdeps/unix/sysv/linux/i386/bits/fcntl.h | 33 +++- sysdeps/unix/sysv/linux/i386/sync_file_range.S | 72 +++++++++ sysdeps/unix/sysv/linux/i386/sysdep.h | 4 +- sysdeps/unix/sysv/linux/ia64/bits/fcntl.h | 33 +++- sysdeps/unix/sysv/linux/kernel-features.h | 6 + sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h | 33 +++- sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S | 6 + sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S | 6 + sysdeps/unix/sysv/linux/powerpc/sys/procfs.h | 2 +- sysdeps/unix/sysv/linux/readlinkat.c | 2 +- sysdeps/unix/sysv/linux/s390/bits/fcntl.h | 33 +++- sysdeps/unix/sysv/linux/setsourcefilter.c | 9 +- sysdeps/unix/sysv/linux/sh/bits/fcntl.h | 33 +++- sysdeps/unix/sysv/linux/sparc/bits/fcntl.h | 33 +++- sysdeps/unix/sysv/linux/sync_file_range.c | 46 ++++++ sysdeps/unix/sysv/linux/syscalls.list | 2 + sysdeps/unix/sysv/linux/ttyname.c | 30 ++-- sysdeps/unix/sysv/linux/ttyname_r.c | 31 ++-- sysdeps/unix/sysv/linux/wordsize-64/syscalls.list | 1 + sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h | 33 +++- 35 files changed, 743 insertions(+), 123 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/i386/sync_file_range.S create mode 100644 sysdeps/unix/sysv/linux/sync_file_range.c (limited to 'sysdeps') 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 . @@ -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 #include -# 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 #include +#include #include +#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 , 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 +#define _ERRNO_H 1 +#include + + + .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, , 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 , 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 +#include +#include + +#include +#include + + +#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 +#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 #include +#include #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 #include +#include 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 -- cgit 1.4.1