1 /* fstat() replacement. 2 Copyright (C) 2011-2021 Free Software Foundation, Inc. 3 4 This file is free software: you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 2.1 of the 7 License, or (at your option) any later version. 8 9 This file is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public License 15 along with this program. If not, see <https://www.gnu.org/licenses/>. */ 16 17 /* If the user's config.h happens to include <sys/stat.h>, let it include only 18 the system's <sys/stat.h> here, so that orig_fstat doesn't recurse to 19 rpl_fstat. */ 20 #define __need_system_sys_stat_h 21 #include <config.h> 22 23 /* Get the original definition of fstat. It might be defined as a macro. */ 24 #include <sys/types.h> 25 #include <sys/stat.h> 26 #undef __need_system_sys_stat_h 27 28 #if defined _WIN32 && ! defined __CYGWIN__ 29 # define WINDOWS_NATIVE 30 #endif 31 32 #if !defined WINDOWS_NATIVE 33 34 static int 35 orig_fstat (int fd, struct stat *buf) /* */ 36 { 37 return fstat (fd, buf); 38 } 39 40 #endif 41 42 /* Specification. */ 43 #ifdef __osf__ 44 /* Write "sys/stat.h" here, not <sys/stat.h>, otherwise OSF/1 5.1 DTK cc 45 eliminates this include because of the preliminary #include <sys/stat.h> 46 above. */ 47 # include "sys/stat.h" 48 #else 49 # include <sys/stat.h> 50 #endif 51 52 #include "stat-time.h" 53 54 #include <errno.h> 55 #include <unistd.h> 56 #ifdef WINDOWS_NATIVE 57 # define WIN32_LEAN_AND_MEAN 58 # include <windows.h> 59 # if GNULIB_MSVC_NOTHROW 60 # include "msvc-nothrow.h" 61 # else 62 # include <io.h> 63 # endif 64 # include "stat-w32.h" 65 #endif 66 67 int 68 rpl_fstat (int fd, struct stat *buf) /* */ 69 { 70 #if REPLACE_FCHDIR && REPLACE_OPEN_DIRECTORY 71 /* Handle the case when rpl_open() used a dummy file descriptor to work 72 around an open() that can't normally visit directories. */ 73 const char *name = _gl_directory_name (fd); 74 if (name != NULL) 75 return stat (name, buf); 76 #endif 77 78 #ifdef WINDOWS_NATIVE 79 /* Fill the fields ourselves, because the original fstat function returns 80 values for st_atime, st_mtime, st_ctime that depend on the current time 81 zone. See 82 <https://lists.gnu.org/r/bug-gnulib/2017-04/msg00134.html> */ 83 HANDLE h = (HANDLE) _get_osfhandle (fd); 84 85 if (h == INVALID_HANDLE_VALUE) 86 { 87 errno = EBADF; 88 return -1; 89 } 90 return _gl_fstat_by_handle (h, NULL, buf); 91 #else 92 return stat_time_normalize (orig_fstat (fd, buf), buf); 93 #endif 94 }