From 21d1af45a6e3eca6687b5b5997511f691061dae2 Mon Sep 17 00:00:00 2001 From: Antoine Leca Date: Sat, 24 Dec 2011 15:02:54 +0100 Subject: [PATCH] utimens(2) system call Variant of utime(2) with struct timespec (with ns precision) instead of time_t values; also allows for tv_nsec members the values UTIME_NOW (force update to current time) or UTIME_OMIT (allow to set either atim or mtim independently.) Provides a superset of utimes(2), futimes(2), lutimes(2), and futimens(2). Provides the same subset of utimensat(2) as does NetBSD 6. Also import utimens() and lutimeNS() from NetBSD-current. * Also use utimes & co for our userland * Also restore use of -p & -r for install while building --- bin/pax/file_subs.c | 10 -- bin/pax/pax.h | 4 +- commands/fetch/fetch.c | 14 -- commands/touch/touch.c | 25 ---- external/bsd/file/include/config.h | 2 - .../bsd/libarchive/include/config_netbsd.h | 6 +- external/public-domain/xz/include/config.h | 4 +- include/minix/callnr.h | 3 + lib/libc/gen/Makefile.inc | 6 +- lib/libc/gen/utimens.c | 53 +++++++ lib/libc/sys-minix/MISSING_SYSCALLS | 3 - lib/libc/sys-minix/Makefile.inc | 1 + lib/libc/sys-minix/futimens.c | 23 +++ lib/libc/sys-minix/futimes.c | 31 ++++ lib/libc/sys-minix/lutimes.c | 36 +++++ lib/libc/sys-minix/utimensat.c | 43 ++++++ lib/libc/sys-minix/utimes.c | 35 +++++ servers/vfs/param.h | 4 + servers/vfs/proto.h | 1 + servers/vfs/table.c | 2 +- servers/vfs/time.c | 141 +++++++++++++++++- share/mk/bsd.own.mk | 4 - sys/sys/fcntl.h | 8 +- sys/sys/stat.h | 2 - sys/sys/time.h | 5 +- usr.bin/gzip/gzip.c | 2 - usr.bin/xinstall/xinstall.c | 5 - usr.sbin/mtree/compare.c | 6 - 28 files changed, 391 insertions(+), 88 deletions(-) create mode 100644 lib/libc/gen/utimens.c create mode 100644 lib/libc/sys-minix/futimens.c create mode 100644 lib/libc/sys-minix/futimes.c create mode 100644 lib/libc/sys-minix/lutimes.c create mode 100644 lib/libc/sys-minix/utimensat.c create mode 100644 lib/libc/sys-minix/utimes.c diff --git a/bin/pax/file_subs.c b/bin/pax/file_subs.c index e6ba65e49..f4e598dfd 100644 --- a/bin/pax/file_subs.c +++ b/bin/pax/file_subs.c @@ -846,18 +846,8 @@ set_ftime(char *fnm, time_t mtime, time_t atime, int frc, int slk) #endif if (slk) return; -#ifdef __minix - { - struct utimbuf timp; - timp.actime = atime; - timp.modtime = mtime; - if (utime(fnm, &timp) < 0) - goto bad; - } -#else if (utimes(fnm, tv) == -1) goto bad; -#endif return; bad: syswarn(1, errno, "Access/modification time set failed on: %s", fnm); diff --git a/bin/pax/pax.h b/bin/pax/pax.h index eb09e39e6..7e8ab1a21 100644 --- a/bin/pax/pax.h +++ b/bin/pax/pax.h @@ -35,10 +35,12 @@ * @(#)pax.h 8.2 (Berkeley) 4/18/94 */ -#if ! HAVE_NBTOOL_CONFIG_H && !defined(__minix) +#if ! HAVE_NBTOOL_CONFIG_H #define HAVE_LUTIMES 1 +#ifndef __minix #define HAVE_STRUCT_STAT_ST_FLAGS 1 #endif +#endif /* * BSD PAX global data structures and constants. diff --git a/commands/fetch/fetch.c b/commands/fetch/fetch.c index 03028da71..5b51d49f7 100644 --- a/commands/fetch/fetch.c +++ b/commands/fetch/fetch.c @@ -779,7 +779,6 @@ fetch(char *URL, const char *path) */ signal: /* set mtime of local file */ -#ifndef __minix if (!n_flag && us.mtime && !o_stdout && of != NULL && (stat(path, &sb) != -1) && sb.st_mode & S_IFREG) { struct timeval tv[2]; @@ -791,19 +790,6 @@ fetch(char *URL, const char *path) if (utimes(tmppath ? tmppath : path, tv)) warn("%s: utimes()", tmppath ? tmppath : path); } -#else - if (!n_flag && us.mtime && !o_stdout && of != NULL && - (stat(path, &sb) != -1) && sb.st_mode & S_IFREG) { - struct utimbuf ut; - - fflush(of); - ut.actime = (us.atime ? us.atime : us.mtime); - ut.modtime = us.mtime; - - if (utime(tmppath ? tmppath : path, &ut)) - warn("%s: utime()", tmppath ? tmppath : path); - } -#endif /* timed out or interrupted? */ if (fetchLastErrCode == FETCH_TIMEOUT) diff --git a/commands/touch/touch.c b/commands/touch/touch.c index efedae1e0..c5d941939 100644 --- a/commands/touch/touch.c +++ b/commands/touch/touch.c @@ -59,7 +59,6 @@ main(int argc, char *argv[]) { struct stat sb; struct timeval tv[2]; - struct utimbuf timbuf; int aflag, cflag, mflag, ch, fd, len, rval, timeset; char *p; @@ -141,28 +140,14 @@ main(int argc, char *argv[]) continue; } -#if 0 if (!aflag) TIMESPEC_TO_TIMEVAL(&tv[0], &sb.st_atimespec); if (!mflag) TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtimespec); -#else - if (!aflag) - tv[0].tv_sec = sb.st_atime; - if (!mflag) - tv[1].tv_sec = sb.st_mtime; -#endif /* Try utimes(2). */ -#if 0 if (!utimes(*argv, tv)) continue; -#else - timbuf.actime = tv[0].tv_sec; - timbuf.modtime = tv[1].tv_sec; - if (!utime(*argv, &timbuf)) - continue; -#endif /* If the user specified a time, nothing else we can do. */ if (timeset) { @@ -176,13 +161,8 @@ main(int argc, char *argv[]) * The permission checks are different, too, in that the * ability to write the file is sufficient. Take a shot. */ -#if 0 if (!utimes(*argv, NULL)) continue; -#else - if (!utime(*argv, NULL)) - continue; -#endif rval = 1; warn("%s", *argv); @@ -310,13 +290,8 @@ stime_file(char *fname, struct timeval *tvp) if (stat(fname, &sb)) err(1, "%s", fname); -#if 0 TIMESPEC_TO_TIMEVAL(tvp, &sb.st_atimespec); TIMESPEC_TO_TIMEVAL(tvp + 1, &sb.st_mtimespec); -#else - (tvp + 0)->tv_sec = sb.st_atime; - (tvp + 1)->tv_sec = sb.st_mtime; -#endif } __dead void diff --git a/external/bsd/file/include/config.h b/external/bsd/file/include/config.h index f02b55582..36d44392d 100644 --- a/external/bsd/file/include/config.h +++ b/external/bsd/file/include/config.h @@ -159,10 +159,8 @@ /* Define to 1 if you have the `utime' function. */ #define HAVE_UTIME 1 -#ifndef __minix /* Define to 1 if you have the `utimes' function. */ #define HAVE_UTIMES 1 -#endif /* Define to 1 if you have the header file. */ #define HAVE_UTIME_H 1 diff --git a/external/bsd/libarchive/include/config_netbsd.h b/external/bsd/libarchive/include/config_netbsd.h index f0432c28d..75645ae98 100644 --- a/external/bsd/libarchive/include/config_netbsd.h +++ b/external/bsd/libarchive/include/config_netbsd.h @@ -242,7 +242,7 @@ /* #undef HAVE_FUTIMENS */ /* Define to 1 if you have the `futimes' function. */ -/* #define HAVE_FUTIMES 1 */ +#define HAVE_FUTIMES 1 /* Define to 1 if you have the `geteuid' function. */ #define HAVE_GETEUID 1 @@ -351,7 +351,7 @@ /* #undef HAVE_LSTAT_EMPTY_STRING_BUG */ /* Define to 1 if you have the `lutimes' function. */ -/* #define HAVE_LUTIMES 1 */ +#define HAVE_LUTIMES 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_LZMADEC_H */ @@ -570,7 +570,7 @@ /* #undef HAVE_UTIMENSAT */ /* Define to 1 if you have the `utimes' function. */ -/* #define HAVE_UTIMES 1 */ +#define HAVE_UTIMES 1 /* Define to 1 if you have the header file. */ #define HAVE_UTIME_H 1 diff --git a/external/public-domain/xz/include/config.h b/external/public-domain/xz/include/config.h index 33544c5ea..764d036aa 100644 --- a/external/public-domain/xz/include/config.h +++ b/external/public-domain/xz/include/config.h @@ -90,7 +90,7 @@ #define HAVE_FCNTL_H 1 /* Define to 1 if you have the `futimens' function. */ -/* #undef HAVE_FUTIMENS */ +#define HAVE_FUTIMENS 1 /* Define to 1 if you have the `futimes' function. */ #define HAVE_FUTIMES 1 @@ -186,7 +186,7 @@ /* #undef HAVE_UTIME */ /* Define to 1 if you have the `utimes' function. */ -/* #undef HAVE_UTIMES */ +#define HAVE_UTIMES 1 /* Define to 1 if you have the `wcwidth' function. */ #define HAVE_WCWIDTH 1 diff --git a/include/minix/callnr.h b/include/minix/callnr.h index f4417ddf5..f863e5cc2 100644 --- a/include/minix/callnr.h +++ b/include/minix/callnr.h @@ -106,6 +106,9 @@ #define CLOCK_GETTIME 115 /* clock_gettime() */ #define CLOCK_SETTIME 116 /* clock_settime() */ +/* Use a tentaive number to avoid collision */ +#define UTIMENS 105 /* to FS: [f]utimens(); also [fl]utimes */ + #define TASK_REPLY 121 /* to VFS: reply code from drivers, not * really a standalone call. */ diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc index 4ed8a2ec3..d1d4f4be8 100644 --- a/lib/libc/gen/Makefile.inc +++ b/lib/libc/gen/Makefile.inc @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.inc,v 1.184 2012/04/12 22:08:32 christos Exp $ +# $NetBSD: Makefile.inc,v 1.185 2012/11/03 19:39:21 christos Exp $ # from: @(#)Makefile.inc 8.6 (Berkeley) 5/4/95 # gen sources @@ -48,8 +48,8 @@ SRCS+= _errno.c alarm.c alphasort.c arc4random.c assert.c basename.c clock.c \ sigset.c sigsetops.c sleep.c \ stringlist.c sysconf.c \ syslog.c telldir.c time.c \ - times.c toascii.c tolower_.c ttyname.c ttyslot.c \ - toupper_.c ualarm.c ulimit.c uname.c unvis.c usleep.c utime.c utmp.c \ + times.c toascii.c tolower_.c ttyname.c ttyslot.c toupper_.c ualarm.c \ + ulimit.c uname.c unvis.c usleep.c utime.c utimens.c utmp.c \ utmpx.c valloc.c vis.c wait.c waitpid.c warn.c warnx.c \ vwarn.c vwarnx.c verr.c verrx.c wordexp.c .endif diff --git a/lib/libc/gen/utimens.c b/lib/libc/gen/utimens.c new file mode 100644 index 000000000..9fb9beeb8 --- /dev/null +++ b/lib/libc/gen/utimens.c @@ -0,0 +1,53 @@ +/* $NetBSD: utimens.c,v 1.1 2012/11/03 19:39:21 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: utimens.c,v 1.1 2012/11/03 19:39:21 christos Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" + +#define _INCOMPLETE_XOPEN_C063 +#include +#include + +int +utimens(const char *path, const struct timespec *times) +{ + return utimensat(AT_FDCWD, path, times, 0); +} + +int +lutimens(const char *path, const struct timespec *times) +{ + return utimensat(AT_FDCWD, path, times, AT_SYMLINK_NOFOLLOW); +} diff --git a/lib/libc/sys-minix/MISSING_SYSCALLS b/lib/libc/sys-minix/MISSING_SYSCALLS index dc75c0669..98ee058c0 100644 --- a/lib/libc/sys-minix/MISSING_SYSCALLS +++ b/lib/libc/sys-minix/MISSING_SYSCALLS @@ -69,9 +69,6 @@ timer_delete timer_gettime timer_settime undelete -utimes -lutimes -futimes utrace uuidgen vadvise diff --git a/lib/libc/sys-minix/Makefile.inc b/lib/libc/sys-minix/Makefile.inc index 542197c7d..98a208fab 100644 --- a/lib/libc/sys-minix/Makefile.inc +++ b/lib/libc/sys-minix/Makefile.inc @@ -17,6 +17,7 @@ SRCS+= accept.c access.c adjtime.c bind.c brk.c sbrk.c m_closefrom.c getsid.c \ vectorio.c shutdown.c sigaction.c sigpending.c sigreturn.c sigsuspend.c\ sigprocmask.c socket.c socketpair.c stat.c statvfs.c symlink.c \ sync.c syscall.c sysuname.c truncate.c umask.c unlink.c write.c \ + utimensat.c utimes.c futimes.c lutimes.c futimens.c \ _exit.c _ucontext.c environ.c __getcwd.c vfork.c sizeup.c init.c # Minix specific syscalls. diff --git a/lib/libc/sys-minix/futimens.c b/lib/libc/sys-minix/futimens.c new file mode 100644 index 000000000..4483260a8 --- /dev/null +++ b/lib/libc/sys-minix/futimens.c @@ -0,0 +1,23 @@ +#include +#include "namespace.h" +#include + +#include + +int futimens(int fd, const struct timespec tv[2]) +{ + message m; + static const struct timespec now[2] = { {0, UTIME_NOW}, {0, UTIME_NOW} }; + + if (tv == NULL) tv = now; + + m.m2_i1 = fd; + m.m2_l1 = tv[0].tv_sec; + m.m2_l2 = tv[1].tv_sec; + m.m2_i2 = tv[0].tv_nsec; + m.m2_i3 = tv[1].tv_nsec; + m.m2_p1 = NULL; + m.m2_s1 = 0; + + return(_syscall(VFS_PROC_NR, UTIMENS, &m)); +} diff --git a/lib/libc/sys-minix/futimes.c b/lib/libc/sys-minix/futimes.c new file mode 100644 index 000000000..7d7d26e0c --- /dev/null +++ b/lib/libc/sys-minix/futimes.c @@ -0,0 +1,31 @@ +#include +#include "namespace.h" +#include + +#include +#include + +#ifdef __weak_alias +__weak_alias(futimes, __futimes50) +#endif + +int futimes(int fd, const struct timeval tv[2]) +{ + message m; + + m.m2_i1 = fd; + if (tv == NULL) { + m.m2_l1 = m.m2_l2 = 0; + m.m2_i2 = m.m2_i3 = UTIME_NOW; + } + else { + m.m2_l1 = tv[0].tv_sec; + m.m2_l2 = tv[1].tv_sec; + m.m2_i2 = tv[0].tv_usec * 1000; + m.m2_i3 = tv[1].tv_usec * 1000; + } + m.m2_p1 = NULL; + m.m2_s1 = 0; + + return(_syscall(VFS_PROC_NR, UTIMENS, &m)); +} diff --git a/lib/libc/sys-minix/lutimes.c b/lib/libc/sys-minix/lutimes.c new file mode 100644 index 000000000..5b6fa5016 --- /dev/null +++ b/lib/libc/sys-minix/lutimes.c @@ -0,0 +1,36 @@ +#include +#include "namespace.h" +#include + +#include +#include +#include +#include +#include + +#ifdef __weak_alias +__weak_alias(lutimes, __lutimes50) +#endif + +int lutimes(const char *name, const struct timeval tv[2]) +{ + message m; + + if (name == NULL) return EINVAL; + if (name[0] == '\0') return ENOENT; /* X/Open requirement */ + m.m2_i1 = strlen(name) + 1; + m.m2_p1 = (char *) __UNCONST(name); + if (tv == NULL) { + m.m2_l1 = m.m2_l2 = 0; + m.m2_i2 = m.m2_i3 = UTIME_NOW; + } + else { + m.m2_l1 = tv[0].tv_sec; + m.m2_l2 = tv[1].tv_sec; + m.m2_i2 = tv[0].tv_usec * 1000; + m.m2_i3 = tv[1].tv_usec * 1000; + } + m.m2_s1 = AT_SYMLINK_NOFOLLOW; + + return(_syscall(VFS_PROC_NR, UTIMENS, &m)); +} diff --git a/lib/libc/sys-minix/utimensat.c b/lib/libc/sys-minix/utimensat.c new file mode 100644 index 000000000..26a1aa877 --- /dev/null +++ b/lib/libc/sys-minix/utimensat.c @@ -0,0 +1,43 @@ +#include +#include "namespace.h" +#include + +#include +#include +#include +#include +#include + +/* Implement a very large but not complete subset of the utimensat() + * Posix:2008/XOpen-7 function. + * Are handled the following cases: + * . utimensat(AT_FDCWD, "/some/absolute/path", , ) + * . utimensat(AT_FDCWD, "some/path", , ) + * . utimensat(fd, "/some/absolute/path", , ) although fd is useless here + * Are not handled the following cases: + * . utimensat(fd, "some/path", , ) path to a file relative to some open fd + */ +int utimensat(int fd, const char *name, const struct timespec tv[2], + int flags) +{ + message m; + static const struct timespec now[2] = { {0, UTIME_NOW}, {0, UTIME_NOW} }; + + if (tv == NULL) tv = now; + + if (name == NULL) return EINVAL; + if (name[0] == '\0') return ENOENT; /* POSIX requirement */ + if (fd != AT_FDCWD && name[0] != '/') return EINVAL; /* Not supported */ + m.m2_i1 = strlen(name) + 1; + m.m2_p1 = (char *) __UNCONST(name); + m.m2_l1 = tv[0].tv_sec; + m.m2_l2 = tv[1].tv_sec; + m.m2_i2 = tv[0].tv_nsec; + m.m2_i3 = tv[1].tv_nsec; + if ((unsigned)flags > SHRT_MAX) + return EINVAL; + else + m.m2_s1 = flags; + + return(_syscall(VFS_PROC_NR, UTIMENS, &m)); +} diff --git a/lib/libc/sys-minix/utimes.c b/lib/libc/sys-minix/utimes.c new file mode 100644 index 000000000..3e8c16f73 --- /dev/null +++ b/lib/libc/sys-minix/utimes.c @@ -0,0 +1,35 @@ +#include +#include "namespace.h" +#include + +#include +#include +#include +#include + +#ifdef __weak_alias +__weak_alias(utimes, __utimes50) +#endif + +int utimes(const char *name, const struct timeval tv[2]) +{ + message m; + + if (name == NULL) return EINVAL; + if (name[0] == '\0') return ENOENT; /* X/Open requirement */ + m.m2_i1 = strlen(name) + 1; + m.m2_p1 = (char *) __UNCONST(name); + if (tv == NULL) { + m.m2_l1 = m.m2_l2 = 0; + m.m2_i2 = m.m2_i3 = UTIME_NOW; + } + else { + m.m2_l1 = tv[0].tv_sec; + m.m2_l2 = tv[1].tv_sec; + m.m2_i2 = tv[0].tv_usec * 1000; + m.m2_i3 = tv[1].tv_usec * 1000; + } + m.m2_s1 = 0; + + return(_syscall(VFS_PROC_NR, UTIMENS, &m)); +} diff --git a/servers/vfs/param.h b/servers/vfs/param.h index 212676621..c31b58fe3 100644 --- a/servers/vfs/param.h +++ b/servers/vfs/param.h @@ -43,6 +43,10 @@ #define utime_file m2_p1 #define utime_length m2_i1 #define utime_strlen m2_i2 +#define utimens_fd m2_i1 +#define utimens_ansec m2_i2 +#define utimens_mnsec m2_i3 +#define utimens_flags m2_s1 #define whence m2_i2 #define svrctl_req m2_i1 #define svrctl_argp m2_p1 diff --git a/servers/vfs/proto.h b/servers/vfs/proto.h index 36c3ef0e8..6e4e40b0e 100644 --- a/servers/vfs/proto.h +++ b/servers/vfs/proto.h @@ -280,6 +280,7 @@ int do_lstat(void); /* time.c */ int do_utime(void); +int do_utimens(void); /* tll.c */ void tll_downgrade(tll_t *tllp); diff --git a/servers/vfs/table.c b/servers/vfs/table.c index b65542635..af3182edc 100644 --- a/servers/vfs/table.c +++ b/servers/vfs/table.c @@ -120,7 +120,7 @@ int (*call_vec[])(void) = { no_sys, /* 102 = (exec_restart) */ no_sys, /* 103 = unused */ no_sys, /* 104 = (getprocnr) */ - no_sys, /* 105 = unused */ + do_utimens, /* 105 = */ /* tentative (utimens) */ no_sys, /* 106 = unused */ no_sys, /* 107 = (getepinfo) */ no_sys, /* 108 = unused */ diff --git a/servers/vfs/time.c b/servers/vfs/time.c index 2695dc837..1343ecd94 100644 --- a/servers/vfs/time.c +++ b/servers/vfs/time.c @@ -2,12 +2,15 @@ * * The entry points into this file are * do_utime: perform the UTIME system call + * do_utimens: perform the UTIMENS system call */ #include "fs.h" #include #include #include +#include +#include #include "file.h" #include "fproc.h" #include "path.h" @@ -16,10 +19,13 @@ #include #include "vmnt.h" +#define UTIMENS_STYLE 0 /* utimes(2)/utimensat(2) style, named file */ +#define FUTIMENS_STYLE 1 /* futimens(2)/futimes(2) style, file desc. */ + /*===========================================================================* * do_utime * *===========================================================================*/ -int do_utime() +int do_utime(void) { /* Perform the utime(name, timep) system call. */ int r; @@ -72,3 +78,136 @@ int do_utime() put_vnode(vp); return(r); } + + +/*===========================================================================* + * do_utimens * + *===========================================================================*/ +int do_utimens(void) +{ +/* Perform the utimens(name, times, flag) system call, and its friends. + * Implement a very large but not complete subset of the utimensat() + * Posix:2008/XOpen-7 function. + * Are handled all the following cases: + * . utimensat(AT_FDCWD, "/some/absolute/path", , ) + * . utimensat(AT_FDCWD, "some/path", , ) + * . utimens("anything", ) really special case of the above two + * . lutimens("anything", ) also really special case of the above + * . utimensat(fd, "/some/absolute/path", , ) although fd is useless here + * . futimens(fd, ) + * Are not handled the following cases: + * . utimensat(fd, "some/path", , ) path to a file relative to some open fd + */ + int r, kind, lookup_flags; + struct vnode *vp; + struct filp *filp = NULL; /* initialization required by clueless GCC */ + struct vmnt *vmp; + struct timespec actim, modtim, now, newactim, newmodtim; + char fullpath[PATH_MAX]; + struct lookup resolve; + vir_bytes vname; + size_t vname_length; + + /* The case times==NULL is handled by the caller, replaced with UTIME_NOW */ + actim.tv_sec = job_m_in.utime_actime; + actim.tv_nsec = job_m_in.utimens_ansec; + modtim.tv_sec = job_m_in.utime_modtime; + modtim.tv_nsec = job_m_in.utimens_mnsec; + + if (job_m_in.utime_file != NULL) { + kind = UTIMENS_STYLE; + if (job_m_in.utimens_flags & ~AT_SYMLINK_NOFOLLOW) + return EINVAL; /* unknown flag */ + /* Temporarily open the file */ + vname = (vir_bytes) job_m_in.utime_file; + vname_length = (size_t) job_m_in.utime_length; + if (job_m_in.utimens_flags & AT_SYMLINK_NOFOLLOW) + lookup_flags = PATH_RET_SYMLINK; + else + lookup_flags = PATH_NOFLAGS; + lookup_init(&resolve, fullpath, lookup_flags, &vmp, &vp); + resolve.l_vmnt_lock = VMNT_READ; + resolve.l_vnode_lock = VNODE_READ; + /* Temporarily open the file */ + if (fetch_name(vname, vname_length, fullpath) != OK) return(err_code); + if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code); + } + else { + kind = FUTIMENS_STYLE; + /* Change timestamps on already-opened fd. Is it valid? */ + if (job_m_in.utimens_flags != 0) + return EINVAL; /* unknown flag */ + if ((filp = get_filp(job_m_in.utimens_fd, VNODE_READ)) == NULL) + return err_code; + vp = filp->filp_vno; + } + + r = OK; + /* Only the owner of a file or the super user can change timestamps. */ + if (vp->v_uid != fp->fp_effuid && fp->fp_effuid != SU_UID) r = EPERM; + /* Need write permission (or super user) to 'touch' the file */ + if (r != OK && actim.tv_nsec == UTIME_NOW + && modtim.tv_nsec == UTIME_NOW) r = forbidden(fp, vp, W_BIT); + if (read_only(vp) != OK) r = EROFS; /* Not even su can touch if R/O */ + + if (r == OK) { + /* Do we need to ask for current time? */ + if (actim.tv_nsec == UTIME_NOW + || actim.tv_nsec == UTIME_OMIT + || modtim.tv_nsec == UTIME_NOW + || modtim.tv_nsec == UTIME_OMIT) { + now = clock_timespec(); + } + + /* Build the request */ + switch (actim.tv_nsec) { + case UTIME_NOW: + newactim = now; + break; + case UTIME_OMIT: + newactim.tv_nsec = UTIME_OMIT; + /* Be nice with old FS, put a sensible value in + * otherwise not used field for seconds + */ + newactim.tv_sec = now.tv_sec; + break; + default: + if ( (unsigned)actim.tv_nsec >= 1000000000) + r = EINVAL; + else + newactim = actim; + break; + } + switch (modtim.tv_nsec) { + case UTIME_NOW: + newmodtim = now; + break; + case UTIME_OMIT: + newmodtim.tv_nsec = UTIME_OMIT; + /* Be nice with old FS, put a sensible value */ + newmodtim.tv_sec = now.tv_sec; + break; + default: + if ( (unsigned)modtim.tv_nsec >= 1000000000) + r = EINVAL; + else + newmodtim = modtim; + break; + } + } + + if (r == OK) + /* Issue request */ + r = req_utime(vp->v_fs_e, vp->v_inode_nr, &newactim, &newmodtim); + + if (kind == UTIMENS_STYLE) { + /* Close the temporary */ + unlock_vnode(vp); + unlock_vmnt(vmp); + put_vnode(vp); + } + else { /* Change timestamps on opened fd. */ + unlock_filp(filp); + } + return r; +} diff --git a/share/mk/bsd.own.mk b/share/mk/bsd.own.mk index c67e9a417..c7e5190ae 100644 --- a/share/mk/bsd.own.mk +++ b/share/mk/bsd.own.mk @@ -1053,16 +1053,12 @@ MKTRACE:= no # install(1) parameters. # COPY?= -c -.if ${HOST_OSTYPE:C/\-.*//} != "Minix" .if ${MKUPDATE} == "no" PRESERVE?= .else -#LSC: Not supported by MINIX install PRESERVE?= -p .endif -#XXX: Not supported by MINIX install RENAME?= -r -.endif # != "Minix" HRDLINK?= -l h SYMLINK?= -l s diff --git a/sys/sys/fcntl.h b/sys/sys/fcntl.h index 15b4a0c21..0fab6a5bc 100644 --- a/sys/sys/fcntl.h +++ b/sys/sys/fcntl.h @@ -185,14 +185,18 @@ struct flock { /* * Constants for X/Open Extended API set 2 (a.k.a. C063) + * linkat(2) - also part of Posix-2008/XPG7 */ -#if defined(_INCOMPLETE_XOPEN_C063) || defined(_KERNEL) +#if (_POSIX_C_SOURCE - 0) >= 200809L || (_XOPEN_SOURCE - 0) >= 700 || \ + defined(_NETBSD_SOURCE) +#if defined(_INCOMPLETE_XOPEN_C063) || defined(_KERNEL) || defined(__minix) #define AT_FDCWD -100 /* Use cwd for relative link target */ -#define AT_EACCESS 0x100 /* Use euig/egid for access checks */ +#define AT_EACCESS 0x100 /* Use euid/egid for access checks */ #define AT_SYMLINK_NOFOLLOW 0x200 /* Do not follow symlinks */ #define AT_SYMLINK_FOLLOW 0x400 /* Follow symlinks */ #define AT_REMOVEDIR 0x800 /* Remove directory only */ #endif +#endif #ifndef _KERNEL diff --git a/sys/sys/stat.h b/sys/sys/stat.h index 970d2b5a1..8ca19b735 100644 --- a/sys/sys/stat.h +++ b/sys/sys/stat.h @@ -295,7 +295,6 @@ int lchflags(const char *, unsigned long); int lchmod(const char *, mode_t); #endif /* defined(_NETBSD_SOURCE) && !defined(__minix) */ -#ifndef __minix #ifndef __LIBC12_SOURCE__ /* * X/Open Extended API set 2 (a.k.a. C063) @@ -315,7 +314,6 @@ int lutimens(const char *, const struct timespec *); int futimens(int, const struct timespec *); #endif #endif -#endif /* !__minix */ __END_DECLS diff --git a/sys/sys/time.h b/sys/sys/time.h index b4f809e40..7bbaf095a 100644 --- a/sys/sys/time.h +++ b/sys/sys/time.h @@ -283,13 +283,14 @@ int gettimeofday(struct timeval * __restrict, void *__restrict); int setitimer(int, const struct itimerval * __restrict, struct itimerval * __restrict) __RENAME(__setitimer50); #endif /* _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE || _NETBSD_SOURCE */ +#if defined(_XOPEN_SOURCE) || defined(_NETBSD_SOURCE) +int utimes(const char *, const struct timeval [2]) __RENAME(__utimes50); +#endif /* _XOPEN_SOURCE || _NETBSD_SOURCE */ #if defined(_NETBSD_SOURCE) || defined(HAVE_NBTOOL_CONFIG_H) int adjtime(const struct timeval *, struct timeval *) __RENAME(__adjtime50); -#ifndef __minix int futimes(int, const struct timeval [2]) __RENAME(__futimes50); int lutimes(const char *, const struct timeval [2]) __RENAME(__lutimes50); -#endif /* !__minix */ int settimeofday(const struct timeval * __restrict, const void *__restrict) __RENAME(__settimeofday50); #endif /* _NETBSD_SOURCE */ diff --git a/usr.bin/gzip/gzip.c b/usr.bin/gzip/gzip.c index fdbdbc537..cd4837807 100644 --- a/usr.bin/gzip/gzip.c +++ b/usr.bin/gzip/gzip.c @@ -1081,10 +1081,8 @@ copymodes(int fd, const struct stat *sbp, const char *file) TIMESPEC_TO_TIMEVAL(×[0], &sb.st_atimespec); TIMESPEC_TO_TIMEVAL(×[1], &sb.st_mtimespec); -#ifndef __minix if (futimes(fd, times) < 0) maybe_warn("couldn't utimes: %s", file); -#endif } #endif diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c index 1d479fd65..47e6b2c78 100644 --- a/usr.bin/xinstall/xinstall.c +++ b/usr.bin/xinstall/xinstall.c @@ -251,9 +251,6 @@ main(int argc, char *argv[]) break; case 'p': dopreserve = 1; -#ifdef __minix - warn("Minix lacks support for futimes(3)/utimes(2)"); -#endif break; case 'r': dorename = 1; @@ -774,7 +771,6 @@ install(char *from_name, char *to_name, u_int flags) /* * Preserve the date of the source file. */ -#ifndef __minix if (dopreserve) { #if HAVE_FUTIMES if (futimes(to_fd, tv) == -1) @@ -784,7 +780,6 @@ install(char *from_name, char *to_name, u_int flags) warn("%s: utimes", to_name); #endif } -#endif (void)close(to_fd); diff --git a/usr.sbin/mtree/compare.c b/usr.sbin/mtree/compare.c index 7686f4242..e2ccbf016 100644 --- a/usr.sbin/mtree/compare.c +++ b/usr.sbin/mtree/compare.c @@ -140,12 +140,6 @@ lchown(const char *path, uid_t owner, gid_t group) return -1; } #endif - -static int -utimes(const char *path, const struct timeval times[2]) -{ - return -1; -} #endif int