From cfdef6ecbadc19ad24e751c1407bafc82c7b5176 Mon Sep 17 00:00:00 2001 From: tls Date: Thu, 10 Jan 2008 04:24:51 +0000 Subject: [PATCH] Teach set_ftime about symbolic links, because it has to know: on some Linux systems, when we build as a tool we think we have lutimes but it doesn't work on some filesystems at runtime. A bit ugly but effective and without use of AC_TRY_RUN in the tool build. Tidier (than mine) set_ftime reorganization from christos. --- bin/pax/extern.h | 4 ++-- bin/pax/file_subs.c | 39 ++++++++++++++++++++++++--------------- bin/pax/ftree.c | 8 ++++---- bin/pax/tables.c | 10 +++++----- 4 files changed, 35 insertions(+), 26 deletions(-) diff --git a/bin/pax/extern.h b/bin/pax/extern.h index da95feaaa629..2d6af6ccd8ea 100644 --- a/bin/pax/extern.h +++ b/bin/pax/extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: extern.h,v 1.53 2007/05/04 21:19:36 christos Exp $ */ +/* $NetBSD: extern.h,v 1.54 2008/01/10 04:24:51 tls Exp $ */ /*- * Copyright (c) 1992 Keith Muller. @@ -157,7 +157,7 @@ int chk_same(ARCHD *); int node_creat(ARCHD *); int unlnk_exist(char *, int); int chk_path(char *, uid_t, gid_t); -void set_ftime(char *fnm, time_t mtime, time_t atime, int frc); +void set_ftime(char *fnm, time_t mtime, time_t atime, int frc, int slk); int set_ids(char *, uid_t, gid_t); void set_pmode(char *, mode_t); void set_chflags(char *fnm, u_int32_t flags); diff --git a/bin/pax/file_subs.c b/bin/pax/file_subs.c index 961b01b5b923..52e7c792caea 100644 --- a/bin/pax/file_subs.c +++ b/bin/pax/file_subs.c @@ -1,4 +1,4 @@ -/* $NetBSD: file_subs.c,v 1.60 2007/04/29 20:23:34 msaitoh Exp $ */ +/* $NetBSD: file_subs.c,v 1.61 2008/01/10 04:24:51 tls Exp $ */ /*- * Copyright (c) 1992 Keith Muller. @@ -42,7 +42,7 @@ #if 0 static char sccsid[] = "@(#)file_subs.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: file_subs.c,v 1.60 2007/04/29 20:23:34 msaitoh Exp $"); +__RCSID("$NetBSD: file_subs.c,v 1.61 2008/01/10 04:24:51 tls Exp $"); #endif #endif /* not lint */ @@ -224,7 +224,8 @@ file_close(ARCHD *arcn, int fd) set_pmode(tmp_name, apply_umask((arcn->sb.st_mode & FILEBITS(0)))); if (patime || pmtime) - set_ftime(tmp_name, arcn->sb.st_mtime, arcn->sb.st_atime, 0); + set_ftime(tmp_name, arcn->sb.st_mtime, + arcn->sb.st_atime, 0, 0); /* Did we write directly to the target file? */ if (arcn->tmp_name == NULL) @@ -611,12 +612,9 @@ badlink: add_dir(nm, arcn->nlen, &(arcn->sb), 0); } -#if HAVE_LUTIMES if (patime || pmtime) -#else - if ((patime || pmtime) && arcn->type != PAX_SLK) -#endif - set_ftime(arcn->name, arcn->sb.st_mtime, arcn->sb.st_atime, 0); + set_ftime(arcn->name, arcn->sb.st_mtime, + arcn->sb.st_atime, 0, (arcn->type == PAX_SLK) ? 1 : 0); #if HAVE_STRUCT_STAT_ST_FLAGS if (pfflags && arcn->type != PAX_SLK) @@ -785,10 +783,16 @@ chk_path(char *name, uid_t st_uid, gid_t st_gid) * other ones are left alone. We do not assume the un-documented feature * of many utimes() implementations that consider a 0 time value as a do * not set request. + * + * Unfortunately, there are systems where lutimes() is present but does + * not work on some filesystem types, which cannot be detected at + * compile time. This requires passing down symlink knowledge into + * this function to obtain correct operation. Linux with XFS is one + * example of such a system. */ void -set_ftime(char *fnm, time_t mtime, time_t atime, int frc) +set_ftime(char *fnm, time_t mtime, time_t atime, int frc, int slk) { struct timeval tv[2]; struct stat sb; @@ -822,13 +826,18 @@ set_ftime(char *fnm, time_t mtime, time_t atime, int frc) * set the times */ #if HAVE_LUTIMES - if (lutimes(fnm, tv)) -#else - if (utimes(fnm, tv)) + if (lutimes(fnm, tv) == 0) + return; + if (errno != ENOSYS) /* XXX linux: lutimes is per-FS */ + goto bad; #endif - syswarn(1, errno, "Access/modification time set failed on: %s", - fnm); + if (slk) + return; + if (utimes(fnm, tv) == -1) + goto bad; return; +bad: + syswarn(1, errno, "Access/modification time set failed on: %s", fnm); } /* @@ -1086,7 +1095,7 @@ rdfile_close(ARCHD *arcn, int *fd) /* * user wants last access time reset */ - set_ftime(arcn->org_name, arcn->sb.st_mtime, arcn->sb.st_atime, 1); + set_ftime(arcn->org_name, arcn->sb.st_mtime, arcn->sb.st_atime, 1, 0); return; } diff --git a/bin/pax/ftree.c b/bin/pax/ftree.c index 7bc44ff13afb..db5aba986065 100644 --- a/bin/pax/ftree.c +++ b/bin/pax/ftree.c @@ -1,4 +1,4 @@ -/* $NetBSD: ftree.c,v 1.35 2007/04/29 20:23:34 msaitoh Exp $ */ +/* $NetBSD: ftree.c,v 1.36 2008/01/10 04:24:51 tls Exp $ */ /*- * Copyright (c) 1992 Keith Muller. @@ -78,7 +78,7 @@ #if 0 static char sccsid[] = "@(#)ftree.c 8.2 (Berkeley) 4/18/94"; #else -__RCSID("$NetBSD: ftree.c,v 1.35 2007/04/29 20:23:34 msaitoh Exp $"); +__RCSID("$NetBSD: ftree.c,v 1.36 2008/01/10 04:24:51 tls Exp $"); #endif #endif /* not lint */ @@ -549,7 +549,7 @@ next_file(ARCHD *arcn) (get_atdir(MFTENT_DUMMY_DEV, ftnode->lineno, &mtime, &atime) == 0)) { set_ftime(ftent->fts_path, - mtime, atime, 1); + mtime, atime, 1, 0); } ftnode = ftnode->parent; if (ftnode->parent == ftnode) @@ -627,7 +627,7 @@ next_file(ARCHD *arcn) #endif &mtime, &atime) < 0)) continue; - set_ftime(ftent->fts_path, mtime, atime, 1); + set_ftime(ftent->fts_path, mtime, atime, 1, 0); continue; case FTS_DC: /* diff --git a/bin/pax/tables.c b/bin/pax/tables.c index e35a7e26f362..7325bf76297f 100644 --- a/bin/pax/tables.c +++ b/bin/pax/tables.c @@ -1,4 +1,4 @@ -/* $NetBSD: tables.c,v 1.29 2007/04/29 20:23:34 msaitoh Exp $ */ +/* $NetBSD: tables.c,v 1.30 2008/01/10 04:24:51 tls Exp $ */ /*- * Copyright (c) 1992 Keith Muller. @@ -42,7 +42,7 @@ #if 0 static char sccsid[] = "@(#)tables.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: tables.c,v 1.29 2007/04/29 20:23:34 msaitoh Exp $"); +__RCSID("$NetBSD: tables.c,v 1.30 2008/01/10 04:24:51 tls Exp $"); #endif #endif /* not lint */ @@ -952,7 +952,7 @@ atdir_end(void) * not read by pax. Read time reset is controlled by -t. */ for (; pt != NULL; pt = pt->fow) - set_ftime(pt->name, pt->mtime, pt->atime, 1); + set_ftime(pt->name, pt->mtime, pt->atime, 1, 0); } } @@ -1263,7 +1263,7 @@ proc_dir(void) if (pmode || dblk.frc_mode) set_pmode(name, dblk.mode); if (patime || pmtime) - set_ftime(name, dblk.mtime, dblk.atime, 0); + set_ftime(name, dblk.mtime, dblk.atime, 0, 0); if (pfflags) set_chflags(name, dblk.fflags); } @@ -1287,7 +1287,7 @@ proc_dir(void) if (pmode || dblk->frc_mode) set_pmode(dblk->name, dblk->mode); if (patime || pmtime) - set_ftime(dblk->name, dblk->mtime, dblk->atime, 0); + set_ftime(dblk->name, dblk->mtime, dblk->atime, 0, 0); if (pfflags) set_chflags(dblk->name, dblk->fflags);