diff options
author | Ulrich Drepper <drepper@redhat.com> | 2007-07-22 18:38:37 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2007-07-22 18:38:37 +0000 |
commit | cc7837639debe7c5fecb1bec7e0109db8336a90b (patch) | |
tree | 93a535ebfd3ea58cdcd942102781ab8c1555d268 /nis/nss_compat/compat-spwd.c | |
parent | 65d834b0add966dbbdb5ed1e916c60b2b2d87f10 (diff) | |
download | glibc-cc7837639debe7c5fecb1bec7e0109db8336a90b.tar.gz glibc-cc7837639debe7c5fecb1bec7e0109db8336a90b.tar.xz glibc-cc7837639debe7c5fecb1bec7e0109db8336a90b.zip |
* libio/fileops.c (_IO_new_file_fopen): Recognize 'e' flag and set
O_CLOEXEC is needed. * nis/nss_compat/compat-grp.c: Use 'e' flag when opening file. Avoid additional fcntl to set O_CLOEXEC if not needed. * nis/nss_compat/compat-initgroups.c: Likewise. * nis/nss_compat/compat-pwd.c: Likewise. * nis/nss_compat/compat-spwd.c: Likewise.
Diffstat (limited to 'nis/nss_compat/compat-spwd.c')
-rw-r--r-- | nis/nss_compat/compat-spwd.c | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/nis/nss_compat/compat-spwd.c b/nis/nss_compat/compat-spwd.c index d1de3f75b0..a5977681f2 100644 --- a/nis/nss_compat/compat-spwd.c +++ b/nis/nss_compat/compat-spwd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-1999,2001-2005,2006 Free Software Foundation, Inc. +/* Copyright (C) 1996-1999, 2001-2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996. @@ -29,6 +29,7 @@ #include <rpc/types.h> #include <rpcsvc/ypclnt.h> #include <bits/libc-lock.h> +#include <kernel-features.h> #include "netgroup.h" @@ -77,6 +78,19 @@ static ent_t ext_ent = { false, true, false, NSS_STATUS_SUCCESS, NULL, /* Protect global state against multiple changers. */ __libc_lock_define_initialized (static, lock) +/* Positive if O_CLOEXEC is supported, negative if it is not supported, + zero if it is still undecided. This variable is shared with the + other compat functions. */ +#ifdef __ASSUME_O_CLOEXEC +# define __compat_have_cloexec 1 +#else +# ifdef O_CLOEXEC +extern int __compat_have_cloexec; +# else +# define __compat_have_cloexec -1 +# endif +#endif + /* Prototypes for local functions. */ static void blacklist_store_name (const char *, ent_t *); static int in_blacklist (const char *, int, ent_t *); @@ -180,21 +194,36 @@ internal_setspent (ent_t *ent, int stayopen) if (ent->stream == NULL) { - ent->stream = fopen ("/etc/shadow", "rm"); + ent->stream = fopen ("/etc/shadow", "rme"); if (ent->stream == NULL) status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL; else { /* We have to make sure the file is `closed on exec'. */ - int result, flags; + int result = 0; - result = flags = fcntl (fileno_unlocked (ent->stream), F_GETFD, 0); - if (result >= 0) + if (__compat_have_cloexec <= 0) { - flags |= FD_CLOEXEC; - result = fcntl (fileno_unlocked (ent->stream), F_SETFD, flags); + int flags; + result = flags = fcntl (fileno_unlocked (ent->stream), F_GETFD, + 0); + if (result >= 0) + { +#if defined O_CLOEXEC && !defined __ASSUME_O_CLOEXEC + if (__compat_have_cloexec == 0) + __compat_have_cloexec = (flags & FD_CLOEXEC) ? 1 : -1; + + if (__compat_have_cloexec < 0) +#endif + { + flags |= FD_CLOEXEC; + result = fcntl (fileno_unlocked (ent->stream), F_SETFD, + flags); + } + } } + if (result < 0) { /* Something went wrong. Close the stream and return a |