From cc7837639debe7c5fecb1bec7e0109db8336a90b Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sun, 22 Jul 2007 18:38:37 +0000 Subject: * 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. --- ChangeLog | 10 +++++++++ nis/nss_compat/compat-grp.c | 43 +++++++++++++++++++++++++++++++------- nis/nss_compat/compat-initgroups.c | 42 ++++++++++++++++++++++++++++++------- nis/nss_compat/compat-pwd.c | 43 +++++++++++++++++++++++++++++++------- nis/nss_compat/compat-spwd.c | 43 +++++++++++++++++++++++++++++++------- 5 files changed, 153 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index ff16e51b56..b7ee456696 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2007-07-22 Ulrich Drepper + + * 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. + 2007-07-21 Samuel Thibault * manual/errno.texi: Change ECANCELED value to 119. diff --git a/nis/nss_compat/compat-grp.c b/nis/nss_compat/compat-grp.c index 236c84a20f..939102868c 100644 --- a/nis/nss_compat/compat-grp.c +++ b/nis/nss_compat/compat-grp.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 , 1996. @@ -27,6 +27,7 @@ #include #include #include +#include static service_user *ni; static enum nss_status (*nss_setgrent) (int stayopen); @@ -70,6 +71,19 @@ static ent_t ext_ent = { TRUE, NSS_STATUS_SUCCESS, NULL, { NULL, 0, 0 }}; /* 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 +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 *); @@ -107,21 +121,36 @@ internal_setgrent (ent_t *ent, int stayopen, int needent) if (ent->stream == NULL) { - ent->stream = fopen ("/etc/group", "rm"); + ent->stream = fopen ("/etc/group", "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 diff --git a/nis/nss_compat/compat-initgroups.c b/nis/nss_compat/compat-initgroups.c index 70403a0785..fd16475ea9 100644 --- a/nis/nss_compat/compat-initgroups.c +++ b/nis/nss_compat/compat-initgroups.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998-2003, 2004, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1998-2004, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk , 1998. @@ -30,6 +30,7 @@ #include #include #include +#include static service_user *ni; /* Type of the lookup function. */ @@ -74,6 +75,19 @@ struct ent_t typedef struct ent_t ent_t; +/* 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 *); @@ -117,21 +131,35 @@ internal_setgrent (ent_t *ent) else ent->blacklist.current = 0; - ent->stream = fopen ("/etc/group", "rm"); + ent->stream = fopen ("/etc/group", "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 diff --git a/nis/nss_compat/compat-pwd.c b/nis/nss_compat/compat-pwd.c index ac132046da..df8f91eea0 100644 --- a/nis/nss_compat/compat-pwd.c +++ b/nis/nss_compat/compat-pwd.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 , 1996. @@ -29,6 +29,7 @@ #include #include #include +#include #include "netgroup.h" @@ -80,6 +81,19 @@ static ent_t ext_ent = { false, false, true, 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 *); @@ -227,21 +241,36 @@ internal_setpwent (ent_t *ent, int stayopen, int needent) if (ent->stream == NULL) { - ent->stream = fopen ("/etc/passwd", "rm"); + ent->stream = fopen ("/etc/passwd", "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 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 , 1996. @@ -29,6 +29,7 @@ #include #include #include +#include #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 -- cgit 1.4.1