]>
git.saurik.com Git - apple/xnu.git/blob - libsyscall/wrappers/utimensat.c
2 * Copyright (c) 2006, 2017 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <sys/types.h>
28 #include <sys/fcntl.h>
32 extern int __gettimeofday(struct timeval
*, struct timezone
*);
33 extern int __commpage_gettimeofday(struct timeval
*);
35 static struct timespec times_now
[2] = {
36 { .tv_nsec
= UTIME_NOW
},
37 { .tv_nsec
= UTIME_NOW
}
41 * Resolve any UTIME_NOW or UTIME_OMIT and return the attributes buffer and
42 * attributes to pass. Assumes times_in is writable.
45 prepare_times_array_and_attrs(struct timespec times_in
[2],
46 struct timespec times_out
[2], size_t *times_out_size
)
48 if (times_in
[0].tv_nsec
== UTIME_OMIT
&&
49 times_in
[1].tv_nsec
== UTIME_OMIT
) {
53 if (times_in
[0].tv_nsec
== UTIME_NOW
||
54 times_in
[1].tv_nsec
== UTIME_NOW
) {
55 struct timespec now
= {};
58 * TODO: Replace with nanosecond time when available
61 if (__commpage_gettimeofday(&tv
) != 0) {
62 __gettimeofday(&tv
, NULL
);
64 TIMEVAL_TO_TIMESPEC(&tv
, &now
);
67 if (times_in
[0].tv_nsec
== UTIME_NOW
) {
70 if (times_in
[1].tv_nsec
== UTIME_NOW
) {
77 struct timespec
*times_cursor
= times_out
;
78 if (times_in
[1].tv_nsec
!= UTIME_OMIT
) {
79 attrs
|= ATTR_CMN_MODTIME
;
80 *times_cursor
++ = times_in
[1];
81 *times_out_size
+= sizeof(struct timespec
);
83 if (times_in
[0].tv_nsec
!= UTIME_OMIT
) {
84 attrs
|= ATTR_CMN_ACCTIME
;
85 *times_cursor
= times_in
[0];
86 *times_out_size
+= sizeof(struct timespec
);
92 futimens(int fd
, const struct timespec _times_in
[2])
94 struct timespec times_in
[2];
95 if (_times_in
!= NULL
) {
96 memcpy(×_in
, _times_in
, sizeof(times_in
));
98 memcpy(×_in
, times_now
, sizeof(times_in
));
101 size_t attrbuf_size
= 0;
102 struct timespec times_out
[2] = {};
103 struct attrlist a
= {
104 .bitmapcount
= ATTR_BIT_MAP_COUNT
106 a
.commonattr
= prepare_times_array_and_attrs(times_in
, times_out
, &attrbuf_size
);
108 return fsetattrlist(fd
, &a
, ×_out
, attrbuf_size
, 0);
112 utimensat(int fd
, const char *path
, const struct timespec _times_in
[2], int flags
)
114 struct timespec times_in
[2];
115 if (_times_in
!= NULL
) {
116 memcpy(×_in
, _times_in
, sizeof(times_in
));
118 memcpy(×_in
, times_now
, sizeof(times_in
));
121 size_t attrbuf_size
= 0;
122 struct timespec times_out
[2] = {};
123 struct attrlist a
= {
124 .bitmapcount
= ATTR_BIT_MAP_COUNT
126 a
.commonattr
= prepare_times_array_and_attrs(times_in
, times_out
, &attrbuf_size
);
129 if (flags
& AT_SYMLINK_NOFOLLOW
) {
130 flags_out
|= FSOPT_NOFOLLOW
;
133 return setattrlistat(fd
, path
, &a
, ×_out
, attrbuf_size
, flags_out
);