X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fopenat.c;h=73f24b06972bd1f8e74cf1147216b9c4f4366667;hb=8de32ec2916ffe14843acf4a53a465a5d413577f;hp=49ecde883ffd23b5d3733020a7af14235ea64c3a;hpb=0632e115747ff96e93330c88f536d7354a7ce507;p=gnulib.git diff --git a/lib/openat.c b/lib/openat.c index 49ecde883..73f24b069 100644 --- a/lib/openat.c +++ b/lib/openat.c @@ -1,10 +1,10 @@ /* provide a replacement openat function - Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify + 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 - the Free Software Foundation; either version 2, or (at your option) - any later version. + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -12,8 +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, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ /* written by Jim Meyering */ @@ -85,14 +84,23 @@ openat_permissive (int fd, char const *file, int flags, mode_t mode, return open (file, flags, mode); { - char *proc_file; - BUILD_PROC_NAME (proc_file, fd, file); - err = open (proc_file, flags, mode); - /* If the syscall succeeds, or if it fails with an unexpected - errno value, then return right away. Otherwise, fall through - and resort to using save_cwd/restore_cwd. */ - if (0 <= err || ! EXPECTED_ERRNO (errno)) - return err; + char buf[OPENAT_BUFFER_SIZE]; + char *proc_file = openat_proc_name (buf, fd, file); + if (proc_file) + { + int open_result = open (proc_file, flags, mode); + int open_errno = errno; + if (proc_file != buf) + free (proc_file); + /* If the syscall succeeds, or if it fails with an unexpected + errno value, then return right away. Otherwise, fall through + and resort to using save_cwd/restore_cwd. */ + if (0 <= open_result || ! EXPECTED_ERRNO (open_errno)) + { + errno = open_errno; + return open_result; + } + } } save_ok = (save_cwd (&saved_cwd) == 0); @@ -128,19 +136,23 @@ openat_permissive (int fd, char const *file, int flags, mode_t mode, bool openat_needs_fchdir (void) { - int fd2; + bool needs_fchdir = true; int fd = open ("/", O_RDONLY); - char *proc_file; - if (fd < 0) - return true; - BUILD_PROC_NAME (proc_file, fd, "."); - fd2 = open (proc_file, O_RDONLY); - close (fd); - if (0 <= fd2) - close (fd2); + if (0 <= fd) + { + char buf[OPENAT_BUFFER_SIZE]; + char *proc_file = openat_proc_name (buf, fd, "."); + if (proc_file) + { + needs_fchdir = false; + if (proc_file != buf) + free (proc_file); + } + close (fd); + } - return fd2 < 0; + return needs_fchdir; } #if !HAVE_FDOPENDIR @@ -164,10 +176,18 @@ fdopendir (int fd) int saved_errno; DIR *dir; - char *proc_file; - BUILD_PROC_NAME (proc_file, fd, "."); - dir = opendir (proc_file); - saved_errno = errno; + char buf[OPENAT_BUFFER_SIZE]; + char *proc_file = openat_proc_name (buf, fd, "."); + if (proc_file) + { + dir = opendir (proc_file); + saved_errno = errno; + } + else + { + dir = NULL; + saved_errno = EOPNOTSUPP; + } /* If the syscall fails with an expected errno value, resort to save_cwd/restore_cwd. */ @@ -195,6 +215,8 @@ fdopendir (int fd) if (dir) close (fd); + if (proc_file != buf) + free (proc_file); errno = saved_errno; return dir; } @@ -244,19 +266,3 @@ fdopendir (int fd) #undef AT_FUNC_USE_F1_COND #undef AT_FUNC_POST_FILE_PARAM_DECLS #undef AT_FUNC_POST_FILE_ARGS - -/* Replacement for Solaris' function by the same name. - Invoke chown or lchown on file, FILE, using OWNER and GROUP, in the - directory open on descriptor FD. If FLAG is AT_SYMLINK_NOFOLLOW, then - use lchown, otherwise, use chown. If possible, do it without changing - the working directory. Otherwise, resort to using save_cwd/fchdir, - then mkdir/restore_cwd. If either the save_cwd or the restore_cwd - fails, then give a diagnostic and exit nonzero. */ - -#define AT_FUNC_NAME fchownat -#define AT_FUNC_F1 lchown -#define AT_FUNC_F2 chown -#define AT_FUNC_USE_F1_COND flag == AT_SYMLINK_NOFOLLOW -#define AT_FUNC_POST_FILE_PARAM_DECLS , uid_t owner, gid_t group, int flag -#define AT_FUNC_POST_FILE_ARGS , owner, group -#include "at-func.c"