Add futimens(2) and part of utimnsat(2)

This commit is contained in:
manu 2011-08-17 07:22:33 +00:00
parent 47d9241c1a
commit 5b61306f9b
5 changed files with 167 additions and 22 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1662 2011/08/15 15:14:00 wiz Exp $
# $NetBSD: mi,v 1.1663 2011/08/17 07:22:34 manu Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -4680,6 +4680,7 @@
./usr/share/man/cat2/fsync_range.0 comp-c-catman .cat
./usr/share/man/cat2/ftruncate.0 comp-c-catman .cat
./usr/share/man/cat2/futimes.0 comp-c-catman .cat
./usr/share/man/cat2/futimens.0 comp-c-catman .cat
./usr/share/man/cat2/getcontext.0 comp-c-catman .cat
./usr/share/man/cat2/getdents.0 comp-c-catman .cat
./usr/share/man/cat2/getdirentries.0 comp-obsolete obsolete
@ -4865,6 +4866,7 @@
./usr/share/man/cat2/undelete.0 comp-c-catman .cat
./usr/share/man/cat2/unlink.0 comp-c-catman .cat
./usr/share/man/cat2/unmount.0 comp-c-catman .cat
./usr/share/man/cat2/utimensat.0 comp-c-catman .cat
./usr/share/man/cat2/utimes.0 comp-c-catman .cat
./usr/share/man/cat2/utrace.0 comp-c-catman .cat
./usr/share/man/cat2/uuidgen.0 comp-c-catman .cat
@ -10864,6 +10866,7 @@
./usr/share/man/html2/fsync_range.html comp-c-htmlman html
./usr/share/man/html2/ftruncate.html comp-c-htmlman html
./usr/share/man/html2/futimes.html comp-c-htmlman html
./usr/share/man/html2/futimens.html comp-c-htmlman html
./usr/share/man/html2/getcontext.html comp-c-htmlman html
./usr/share/man/html2/getdents.html comp-c-htmlman html
./usr/share/man/html2/getegid.html comp-c-htmlman html
@ -11037,6 +11040,7 @@
./usr/share/man/html2/undelete.html comp-c-htmlman html
./usr/share/man/html2/unlink.html comp-c-htmlman html
./usr/share/man/html2/unmount.html comp-c-htmlman html
./usr/share/man/html2/utimensat.html comp-c-htmlman html
./usr/share/man/html2/utimes.html comp-c-htmlman html
./usr/share/man/html2/utrace.html comp-c-htmlman html
./usr/share/man/html2/uuidgen.html comp-c-htmlman html
@ -16822,6 +16826,7 @@
./usr/share/man/man2/fsync_range.2 comp-c-man .man
./usr/share/man/man2/ftruncate.2 comp-c-man .man
./usr/share/man/man2/futimes.2 comp-c-man .man
./usr/share/man/man2/futimens.2 comp-c-man .man
./usr/share/man/man2/getcontext.2 comp-c-man .man
./usr/share/man/man2/getdents.2 comp-c-man .man
./usr/share/man/man2/getegid.2 comp-c-man .man
@ -17005,6 +17010,7 @@
./usr/share/man/man2/undelete.2 comp-c-man .man
./usr/share/man/man2/unlink.2 comp-c-man .man
./usr/share/man/man2/unmount.2 comp-c-man .man
./usr/share/man/man2/utimensat.2 comp-c-man .man
./usr/share/man/man2/utimes.2 comp-c-man .man
./usr/share/man/man2/utrace.2 comp-c-man .man
./usr/share/man/man2/uuidgen.2 comp-c-man .man

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.inc,v 1.208 2011/08/08 12:08:53 manu Exp $
# $NetBSD: Makefile.inc,v 1.209 2011/08/17 07:22:33 manu Exp $
# @(#)Makefile.inc 8.3 (Berkeley) 10/24/94
# sys sources
@ -90,7 +90,7 @@ ASM= access.S acct.S \
faccessat.S fchdir.S fchflags.S fchmod.S fchmodat.S fchown.S \
fchownat.S fchroot.S fexecve.S __fhopen40.S __fhstat50.S \
__fhstatvfs140.S fktrace.S flock.S fpathconf.S __fstat50.S \
fstatvfs1.S fstatat.S __futimes50.S \
fstatvfs1.S fstatat.S __futimes50.S futimens.S \
__getcwd.S __getdents30.S __getfh30.S getvfsstat.S getgroups.S\
__getitimer50.S __getlogin.S getpeername.S getpgid.S getpgrp.S \
getpriority.S getrlimit.S __getrusage50.S getsid.S \
@ -315,6 +315,7 @@ MLINKS+=statvfs.2 fstatvfs1.2
MLINKS+=syscall.2 __syscall.2
MLINKS+=truncate.2 ftruncate.2
MLINKS+=utimes.2 futimes.2 utimes.2 lutimes.2
MLINKS+=utimes.2 futimens.2 utimes.2 utimensat.2
MLINKS+=wait.2 wait3.2 wait.2 wait4.2 wait.2 waitpid.2
MLINKS+=write.2 writev.2 write.2 pwrite.2 write.2 pwritev.2
MLINKS+=pipe.2 pipe2.2

