AC_C_INLINE
AC_CHECK_HEADERS_ONCE(fcntl.h linux/fd.h memory.h net/errno.h \
- sgtty.h string.h stropts.h \
- sys/param.h sys/device.h sys/filio.h sys/gentape.h \
+ sgtty.h string.h \
+ sys/param.h sys/device.h sys/gentape.h \
sys/inet.h sys/io/trioctl.h \
sys/mtio.h sys/time.h sys/tprintf.h sys/tape.h \
unistd.h locale.h)
fseeko
ftruncate
full-write
+futimens
getdate
getline
getopt-gnu
timespec
unlinkdir
unlocked-io
-utimens
+utimensat
version-etc-fsf
xalloc
xalloc-die
void undo_last_backup (void);
int deref_stat (bool deref, char const *name, struct stat *buf);
+int fd_utimensat (int fd, int parentfd, char const *file,
+ struct timespec const ts[2], int atflag);
extern int chdir_current;
int chdir_arg (char const *dir);
void xpipe (int fd[2]);
void *page_aligned_alloc (void **ptr, size_t size);
-int set_file_atime (int fd, char const *file,
- struct timespec const timespec[2]);
+int set_file_atime (int fd, char const *file, struct timespec atime,
+ int atflag);
/* Module names.c. */
}
else
{
- diff_handle = open (file_name, open_read_flags);
+ int atime_flag =
+ (atime_preserve_option == system_atime_preserve
+ ? O_NOATIME
+ : 0);
+
+ diff_handle = open (file_name,
+ (O_RDONLY | O_BINARY | O_CLOEXEC | O_NOCTTY
+ | O_NONBLOCK | atime_flag));
if (diff_handle < 0)
{
if (atime_preserve_option == replace_atime_preserve)
{
- struct timespec ts[2];
- ts[0] = get_stat_atime (&stat_data);
- ts[1] = get_stat_mtime (&stat_data);
- if (set_file_atime (diff_handle, file_name, ts) != 0)
+ struct timespec atime = get_stat_atime (&stat_data);
+ if (set_file_atime (diff_handle, file_name, atime, 0) != 0)
utime_error (file_name);
}
struct stat stat_data;
int fd, status;
off_t offset;
+ int atime_flag =
+ (atime_preserve_option == system_atime_preserve
+ ? O_NOATIME
+ : 0);
if (current_stat_info.had_trailing_slash)
{
return;
}
- fd = open (current_stat_info.file_name, open_read_flags);
+
+ fd = open (current_stat_info.file_name,
+ (O_RDONLY | O_BINARY | O_CLOEXEC | O_NOCTTY | O_NONBLOCK
+ | atime_flag));
if (fd < 0)
{
char type;
off_t original_size;
struct timespec original_ctime;
- struct timespec restore_times[2];
off_t block_ordinal = -1;
int fd = 0;
bool is_dir;
}
st->archive_file_size = original_size = st->stat.st_size;
- st->atime = restore_times[0] = get_stat_atime (&st->stat);
- st->mtime = restore_times[1] = get_stat_mtime (&st->stat);
+ st->atime = get_stat_atime (&st->stat);
+ st->mtime = get_stat_mtime (&st->stat);
st->ctime = original_ctime = get_stat_ctime (&st->stat);
#ifdef S_ISHIDDEN
set_exit_status (TAREXIT_DIFFERS);
}
else if (atime_preserve_option == replace_atime_preserve
- && set_file_atime (fd, p, restore_times) != 0)
+ && set_file_atime (fd, p, st->atime, fstatat_flags) != 0)
utime_error (p);
}
#include <system.h>
#include <quotearg.h>
-#include <utimens.h>
#include <errno.h>
#include <priv-set.h>
if (! touch_option && permstatus != INTERDIR_PERMSTATUS)
{
- /* We set the accessed time to `now', which is really the time we
- started extracting files, unless incremental_option is used, in
- which case .st_atime is used. */
-
- /* FIXME: incremental_option should set ctime too, but how? */
-
struct timespec ts[2];
if (incremental_option)
ts[0] = st->atime;
else
- ts[0] = start_time;
+ ts[0].tv_nsec = UTIME_NOW;
ts[1] = st->mtime;
- if (fdutimens (file_name, fd, ts) != 0)
+ if (fd_utimensat (fd, AT_FDCWD, file_name, ts, 0) != 0)
utime_error (file_name);
else
{
- check_time (file_name, ts[0]);
+ if (incremental_option)
+ check_time (file_name, ts[0]);
check_time (file_name, ts[1]);
}
}
#include <save-cwd.h>
#include <xgetcwd.h>
#include <unlinkdir.h>
-#include <utimens.h>
-
-#if HAVE_STROPTS_H
-# include <stropts.h>
-#endif
-#if HAVE_SYS_FILIO_H
-# include <sys/filio.h>
-#endif
#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
return deref ? stat (name, buf) : lstat (name, buf);
}
-/* Set FD's (i.e., FILE's) access time to TIMESPEC[0]. If that's not
- possible to do by itself, set its access and data modification
- times to TIMESPEC[0] and TIMESPEC[1], respectively. */
+/* Use futimens if possible, utimensat otherwise. */
int
-set_file_atime (int fd, char const *file, struct timespec const timespec[2])
+fd_utimensat (int fd, int parentfd, char const *file,
+ struct timespec const ts[2], int atflag)
{
-#ifdef _FIOSATIME
if (0 <= fd)
{
- struct timeval timeval;
- timeval.tv_sec = timespec[0].tv_sec;
- timeval.tv_usec = timespec[0].tv_nsec / 1000;
- if (ioctl (fd, _FIOSATIME, &timeval) == 0)
- return 0;
+ int result = futimens (fd, ts);
+ if (! (result < 0 && errno == ENOSYS))
+ return result;
}
-#endif
- return gl_futimens (fd, file, timespec);
+ return utimensat (parentfd, file, ts, atflag);
+}
+
+/* Set FD's (i.e., FILE's) access time to ATIME.
+ ATFLAG controls symbolic-link following, in the style of openat. */
+int
+set_file_atime (int fd, char const *file, struct timespec atime, int atflag)
+{
+ struct timespec ts[2];
+ ts[0] = atime;
+ ts[1].tv_nsec = UTIME_OMIT;
+ return fd_utimensat (fd, AT_FDCWD, file, ts, atflag);
}
/* A description of a working directory. */