Blame gl/fstat.c

Packit aea12f
/* fstat() replacement.
Packit aea12f
   Copyright (C) 2011-2019 Free Software Foundation, Inc.
Packit aea12f
Packit aea12f
   This program is free software: you can redistribute it and/or modify
Packit aea12f
   it under the terms of the GNU General Public License as published by
Packit aea12f
   the Free Software Foundation; either version 3 of the License, or
Packit aea12f
   (at your option) any later version.
Packit aea12f
Packit aea12f
   This program is distributed in the hope that it will be useful,
Packit aea12f
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit aea12f
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit aea12f
   GNU General Public License for more details.
Packit aea12f
Packit aea12f
   You should have received a copy of the GNU General Public License
Packit aea12f
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
Packit aea12f
Packit aea12f
/* If the user's config.h happens to include <sys/stat.h>, let it include only
Packit aea12f
   the system's <sys/stat.h> here, so that orig_fstat doesn't recurse to
Packit aea12f
   rpl_fstat.  */
Packit aea12f
#define __need_system_sys_stat_h
Packit aea12f
#include <config.h>
Packit aea12f
Packit aea12f
/* Get the original definition of fstat.  It might be defined as a macro.  */
Packit aea12f
#include <sys/types.h>
Packit aea12f
#include <sys/stat.h>
Packit aea12f
#undef __need_system_sys_stat_h
Packit aea12f
Packit aea12f
#if defined _WIN32 && ! defined __CYGWIN__
Packit aea12f
# define WINDOWS_NATIVE
Packit aea12f
#endif
Packit aea12f
Packit aea12f
#if !defined WINDOWS_NATIVE
Packit aea12f
Packit aea12f
static int
Packit aea12f
orig_fstat (int fd, struct stat *buf)
Packit aea12f
{
Packit aea12f
  return fstat (fd, buf);
Packit aea12f
}
Packit aea12f
Packit aea12f
#endif
Packit aea12f
Packit aea12f
/* Specification.  */
Packit aea12f
#ifdef __osf__
Packit aea12f
/* Write "sys/stat.h" here, not <sys/stat.h>, otherwise OSF/1 5.1 DTK cc
Packit aea12f
   eliminates this include because of the preliminary #include <sys/stat.h>
Packit aea12f
   above.  */
Packit aea12f
# include "sys/stat.h"
Packit aea12f
#else
Packit aea12f
# include <sys/stat.h>
Packit aea12f
#endif
Packit aea12f
Packit aea12f
#include "stat-time.h"
Packit aea12f
Packit aea12f
#include <errno.h>
Packit aea12f
#include <unistd.h>
Packit aea12f
#ifdef WINDOWS_NATIVE
Packit aea12f
# define WIN32_LEAN_AND_MEAN
Packit aea12f
# include <windows.h>
Packit aea12f
# if GNULIB_MSVC_NOTHROW
Packit aea12f
#  include "msvc-nothrow.h"
Packit aea12f
# else
Packit aea12f
#  include <io.h>
Packit aea12f
# endif
Packit aea12f
# include "stat-w32.h"
Packit aea12f
#endif
Packit aea12f
Packit aea12f
int
Packit aea12f
rpl_fstat (int fd, struct stat *buf)
Packit aea12f
{
Packit aea12f
#if REPLACE_FCHDIR && REPLACE_OPEN_DIRECTORY
Packit aea12f
  /* Handle the case when rpl_open() used a dummy file descriptor to work
Packit aea12f
     around an open() that can't normally visit directories.  */
Packit aea12f
  const char *name = _gl_directory_name (fd);
Packit aea12f
  if (name != NULL)
Packit aea12f
    return stat (name, buf);
Packit aea12f
#endif
Packit aea12f
Packit aea12f
#ifdef WINDOWS_NATIVE
Packit aea12f
  /* Fill the fields ourselves, because the original fstat function returns
Packit aea12f
     values for st_atime, st_mtime, st_ctime that depend on the current time
Packit aea12f
     zone.  See
Packit aea12f
     <https://lists.gnu.org/r/bug-gnulib/2017-04/msg00134.html>  */
Packit aea12f
  HANDLE h = (HANDLE) _get_osfhandle (fd);
Packit aea12f
Packit aea12f
  if (h == INVALID_HANDLE_VALUE)
Packit aea12f
    {
Packit aea12f
      errno = EBADF;
Packit aea12f
      return -1;
Packit aea12f
    }
Packit aea12f
  return _gl_fstat_by_handle (h, NULL, buf);
Packit aea12f
#else
Packit aea12f
  return stat_time_normalize (orig_fstat (fd, buf), buf);
Packit aea12f
#endif
Packit aea12f
}