View File

@ -1,4 +1,4 @@
.\" $NetBSD: utimes.2,v 1.26 2010/04/29 17:02:38 jruoho Exp $
.\" $NetBSD: utimes.2,v 1.27 2011/08/17 07:22:33 manu Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@ -35,7 +35,9 @@
.Sh NAME
.Nm utimes ,
.Nm lutimes ,
.Nm futimes
.Nm futimes ,
.Nm futimens ,
.Nm utimensat
.Nd set file access and modification times
.Sh LIBRARY
.Lb libc
@ -47,6 +49,11 @@
.Fn lutimes "const char *path" "const struct timeval times[2]"
.Ft int
.Fn futimes "int fd" "const struct timeval times[2]"
.Ft int
.Fn futimens "int fd" "const struct timespec times[2]"
.Ft int
.Fn utimensat "int fd" "const char *path" "const struct timespec times[2]" "\
int flag"
.Sh DESCRIPTION
The access and modification times of the file named by
.Fa path
@ -93,15 +100,52 @@ changes the access and modification times of the link,
while
.Fn utimes
changes the times of the file the link references.
.Pp
.Fn futimens
is like
.Fn futimes
except that time is specified with nanosecond instead of microseconds.
.Pp
.Fn utimensat
also allows time to be specifed with nanoseconds. When it operates on
a symbolic link, it will change the target's time if
.Ar follow
is unset.
If
.Ar follow
is set to
.Dv AT_SYMLINK_NOFOLLOW ,
the symbolic link's dates are changed.
.Pp
The nanosecond fields for
.Fn futimes
and
.Fn utimensat
can be set to the special value
.Dv UTIME_NOW
to set the current time, or to
.Dv UTIME_OMIT
to let the time unchanged (this allows changing access time but not
modification time, and vice-versa).
.Pp
.Fn utimensat
is partially implemented.
It will return
.Er ENOSYS
for
.Fa fd
values different than
.Dv AT_FDCWD .
.Sh RETURN VALUES
Upon successful completion, a value of 0 is returned.
Otherwise, a value of \-1 is returned and
.Va errno
is set to indicate the error.
.Sh ERRORS
.Fn utimes
.Fn utimes ,
.Fn lutimes ,
and
.Fn lutimes
.Fn utimensat
will fail if:
.Bl -tag -width Er
.It Bq Er EACCES
@ -144,6 +188,8 @@ The file system containing the file is mounted read-only.
.El
.Pp
.Fn futimes
and
.Fn futimens
will fail if:
.Bl -tag -width Er
.It Bq Er EACCES
@ -184,6 +230,11 @@ function conforms to
It was however marked as legacy in the
.St -p1003.1-2004
revision.
.Fn futimens
and
.Fn utmensat
functions conform to
.St -p1003.1-2008 .
.Sh HISTORY
The
.Fn utimes
@ -199,3 +250,11 @@ function call appeared in
.Nx 1.3 .
Birthtime setting support was added in
.Nx 5.0 .
.Fn futimens
and
.Fn utimensat
functions calls appreared in
.Nx 6.0
.Sh BUGS
.Fn utimensat
is partially implemented.

View File

