xref: /netbsd-src/external/gpl3/gdb/dist/gnulib/import/fstat.c (revision 4b169a6ba595ae283ca507b26b15fdff40495b1c)
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