diff options
author | Jakub Jelinek <jakub@redhat.com> | 2008-03-14 17:22:27 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2008-03-14 17:22:27 +0000 |
commit | b87b7fc3e6e41cf8006fb2341c236a46f6d8bdd4 (patch) | |
tree | 8b042dd05d766dd46dfa953aec240207eae14208 /sysdeps/unix/sysv | |
parent | 5c25449dd9fd706f79ee6d92019f28044d9270fa (diff) | |
download | glibc-b87b7fc3e6e41cf8006fb2341c236a46f6d8bdd4.tar glibc-b87b7fc3e6e41cf8006fb2341c236a46f6d8bdd4.tar.gz glibc-b87b7fc3e6e41cf8006fb2341c236a46f6d8bdd4.tar.bz2 glibc-b87b7fc3e6e41cf8006fb2341c236a46f6d8bdd4.zip |
Updated to fedora-glibc-20080310T1651
Diffstat (limited to 'sysdeps/unix/sysv')
-rw-r--r-- | sysdeps/unix/sysv/linux/bits/posix_opt.h | 7 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/dl-osinfo.h | 97 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/dl-sysdep.c | 104 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/dl-sysdep.h | 11 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/fpathconf.c | 5 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/pathconf.c | 48 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/pathconf.h | 13 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sysconf.c | 20 |
8 files changed, 195 insertions, 110 deletions
diff --git a/sysdeps/unix/sysv/linux/bits/posix_opt.h b/sysdeps/unix/sysv/linux/bits/posix_opt.h index 1a96db2982..37612e0bd5 100644 --- a/sysdeps/unix/sysv/linux/bits/posix_opt.h +++ b/sysdeps/unix/sysv/linux/bits/posix_opt.h @@ -1,5 +1,6 @@ /* Define POSIX options for Linux. - Copyright (C) 1996,1997,1999,2000,2002,2003 Free Software Foundation, Inc. + Copyright (C) 1996,1997,1999,2000,2002,2003,2008 + 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 @@ -51,8 +52,8 @@ /* Setting of memory protections is supported. */ #define _POSIX_MEMORY_PROTECTION 200112L -/* Only root can change owner of file. */ -#define _POSIX_CHOWN_RESTRICTED 1 +/* Some filesystems allow all users to change file ownership. */ +#define _POSIX_CHOWN_RESTRICTED 0 /* `c_cc' member of 'struct termios' structure can be disabled by using the value _POSIX_VDISABLE. */ diff --git a/sysdeps/unix/sysv/linux/dl-osinfo.h b/sysdeps/unix/sysv/linux/dl-osinfo.h index f0600283b6..582412e300 100644 --- a/sysdeps/unix/sysv/linux/dl-osinfo.h +++ b/sysdeps/unix/sysv/linux/dl-osinfo.h @@ -1,6 +1,5 @@ /* Operating system specific code for generic dynamic loader functions. Linux. - Copyright (C) 2000,2001,2002,2004,2005,2006,2007 - Free Software Foundation, Inc. + Copyright (C) 2000-2002,2004-2007,2008 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 @@ -18,10 +17,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <string.h> #include <errno.h> -#include <fcntl.h> -#include <sys/utsname.h> #include <kernel-features.h> #include <dl-sysdep.h> #include <stdint.h> @@ -44,97 +40,6 @@ dl_fatal (const char *str) } #endif -static inline int __attribute__ ((always_inline)) -_dl_discover_osversion (void) -{ -#if (defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO) && defined SHARED - if (GLRO(dl_sysinfo_map) != NULL) - { - /* If the kernel-supplied DSO contains a note indicating the kernel's - version, we don't need to call uname or parse any strings. */ - - static const struct - { - ElfW(Nhdr) hdr; - char vendor[8]; - } expected_note = { { sizeof "Linux", sizeof (ElfW(Word)), 0 }, "Linux" }; - const ElfW(Phdr) *const phdr = GLRO(dl_sysinfo_map)->l_phdr; - const ElfW(Word) phnum = GLRO(dl_sysinfo_map)->l_phnum; - for (uint_fast16_t i = 0; i < phnum; ++i) - if (phdr[i].p_type == PT_NOTE) - { - const ElfW(Addr) start = (phdr[i].p_vaddr - + GLRO(dl_sysinfo_map)->l_addr); - const ElfW(Nhdr) *note = (const void *) start; - while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz) - { - if (!memcmp (note, &expected_note, sizeof expected_note)) - return *(const ElfW(Word) *) ((const void *) note - + sizeof expected_note); -#define ROUND(len) (((len) + sizeof note->n_type - 1) & -sizeof note->n_type) - note = ((const void *) (note + 1) - + ROUND (note->n_namesz) + ROUND (note->n_descsz)); -#undef ROUND - } - } - } -#endif - - char bufmem[64]; - char *buf = bufmem; - unsigned int version; - int parts; - char *cp; - struct utsname uts; - - /* Try the uname system call. */ - if (__uname (&uts)) - { - /* This was not successful. Now try reading the /proc filesystem. */ - int fd = __open ("/proc/sys/kernel/osrelease", O_RDONLY); - if (fd < 0) - return -1; - ssize_t reslen = __read (fd, bufmem, sizeof (bufmem)); - __close (fd); - if (reslen <= 0) - /* This also didn't work. We give up since we cannot - make sure the library can actually work. */ - return -1; - buf[MIN (reslen, (ssize_t) sizeof (bufmem) - 1)] = '\0'; - } - else - buf = uts.release; - - /* Now convert it into a number. The string consists of at most - three parts. */ - version = 0; - parts = 0; - cp = buf; - while ((*cp >= '0') && (*cp <= '9')) - { - unsigned int here = *cp++ - '0'; - - while ((*cp >= '0') && (*cp <= '9')) - { - here *= 10; - here += *cp++ - '0'; - } - - ++parts; - version <<= 8; - version |= here; - - if (*cp++ != '.' || parts == 3) - /* Another part following? */ - break; - } - - if (parts < 3) - version <<= 8 * (3 - parts); - - return version; -} - #define DL_SYSDEP_OSCHECK(FATAL) \ do { \ /* Test whether the kernel is new enough. This test is only performed \ diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c index 42aec77e82..08ae9aa86d 100644 --- a/sysdeps/unix/sysv/linux/dl-sysdep.c +++ b/sysdeps/unix/sysv/linux/dl-sysdep.c @@ -1,5 +1,5 @@ /* Dynamic linker system dependencies for Linux. - Copyright (C) 1995,1997,2001,2004,2005,2006 Free Software Foundation, Inc. + Copyright (C) 1995,1997,2001,2004,2005,2006, 2008 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 @@ -20,11 +20,15 @@ /* Linux needs some special initialization, but otherwise uses the generic dynamic linker system interface code. */ +#include <string.h> +#include <fcntl.h> #include <unistd.h> +#include <sys/utsname.h> #include <ldsodefs.h> #include <kernel-features.h> -#define DL_SYSDEP_INIT frob_brk () +#ifdef SHARED +# define DL_SYSDEP_INIT frob_brk () static inline void frob_brk (void) @@ -53,4 +57,98 @@ frob_brk (void) #endif } -#include <elf/dl-sysdep.c> +# include <elf/dl-sysdep.c> +#endif + + +int +attribute_hidden +_dl_discover_osversion (void) +{ +#if (defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO) && defined SHARED + if (GLRO(dl_sysinfo_map) != NULL) + { + /* If the kernel-supplied DSO contains a note indicating the kernel's + version, we don't need to call uname or parse any strings. */ + + static const struct + { + ElfW(Nhdr) hdr; + char vendor[8]; + } expected_note = { { sizeof "Linux", sizeof (ElfW(Word)), 0 }, "Linux" }; + const ElfW(Phdr) *const phdr = GLRO(dl_sysinfo_map)->l_phdr; + const ElfW(Word) phnum = GLRO(dl_sysinfo_map)->l_phnum; + for (uint_fast16_t i = 0; i < phnum; ++i) + if (phdr[i].p_type == PT_NOTE) + { + const ElfW(Addr) start = (phdr[i].p_vaddr + + GLRO(dl_sysinfo_map)->l_addr); + const ElfW(Nhdr) *note = (const void *) start; + while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz) + { + if (!memcmp (note, &expected_note, sizeof expected_note)) + return *(const ElfW(Word) *) ((const void *) note + + sizeof expected_note); +#define ROUND(len) (((len) + sizeof note->n_type - 1) & -sizeof note->n_type) + note = ((const void *) (note + 1) + + ROUND (note->n_namesz) + ROUND (note->n_descsz)); +#undef ROUND + } + } + } +#endif + + char bufmem[64]; + char *buf = bufmem; + unsigned int version; + int parts; + char *cp; + struct utsname uts; + + /* Try the uname system call. */ + if (__uname (&uts)) + { + /* This was not successful. Now try reading the /proc filesystem. */ + int fd = __open ("/proc/sys/kernel/osrelease", O_RDONLY); + if (fd < 0) + return -1; + ssize_t reslen = __read (fd, bufmem, sizeof (bufmem)); + __close (fd); + if (reslen <= 0) + /* This also didn't work. We give up since we cannot + make sure the library can actually work. */ + return -1; + buf[MIN (reslen, (ssize_t) sizeof (bufmem) - 1)] = '\0'; + } + else + buf = uts.release; + + /* Now convert it into a number. The string consists of at most + three parts. */ + version = 0; + parts = 0; + cp = buf; + while ((*cp >= '0') && (*cp <= '9')) + { + unsigned int here = *cp++ - '0'; + + while ((*cp >= '0') && (*cp <= '9')) + { + here *= 10; + here += *cp++ - '0'; + } + + ++parts; + version <<= 8; + version |= here; + + if (*cp++ != '.' || parts == 3) + /* Another part following? */ + break; + } + + if (parts < 3) + version <<= 8 * (3 - parts); + + return version; +} diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.h b/sysdeps/unix/sysv/linux/dl-sysdep.h index becfc8df3f..0371fe87a1 100644 --- a/sysdeps/unix/sysv/linux/dl-sysdep.h +++ b/sysdeps/unix/sysv/linux/dl-sysdep.h @@ -1,5 +1,5 @@ /* System-specific settings for dynamic linker code. Linux version. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2008 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 @@ -25,3 +25,12 @@ we aren't making direct use of it. So enable this across the board. */ #define NEED_DL_SYSINFO_DSO 1 + + +/* The _dl_discover_osversion function is so far only needed in sysconf + to check for kernels later than 2.6.23. */ +#if !defined ASSEMBLER && __LINUX_KERNEL_VERSION < 0x020617 +/* Get version of the OS. */ +extern int _dl_discover_osversion (void) attribute_hidden; +# define HAVE_DL_DISCOVER_OSVERSION 1 +#endif diff --git a/sysdeps/unix/sysv/linux/fpathconf.c b/sysdeps/unix/sysv/linux/fpathconf.c index c1cdb1b899..2701c9ec99 100644 --- a/sysdeps/unix/sysv/linux/fpathconf.c +++ b/sysdeps/unix/sysv/linux/fpathconf.c @@ -1,5 +1,5 @@ /* Get file-specific information about descriptor FD. Linux version. - Copyright (C) 1991,1995,1996,1998-2002,2003 Free Software Foundation, Inc. + Copyright (C) 1991,1995,1996,1998-2003,2008 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 @@ -45,6 +45,9 @@ __fpathconf (fd, name) case _PC_2_SYMLINKS: return __statfs_symlinks (__fstatfs (fd, &fsbuf), &fsbuf); + case _PC_CHOWN_RESTRICTED: + return __statfs_chown_restricted (__fstatfs (fd, &fsbuf), &fsbuf); + default: return posix_fpathconf (fd, name); } diff --git a/sysdeps/unix/sysv/linux/pathconf.c b/sysdeps/unix/sysv/linux/pathconf.c index e12a08434a..db03529fe8 100644 --- a/sysdeps/unix/sysv/linux/pathconf.c +++ b/sysdeps/unix/sysv/linux/pathconf.c @@ -1,5 +1,5 @@ /* Get file-specific information about a file. Linux version. - Copyright (C) 1991,1995,1996,1998-2002,2003 Free Software Foundation, Inc. + Copyright (C) 1991,1995,1996,1998-2003,2008 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 @@ -19,8 +19,10 @@ #include <unistd.h> #include <errno.h> + #include "pathconf.h" #include "linux_fsinfo.h" +#include <not-cancel.h> static long int posix_pathconf (const char *file, int name); @@ -46,6 +48,9 @@ __pathconf (const char *file, int name) case _PC_2_SYMLINKS: return __statfs_symlinks (__statfs (file, &fsbuf), &fsbuf); + case _PC_CHOWN_RESTRICTED: + return __statfs_chown_restricted (__statfs (file, &fsbuf), &fsbuf); + default: return posix_pathconf (file, name); } @@ -179,3 +184,44 @@ __statfs_symlinks (int result, const struct statfs *fsbuf) return 1; } } + + +/* Used like: return __statfs_chown_restricted (__statfs (name, &buf), &buf);*/ +long int +__statfs_chown_restricted (int result, const struct statfs *fsbuf) +{ + if (result < 0) + { + if (errno == ENOSYS) + /* Not possible, return the default value. */ + return 1; + + /* Some error occured. */ + return -1; + } + + int fd; + long int retval = 1; + switch (fsbuf->f_type) + { + case XFS_SUPER_MAGIC: + /* Read the value from /proc/sys/fs/xfs/restrict_chown. If we cannot + read it default to assume the restriction is in place. */ + fd = open_not_cancel_2 ("/proc/sys/fs/xfs/restrict_chown", O_RDONLY); + if (fd != -1) + { + char buf[2]; + if (TEMP_FAILURE_RETRY (read_not_cancel (fd, buf, 2)) == 2 + && buf[0] >= '0' && buf[0] <= '1') + retval = buf[0] - '0'; + + close_not_cancel_no_status (fd); + } + break; + + default: + break; + } + + return retval; +} diff --git a/sysdeps/unix/sysv/linux/pathconf.h b/sysdeps/unix/sysv/linux/pathconf.h index 20e23685eb..806adcc5ea 100644 --- a/sysdeps/unix/sysv/linux/pathconf.h +++ b/sysdeps/unix/sysv/linux/pathconf.h @@ -1,5 +1,5 @@ /* Common parts of Linux implementation of pathconf and fpathconf. - Copyright (C) 1991,1995,1996,1998-2002,2003 Free Software Foundation, Inc. + Copyright (C) 1991,1995,1996,1998-2003,2008 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 @@ -22,13 +22,18 @@ #include <sys/statfs.h> -/* Used like: return statfs_link_max (__statfs (name, &buf), &buf); */ +/* Used like: return __statfs_link_max (__statfs (name, &buf), &buf); */ extern long int __statfs_link_max (int result, const struct statfs *fsbuf); -/* Used like: return statfs_filesize_max (__statfs (name, &buf), &buf); */ +/* Used like: return __statfs_filesize_max (__statfs (name, &buf), &buf); */ extern long int __statfs_filesize_max (int result, const struct statfs *fsbuf); -/* Used like: return statfs_link_max (__statfs (name, &buf), &buf); */ +/* Used like: return __statfs_link_max (__statfs (name, &buf), &buf); */ extern long int __statfs_symlinks (int result, const struct statfs *fsbuf); + + +/* Used like: return __statfs_chown_restricted (__statfs (name, &buf), &buf);*/ +extern long int __statfs_chown_restricted (int result, + const struct statfs *fsbuf); diff --git a/sysdeps/unix/sysv/linux/sysconf.c b/sysdeps/unix/sysv/linux/sysconf.c index f9f6f1bfa5..ab9cddc306 100644 --- a/sysdeps/unix/sysv/linux/sysconf.c +++ b/sysdeps/unix/sysv/linux/sysconf.c @@ -1,5 +1,5 @@ /* Get file-specific information about a file. Linux version. - Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2006, 2008 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 @@ -23,7 +23,9 @@ #include <sysdep.h> #include <time.h> #include <unistd.h> +#include <sys/resource.h> #include <not-cancel.h> +#include <ldsodefs.h> static long int posix_sysconf (int name); @@ -70,6 +72,22 @@ __sysconf (int name) } #endif + case _SC_ARG_MAX: +#if __LINUX_KERNEL_VERSION < 0x020617 + /* Determine whether this is a kernel 2.6.23 or later. Only + then do we have an argument limit determined by the stack + size. */ + if (GLRO(dl_discover_osversion) () >= 0x020617) +#endif + { + /* Use getrlimit to get the stack limit. */ + struct rlimit rlimit; + if (__getrlimit (RLIMIT_STACK, &rlimit) == 0) + return MAX (ARG_MAX, rlimit.rlim_cur / 4); + } + + return ARG_MAX; + case _SC_NGROUPS_MAX: /* Try to read the information from the /proc/sys/kernel/ngroups_max file. */ |