@ -1,4 +1,4 @@
$NetBSD: syscalls.master,v 1.251 2011/08/08 12:08:53 manu Exp $
$NetBSD: syscalls.master,v 1.252 2011/08/17 07:22:34 manu Exp $
; @(#)syscalls.master 8.2 (Berkeley) 1/13/94
@ -923,3 +923,5 @@
const char *path2); }
471 STD RUMP { int|sys||unlinkat(int fd, const char *path, \
int flag); }
472 STD RUMP { int|sys||futimens(int fd, \
const struct timespec *tptr); }

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_syscalls.c,v 1.433 2011/08/08 12:08:53 manu Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.434 2011/08/17 07:22:34 manu Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.433 2011/08/08 12:08:53 manu Exp $");
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.434 2011/08/17 07:22:34 manu Exp $");
#ifdef _KERNEL_OPT
#include "opt_fileassoc.h"
@ -3031,6 +3031,26 @@ sys___futimes50(struct lwp *l, const struct sys___futimes50_args *uap,
return (error);
}
int
sys_futimens(struct lwp *l, const struct sys_futimens_args *uap,
register_t *retval)
{
/* {
syscallarg(int) fd;
syscallarg(const struct timespec *) tptr;
} */
int error;
file_t *fp;
/* fd_getvnode() will use the descriptor for us */
if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
return (error);
error = do_sys_utimens(l, fp->f_data, NULL, 0, SCARG(uap, tptr),
UIO_USERSPACE);
fd_putfile(SCARG(uap, fd));
return (error);
}
/*
* Set the access and modification times given a path name; this
* version does not follow links.
@ -3058,6 +3078,20 @@ sys_utimensat(struct lwp *l, const struct sys_utimensat_args *uap,
syscallarg(const struct timespec *) tptr;
syscallarg(int) flag;
} */
int follow;
const struct timespec *tptr;
/*
* Specified fd is not yet implemented
*/
if (SCARG(uap, fd) != AT_FDCWD)
return ENOSYS;
tptr = SCARG(uap, tptr);
follow = (SCARG(uap, flag) & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW;
return do_sys_utimens(l, NULL, SCARG(uap, path), follow,
tptr, UIO_USERSPACE);
return ENOSYS;
}
@ -3066,8 +3100,8 @@ sys_utimensat(struct lwp *l, const struct sys_utimensat_args *uap,
* Common routine to set access and modification times given a vnode.
*/
int
do_sys_utimes(struct lwp *l, struct vnode *vp, const char *path, int flag,
const struct timeval *tptr, enum uio_seg seg)
do_sys_utimens(struct lwp *l, struct vnode *vp, const char *path, int flag,
const struct timespec *tptr, enum uio_seg seg)
{
struct vattr vattr;
int error, dorele = 0;
@ -3092,19 +3126,20 @@ do_sys_utimes(struct lwp *l, struct vnode *vp, const char *path, int flag,
nanotime(&ts[0]);
ts[1] = ts[0];
} else {
struct timeval tv[2];
vanull = false;
if (seg != UIO_SYSSPACE) {
error = copyin(tptr, tv, sizeof (tv));
error = copyin(tptr, ts, sizeof (ts));
if (error != 0)
return error;
tptr = tv;
}
TIMEVAL_TO_TIMESPEC(&tptr[0], &ts[0]);
TIMEVAL_TO_TIMESPEC(&tptr[1], &ts[1]);
}
if (ts[0].tv_nsec == UTIME_NOW)
nanotime(&ts[0]);
if (ts[1].tv_nsec == UTIME_NOW)
nanotime(&ts[1]);
if (vp == NULL) {
/* note: SEG describes TPTR, not PATH; PATH is always user */
error = namei_simple_user(path, sflags, &vp);
@ -3117,10 +3152,16 @@ do_sys_utimes(struct lwp *l, struct vnode *vp, const char *path, int flag,
setbirthtime = (VOP_GETATTR(vp, &vattr, l->l_cred) == 0 &&
timespeccmp(&ts[1], &vattr.va_birthtime, <));
vattr_null(&vattr);
vattr.va_atime = ts[0];
vattr.va_mtime = ts[1];
if (setbirthtime)
vattr.va_birthtime = ts[1];
if (ts[0].tv_nsec != UTIME_OMIT)
vattr.va_atime = ts[0];
if (ts[1].tv_nsec != UTIME_OMIT) {
vattr.va_mtime = ts[1];
if (setbirthtime)
vattr.va_birthtime = ts[1];
}
if (vanull)
vattr.va_vaflags |= VA_UTIMES_NULL;
error = VOP_SETATTR(vp, &vattr, l->l_cred);
@ -3132,6 +3173,42 @@ do_sys_utimes(struct lwp *l, struct vnode *vp, const char *path, int flag,
return error;
}
int
do_sys_utimes(struct lwp *l, struct vnode *vp, const char *path, int flag,
const struct timeval *tptr, enum uio_seg seg)
{
struct timespec ts[2];
struct timespec *tsptr = NULL;
int error;
if (tptr != NULL) {
struct timeval tv[2];
if (seg != UIO_SYSSPACE) {
error = copyin(tptr, tv, sizeof (tv));
if (error != 0)
return error;
tptr = tv;
}
if ((tv[0].tv_usec == UTIME_NOW) ||
(tv[0].tv_usec == UTIME_OMIT))
ts[0].tv_nsec = tv[0].tv_usec;
else
TIMEVAL_TO_TIMESPEC(&tptr[0], &ts[0]);
if ((tv[1].tv_usec == UTIME_NOW) ||
(tv[1].tv_usec == UTIME_OMIT))
ts[1].tv_nsec = tv[1].tv_usec;
else
TIMEVAL_TO_TIMESPEC(&tptr[1], &ts[1]);
tsptr = &ts[0];
}
return do_sys_utimens(l, vp, path, flag, tsptr, UIO_SYSSPACE);
}
/*
* Truncate a file given its path name.
*/