Skip to content

Commit

Permalink
Move time setting to syscall.c and add syscall fallback.
Browse files Browse the repository at this point in the history
See bug 5506 and bug 7621.
  • Loading branch information
Wayne Davison committed Aug 26, 2010
1 parent 020df16 commit 2a18935
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 35 deletions.
74 changes: 74 additions & 0 deletions syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,3 +327,77 @@ OFF_T do_lseek(int fd, OFF_T offset, int whence)
return lseek(fd, offset, whence);
#endif
}

#ifdef HAVE_UTIMENSAT
int do_utimensat(const char *fname, time_t modtime, uint32 mod_nsec)
{
struct timespec t[2];

if (dry_run) return 0;
RETURN_ERROR_IF_RO_OR_LO;

t[0].tv_sec = 0;
t[0].tv_nsec = UTIME_NOW;
t[1].tv_sec = modtime;
t[1].tv_nsec = mod_nsec;
return utimensat(AT_FDCWD, fname, t, AT_SYMLINK_NOFOLLOW);
}
#endif

#ifdef HAVE_LUTIMES
int do_lutimes(const char *fname, time_t modtime, uint32 mod_nsec)
{
struct timeval t[2];

if (dry_run) return 0;
RETURN_ERROR_IF_RO_OR_LO;

t[0].tv_sec = time(NULL);
t[0].tv_usec = 0;
t[1].tv_sec = modtime;
t[1].tv_usec = mod_nsec / 1000;
return lutimes(fname, t);
}
#endif

#ifdef HAVE_UTIMES
int do_utimes(const char *fname, time_t modtime, uint32 mod_nsec)
{
struct timeval t[2];

if (dry_run) return 0;
RETURN_ERROR_IF_RO_OR_LO;

t[0].tv_sec = time(NULL);
t[0].tv_usec = 0;
t[1].tv_sec = modtime;
t[1].tv_usec = mod_nsec / 1000;
return utimes(fname, t);
}

#elif defined HAVE_UTIME
int do_utime(const char *fname, time_t modtime, UNUSED(uint32 mod_nsec))
{
#ifdef HAVE_STRUCT_UTIMBUF
struct utimbuf tbuf;
#else
time_t t[2];
#endif

if (dry_run) return 0;
RETURN_ERROR_IF_RO_OR_LO;

# ifdef HAVE_STRUCT_UTIMBUF
tbuf.actime = time(NULL);
tbuf.modtime = modtime;
return utime(fname, &tbuf);
# else
t[0] = time(NULL);
t[1] = modtime;
return utime(fname, t);
# endif
}

#else
#error Need utimes or utime function.
#endif
77 changes: 42 additions & 35 deletions util.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#include "itypes.h"
#include "inums.h"

extern int dry_run;
extern int module_id;
extern int modify_window;
extern int relative_paths;
Expand Down Expand Up @@ -123,53 +122,61 @@ NORETURN void overflow_exit(const char *str)
exit_cleanup(RERR_MALLOC);
}

/* This returns 0 for success, 1 for a symlink if symlink time-setting
* is not possible, or -1 for any other error. */
int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)
{
if (!(preserve_times & PRESERVE_LINK_TIMES) && S_ISLNK(mode))
return 1;
static int switch_step = 0;

if (DEBUG_GTE(TIME, 1)) {
rprintf(FINFO, "set modtime of %s to (%ld) %s",
fname, (long)modtime,
asctime(localtime(&modtime)));
}

if (dry_run)
return 0;

{
switch (switch_step) {
#ifdef HAVE_UTIMENSAT
struct timespec t[2];
t[0].tv_sec = 0;
t[0].tv_nsec = UTIME_NOW;
t[1].tv_sec = modtime;
t[1].tv_nsec = mod_nsec;
return utimensat(AT_FDCWD, fname, t, AT_SYMLINK_NOFOLLOW);
#elif defined HAVE_UTIMES || defined HAVE_LUTIMES
struct timeval t[2];
t[0].tv_sec = time(NULL);
t[0].tv_usec = 0;
t[1].tv_sec = modtime;
t[1].tv_usec = mod_nsec / 1000;
# ifdef HAVE_LUTIMES
return lutimes(fname, t);
# else
return utimes(fname, t);
# endif
#elif defined HAVE_STRUCT_UTIMBUF
struct utimbuf tbuf;
tbuf.actime = time(NULL);
tbuf.modtime = modtime;
return utime(fname,&tbuf);
#elif defined HAVE_UTIME
time_t t[2];
t[0] = time(NULL);
t[1] = modtime;
return utime(fname,t);
#include "case_N.h"
if (do_utimensat(fname, modtime, mod_nsec) == 0)
break;
if (errno != ENOSYS)
return -1;
switch_step++;
/* FALLTHROUGH */
#endif

#ifdef HAVE_LUTIMES
#include "case_N.h"
if (do_lutimes(fname, modtime, mod_nsec) == 0)
break;
if (errno != ENOSYS)
return -1;
switch_step++;
/* FALLTHROUGH */
#endif

#include "case_N.h"
switch_step++;
if (preserve_times & PRESERVE_LINK_TIMES) {
preserve_times &= ~PRESERVE_LINK_TIMES;
if (S_ISLNK(mode))
return 1;
}
/* FALLTHROUGH */

#include "case_N.h"
#ifdef HAVE_UTIMES
if (do_utimes(fname, modtime, mod_nsec) == 0)
break;
#else
#error No file-time-modification routine found!
if (do_utime(fname, modtime, mod_nsec) == 0)
break;
#endif

return -1;
}

return 0;
}

/* Create any necessary directories in fname. Any missing directories are
Expand Down

0 comments on commit 2a18935

Please sign in to comment.