18dffb485Schristos /* fstat() replacement.
2*4b169a6bSchristos Copyright (C) 2011-2022 Free Software Foundation, Inc.
38dffb485Schristos
4*4b169a6bSchristos This file is free software: you can redistribute it and/or modify
5*4b169a6bSchristos it under the terms of the GNU Lesser General Public License as
6*4b169a6bSchristos published by the Free Software Foundation; either version 2.1 of the
7*4b169a6bSchristos License, or (at your option) any later version.
88dffb485Schristos
9*4b169a6bSchristos This file is distributed in the hope that it will be useful,
108dffb485Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
118dffb485Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12*4b169a6bSchristos GNU Lesser General Public License for more details.
138dffb485Schristos
14*4b169a6bSchristos You should have received a copy of the GNU Lesser General Public License
158dffb485Schristos along with this program. If not, see <https://www.gnu.org/licenses/>. */
168dffb485Schristos
178dffb485Schristos /* If the user's config.h happens to include <sys/stat.h>, let it include only
188dffb485Schristos the system's <sys/stat.h> here, so that orig_fstat doesn't recurse to
198dffb485Schristos rpl_fstat. */
208dffb485Schristos #define __need_system_sys_stat_h
218dffb485Schristos #include <config.h>
228dffb485Schristos
238dffb485Schristos /* Get the original definition of fstat. It might be defined as a macro. */
248dffb485Schristos #include <sys/types.h>
258dffb485Schristos #include <sys/stat.h>
268dffb485Schristos #undef __need_system_sys_stat_h
278dffb485Schristos
288dffb485Schristos #if defined _WIN32 && ! defined __CYGWIN__
298dffb485Schristos # define WINDOWS_NATIVE
308dffb485Schristos #endif
318dffb485Schristos
328dffb485Schristos #if !defined WINDOWS_NATIVE
338dffb485Schristos
348dffb485Schristos static int
orig_fstat(int fd,struct stat * buf)358dffb485Schristos orig_fstat (int fd, struct stat *buf)
368dffb485Schristos {
378dffb485Schristos return fstat (fd, buf);
388dffb485Schristos }
398dffb485Schristos
408dffb485Schristos #endif
418dffb485Schristos
428dffb485Schristos /* Specification. */
438dffb485Schristos #ifdef __osf__
448dffb485Schristos /* Write "sys/stat.h" here, not <sys/stat.h>, otherwise OSF/1 5.1 DTK cc
458dffb485Schristos eliminates this include because of the preliminary #include <sys/stat.h>
468dffb485Schristos above. */
478dffb485Schristos # include "sys/stat.h"
488dffb485Schristos #else
498dffb485Schristos # include <sys/stat.h>
508dffb485Schristos #endif
518dffb485Schristos
528dffb485Schristos #include "stat-time.h"
538dffb485Schristos
548dffb485Schristos #include <errno.h>
558dffb485Schristos #include <unistd.h>
568dffb485Schristos #ifdef WINDOWS_NATIVE
578dffb485Schristos # define WIN32_LEAN_AND_MEAN
588dffb485Schristos # include <windows.h>
598dffb485Schristos # if GNULIB_MSVC_NOTHROW
608dffb485Schristos # include "msvc-nothrow.h"
618dffb485Schristos # else
628dffb485Schristos # include <io.h>
638dffb485Schristos # endif
648dffb485Schristos # include "stat-w32.h"
658dffb485Schristos #endif
668dffb485Schristos
678dffb485Schristos int
rpl_fstat(int fd,struct stat * buf)688dffb485Schristos rpl_fstat (int fd, struct stat *buf)
698dffb485Schristos {
708dffb485Schristos #if REPLACE_FCHDIR && REPLACE_OPEN_DIRECTORY
718dffb485Schristos /* Handle the case when rpl_open() used a dummy file descriptor to work
728dffb485Schristos around an open() that can't normally visit directories. */
738dffb485Schristos const char *name = _gl_directory_name (fd);
748dffb485Schristos if (name != NULL)
758dffb485Schristos return stat (name, buf);
768dffb485Schristos #endif
778dffb485Schristos
788dffb485Schristos #ifdef WINDOWS_NATIVE
798dffb485Schristos /* Fill the fields ourselves, because the original fstat function returns
808dffb485Schristos values for st_atime, st_mtime, st_ctime that depend on the current time
818dffb485Schristos zone. See
828dffb485Schristos <https://lists.gnu.org/r/bug-gnulib/2017-04/msg00134.html> */
838dffb485Schristos HANDLE h = (HANDLE) _get_osfhandle (fd);
848dffb485Schristos
858dffb485Schristos if (h == INVALID_HANDLE_VALUE)
868dffb485Schristos {
878dffb485Schristos errno = EBADF;
888dffb485Schristos return -1;
898dffb485Schristos }
908dffb485Schristos return _gl_fstat_by_handle (h, NULL, buf);
918dffb485Schristos #else
928dffb485Schristos return stat_time_normalize (orig_fstat (fd, buf), buf);
938dffb485Schristos #endif
948dffb485Schristos }
95