4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
30 * Portions of this source code were derived from Berkeley 4.3 BSD
31 * under license from the Regents of the University of California.
34 #include <sys/param.h>
35 #include <sys/isa_defs.h>
36 #include <sys/types.h>
38 #include <sys/sysmacros.h>
39 #include <sys/systm.h>
40 #include <sys/errno.h>
41 #include <sys/vnode.h>
44 #include <sys/debug.h>
45 #include <sys/model.h>
46 #include <sys/fcntl.h>
48 #include <sys/pathname.h>
51 cfutimesat(int fd
, char *fname
, int nmflag
, vattr_t
*vap
, int flags
, int follow
)
54 vnode_t
*startvp
, *vp
;
58 if (fd
== AT_FDCWD
&& fname
== NULL
)
59 return (set_errno(EFAULT
));
61 if (nmflag
== 1 || (nmflag
== 2 && fname
!= NULL
)) {
62 if (copyin(fname
, &startchar
, sizeof (char)))
63 return (set_errno(EFAULT
));
72 * is this absolute path?
74 if (startchar
!= '/') {
75 if ((fp
= getf(fd
)) == NULL
)
76 return (set_errno(EBADF
));
77 startvp
= fp
->f_vnode
;
85 if ((nmflag
== 1) || ((nmflag
== 2) && (fname
!= NULL
))) {
86 if ((error
= lookupnameat(fname
, UIO_USERSPACE
,
87 follow
, NULLVPP
, &vp
, startvp
)) != 0) {
90 return (set_errno(error
));
97 if (startvp
!= NULL
) {
101 if (vn_is_readonly(vp
)) {
104 error
= fop_setattr(vp
, vap
, flags
, CRED(), NULL
);
109 return (set_errno(error
));
114 get_timespec_vattr(timespec_t
*tsptr
, struct vattr
*vattr
, int *flags
)
121 if (get_udatamodel() == DATAMODEL_NATIVE
) {
122 if (copyin(tsptr
, ts
, sizeof (ts
)))
125 timespec32_t ts32
[2];
127 if (copyin(tsptr
, ts32
, sizeof (ts32
)))
129 TIMESPEC32_TO_TIMESPEC(&ts
[0], &ts32
[0]);
130 TIMESPEC32_TO_TIMESPEC(&ts
[1], &ts32
[1]);
132 if (ts
[0].tv_nsec
== UTIME_NOW
|| ts
[1].tv_nsec
== UTIME_NOW
)
135 if (ts
[0].tv_nsec
== UTIME_OMIT
) {
139 if (ts
[0].tv_nsec
== UTIME_NOW
)
141 else if (ts
[0].tv_nsec
< 0 || ts
[0].tv_nsec
>= NANOSEC
)
144 if (ts
[1].tv_nsec
== UTIME_OMIT
) {
148 if (ts
[1].tv_nsec
== UTIME_NOW
)
150 else if (ts
[1].tv_nsec
< 0 || ts
[1].tv_nsec
>= NANOSEC
)
153 vattr
->va_atime
= ts
[0];
154 vattr
->va_mtime
= ts
[1];
155 vattr
->va_mask
= mask
;
159 vattr
->va_atime
= now
;
160 vattr
->va_mtime
= now
;
161 vattr
->va_mask
= VATTR_ATIME
| VATTR_MTIME
;
169 futimens(int fd
, timespec_t
*tsptr
)
175 if ((error
= get_timespec_vattr(tsptr
, &vattr
, &flags
)) != 0)
176 return (set_errno(error
));
178 return (cfutimesat(fd
, NULL
, 2, &vattr
, flags
, FOLLOW
));
182 utimensat(int fd
, char *fname
, timespec_t
*tsptr
, int flag
)
188 if ((error
= get_timespec_vattr(tsptr
, &vattr
, &flags
)) != 0)
189 return (set_errno(error
));
191 return (cfutimesat(fd
, fname
, 1, &vattr
, flags
,
192 (flag
& AT_SYMLINK_NOFOLLOW
)? NO_FOLLOW
: FOLLOW
));
197 uintptr_t arg1
, uintptr_t arg2
, uintptr_t arg3
, uintptr_t arg4
)
201 return (futimens((int)arg1
, (timespec_t
*)arg2
));
203 return (utimensat((int)arg1
, (char *)arg2
,
204 (timespec_t
*)arg3
, (int)arg4
));
206 return (set_errno(EINVAL
));