X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=lib%2Fopenat.c;h=341c5113818af03a243f3192dda470bce11bbeb2;hb=92249085071a973e2c0621b0415b93d2e48bb00d;hp=acbf7e323ea46eac88543ff46a9b989de9e08827;hpb=2e7e88b2efec90c4ad9dc7a24d533b36a6223be2;p=debian%2Fgzip diff --git a/lib/openat.c b/lib/openat.c index acbf7e3..341c511 100644 --- a/lib/openat.c +++ b/lib/openat.c @@ -1,5 +1,5 @@ /* provide a replacement openat function - Copyright (C) 2004-2016 Free Software Foundation, Inc. + Copyright (C) 2004-2018 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -12,7 +12,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + along with this program. If not, see . */ /* written by Jim Meyering */ @@ -41,6 +41,8 @@ orig_openat (int fd, char const *filename, int flags, mode_t mode) #include "openat.h" +#include "cloexec.h" + #include #include #include @@ -50,10 +52,18 @@ orig_openat (int fd, char const *filename, int flags, mode_t mode) #if HAVE_OPENAT -/* Like openat, but work around Solaris 9 bugs with trailing slash. */ +/* Like openat, but support O_CLOEXEC and work around Solaris 9 bugs + with trailing slash. */ int rpl_openat (int dfd, char const *filename, int flags, ...) { + /* 0 = unknown, 1 = yes, -1 = no. */ +#if GNULIB_defined_O_CLOEXEC + int have_cloexec = -1; +#else + static int have_cloexec; +#endif + mode_t mode; int fd; @@ -103,7 +113,25 @@ rpl_openat (int dfd, char const *filename, int flags, ...) } # endif - fd = orig_openat (dfd, filename, flags, mode); + fd = orig_openat (dfd, filename, + flags & ~(have_cloexec <= 0 ? O_CLOEXEC : 0), mode); + + if (flags & O_CLOEXEC) + { + if (! have_cloexec) + { + if (0 <= fd) + have_cloexec = 1; + else if (errno == EINVAL) + { + fd = orig_openat (dfd, filename, flags & ~O_CLOEXEC, mode); + have_cloexec = -1; + } + } + if (have_cloexec < 0 && 0 <= fd) + set_cloexec_flag (fd, true); + } + # if OPEN_TRAILING_SLASH_BUG /* If the filename ends in a slash and fd does not refer to a directory, @@ -146,7 +174,7 @@ rpl_openat (int dfd, char const *filename, int flags, ...) # include "save-cwd.h" /* Replacement for Solaris' openat function. - + First, try to simulate it via open ("/proc/self/fd/FD/FILE"). Failing that, simulate it by doing save_cwd/fchdir/open/restore_cwd. If either the save_cwd or the restore_cwd fails (relatively unlikely),