Blame lib/fstat.c

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