From 9452e30a05dd79850be35ba9886992f482761b1e Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 4 Aug 2007 20:51:44 +0000 Subject: Updated to fedora-glibc-20070804T2027 --- sysdeps/unix/dirstream.h | 9 ++--- sysdeps/unix/opendir.c | 45 ++++++++++++++++++------ sysdeps/unix/sysv/linux/getsysstats.c | 64 +++-------------------------------- 3 files changed, 45 insertions(+), 73 deletions(-) (limited to 'sysdeps/unix') diff --git a/sysdeps/unix/dirstream.h b/sysdeps/unix/dirstream.h index a1f74473c6..8303f07fab 100644 --- a/sysdeps/unix/dirstream.h +++ b/sysdeps/unix/dirstream.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1995, 1996, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,7 +17,6 @@ 02111-1307 USA. */ #ifndef _DIRSTREAM_H - #define _DIRSTREAM_H 1 #include @@ -33,14 +32,16 @@ struct __dirstream { int fd; /* File descriptor. */ - char *data; /* Directory block. */ + __libc_lock_define (, lock) /* Mutex lock for this structure. */ + size_t allocation; /* Space allocated for the block. */ size_t size; /* Total valid data in the block. */ size_t offset; /* Current offset into the block. */ off_t filepos; /* Position of next entry to read. */ - __libc_lock_define (, lock) /* Mutex lock for this structure. */ + /* Directory block. */ + char data[0] __attribute__ ((aligned (__alignof__ (void*)))); }; #define _DIR_dirfd(dirp) ((dirp)->fd) diff --git a/sysdeps/unix/opendir.c b/sysdeps/unix/opendir.c index 59772cda75..0a116247d2 100644 --- a/sysdeps/unix/opendir.c +++ b/sysdeps/unix/opendir.c @@ -31,6 +31,7 @@ #include #include +#include /* opendir() must not accidentally open something other than a directory. @@ -110,7 +111,11 @@ __opendir (const char *name) } } - int fd = open_not_cancel_2 (name, O_RDONLY|O_NDELAY|EXTRA_FLAGS|O_LARGEFILE); + int flags = O_RDONLY|O_NDELAY|EXTRA_FLAGS|O_LARGEFILE; +#ifdef O_CLOEXEC + flags |= O_CLOEXEC; +#endif + int fd = open_not_cancel_2 (name, flags); if (__builtin_expect (fd, 0) < 0) return NULL; @@ -138,12 +143,33 @@ __opendir (const char *name) weak_alias (__opendir, opendir) +#ifdef __ASSUME_O_CLOEXEC +# define check_have_o_cloexec(fd) 1 +#else +static int +check_have_o_cloexec (int fd) +{ + if (__have_o_cloexec == 0) + __have_o_cloexec = (__fcntl (fd, F_GETFD, 0) & FD_CLOEXEC) == 0 ? -1 : 1; + return __have_o_cloexec > 0; +} +#endif + + DIR * internal_function __alloc_dir (int fd, bool close_fd, const struct stat64 *statp) { - if (__builtin_expect (__fcntl (fd, F_SETFD, FD_CLOEXEC), 0) < 0) - goto lose; + /* We always have to set the close-on-exit flag if the user provided + the file descriptor. Otherwise only if we have no working + O_CLOEXEC support. */ +#ifdef O_CLOEXEC + if (! close_fd || ! check_have_o_cloexec (fd)) +#endif + { + if (__builtin_expect (__fcntl (fd, F_SETFD, FD_CLOEXEC), 0) < 0) + goto lose; + } size_t allocation; #ifdef _STATBUF_ST_BLKSIZE @@ -155,9 +181,7 @@ __alloc_dir (int fd, bool close_fd, const struct stat64 *statp) allocation = (BUFSIZ < sizeof (struct dirent64) ? sizeof (struct dirent64) : BUFSIZ); - const int pad = -sizeof (DIR) % __alignof__ (struct dirent64); - - DIR *dirp = (DIR *) malloc (sizeof (DIR) + allocation + pad); + DIR *dirp = (DIR *) malloc (sizeof (DIR) + allocation); if (dirp == NULL) lose: { @@ -169,14 +193,15 @@ __alloc_dir (int fd, bool close_fd, const struct stat64 *statp) } return NULL; } - memset (dirp, '\0', sizeof (DIR)); - dirp->data = (char *) (dirp + 1) + pad; - dirp->allocation = allocation; - dirp->fd = fd; + dirp->fd = fd; #ifndef NOT_IN_libc __libc_lock_init (dirp->lock); #endif + dirp->allocation = allocation; + dirp->size = 0; + dirp->offset = 0; + dirp->filepos = 0; return dirp; } diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c index ee7a539a6f..6d4c9c06e8 100644 --- a/sysdeps/unix/sysv/linux/getsysstats.c +++ b/sysdeps/unix/sysv/linux/getsysstats.c @@ -68,9 +68,11 @@ #endif -static int -count_processors_in_proc (void) +int +__get_nprocs () { + /* XXX Here will come a test for the new system call. */ + char buffer[8192]; int result = 1; @@ -102,62 +104,6 @@ count_processors_in_proc (void) return result; } - - -int -__get_nprocs () -{ - /* XXX Here will come a test for the new system call. */ - - /* Try to use the sysfs filesystem. It has actual information about - online processors. */ - DIR *dir = __opendir ("/sys/devices/system/cpu"); - if (dir != NULL) - { - int dfd = dirfd (dir); - int count = 0; - struct dirent64 *d; - - while ((d = __readdir64 (dir)) != NULL) - /* NB: the sysfs has d_type support. */ - if (d->d_type == DT_DIR && strncmp (d->d_name, "cpu", 3) == 0) - { - char *endp; - unsigned long int nr = strtoul (d->d_name + 3, &endp, 10); - if (nr != ULONG_MAX && endp != d->d_name + 3 && *endp == '\0') - { - /* Try reading the online file. */ - char oname[_D_ALLOC_NAMLEN (d) + sizeof "/online"]; - strcpy (stpcpy (oname, d->d_name), "/online"); - - /* We unconditionally use openat since the "online" - file became readable only after the openat system - call was introduced. */ - char buf[1]; - int fd = openat_not_cancel_3 (dfd, oname, O_RDONLY); - - /* If we cannot read the online file we have to assume - the CPU is online. */ - if (fd < 0) - ++count; - else - { - if (read_not_cancel (fd, buf, sizeof (buf)) < 0 - || buf[0] == '1') - ++count; - - close_not_cancel_no_status (fd); - } - } - } - - __closedir (dir); - - return count; - } - - return count_processors_in_proc (); -} weak_alias (__get_nprocs, get_nprocs) @@ -206,7 +152,7 @@ __get_nprocs_conf () fclose (fp); } #else - result = count_processors_in_proc (); + result = __get_nprocs (); #endif return result; -- cgit v1.2.3-70-g09d2