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.
This commit is contained in:
Antoine Leca
2011-12-24 15:02:54 +01:00
committed by Ben Gras
parent 88414c568c
commit 9131e98a7d
19 changed files with 385 additions and 16 deletions

View File

@@ -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

53
lib/libc/gen/utimens.c Normal file
View File

@@ -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 <sys/cdefs.h>
#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 <fcntl.h>
#include <sys/stat.h>
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);
}

View File

@@ -69,9 +69,6 @@ timer_delete
timer_gettime
timer_settime
undelete
utimes
lutimes
futimes
utrace
uuidgen
vadvise

View File

@@ -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.

View File

@@ -0,0 +1,23 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <sys/stat.h>
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));
}

View File

@@ -0,0 +1,31 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <sys/stat.h>
#include <sys/time.h>
#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));
}

View File

@@ -0,0 +1,36 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#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));
}

View File

@@ -0,0 +1,43 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
/* 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));
}

View File

@@ -0,0 +1,35 @@
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <string.h>
#include <errno.h>
#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));
}