mirror of
git://sourceware.org/git/glibc.git
synced 2025-01-18 12:16:13 +08:00
* io/Makefile (aux): Add have_o_cloexec.
* include/fcntl.h: Declare __have_o_cloexec. * io/have_o_cloexec.c: New file. * sysdeps/unix/opendir.c (__opendir): Use O_CLOEXEC is available. (__alloc_dir): If O_CLOEXEC has been used, don't duplicate the fcntl call if not necessary. * login/utmp_file.c (setutent_file): Use __have_o_cloexec instead of local variable.
This commit is contained in:
parent
fa39685d5c
commit
cbf0489bcf
@ -1,5 +1,14 @@
|
||||
2007-08-02 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* io/Makefile (aux): Add have_o_cloexec.
|
||||
* include/fcntl.h: Declare __have_o_cloexec.
|
||||
* io/have_o_cloexec.c: New file.
|
||||
* sysdeps/unix/opendir.c (__opendir): Use O_CLOEXEC is available.
|
||||
(__alloc_dir): If O_CLOEXEC has been used, don't duplicate the
|
||||
fcntl call if not necessary.
|
||||
* login/utmp_file.c (setutent_file): Use __have_o_cloexec instead
|
||||
of local variable.
|
||||
|
||||
* sysdeps/unix/opendir.c (__alloc_dir): Don't initialize ->data.
|
||||
Avoid memset, add explicit initialization.
|
||||
* sysdeps/unix/dirstream.h (struct __dirstream): Move data elemtn
|
||||
|
@ -41,4 +41,8 @@ extern void __atfct_seterrno_2 (int errval, int fd1, const char *buf1,
|
||||
/* Flag determining whether the *at system calls are available. */
|
||||
extern int __have_atfcts attribute_hidden;
|
||||
|
||||
#ifdef O_CLOEXEC
|
||||
extern int __have_o_cloexec attribute_hidden;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -54,6 +54,8 @@ routines := \
|
||||
sendfile sendfile64 \
|
||||
utimensat futimens
|
||||
|
||||
aux := have_o_cloexec
|
||||
|
||||
# These routines will be omitted from the libc shared object.
|
||||
# Instead the static object files will be included in a special archive
|
||||
# linked against when the shared library will be used.
|
||||
|
24
io/have_o_cloexec.c
Normal file
24
io/have_o_cloexec.c
Normal file
@ -0,0 +1,24 @@
|
||||
/* Copyright (C) 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
|
||||
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 <fcntl.h>
|
||||
#include <kernel-features.h>
|
||||
|
||||
#if defined O_CLOEXEC && !defined __ASSUME_O_CLOEXEC
|
||||
int __have_o_cloexec;
|
||||
#endif
|
@ -157,9 +157,7 @@ setutent_file (void)
|
||||
|
||||
#ifndef __ASSUME_O_CLOEXEC
|
||||
# ifdef O_CLOEXEC
|
||||
static int have_o_cloexec;
|
||||
|
||||
if (have_o_cloexec <= 0)
|
||||
if (__have_o_cloexec <= 0)
|
||||
# endif
|
||||
{
|
||||
/* We have to make sure the file is `closed on exec'. */
|
||||
@ -167,8 +165,8 @@ setutent_file (void)
|
||||
if (result >= 0)
|
||||
{
|
||||
# ifdef O_CLOEXEC
|
||||
if (have_o_cloexec == 0)
|
||||
have_o_cloexec = (result & FD_CLOEXEC) ? 1 : -1;
|
||||
if (__have_o_cloexec == 0)
|
||||
__have_o_cloexec = (result & FD_CLOEXEC) ? 1 : -1;
|
||||
# endif
|
||||
|
||||
result = fcntl_not_cancel (file_fd, F_SETFD,
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include <dirstream.h>
|
||||
#include <not-cancel.h>
|
||||
#include <kernel-features.h>
|
||||
|
||||
|
||||
/* 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
|
||||
|
Loading…
Reference in New Issue
Block a user