xref: /haiku/src/system/libroot/posix/sys/utimes.c (revision 6c00aabc9e209639ff2753ba8cc2acf3f1b5ec95)
121470984SAxel Dörfler /*
2*6c00aabcSIngo Weinhold  * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
36a9eee58SAxel Dörfler  * Copyright 2006-2009, Axel Dörfler, axeld@pinc-software.de.
421470984SAxel Dörfler  * Distributed under the terms of the MIT License.
521470984SAxel Dörfler  */
621470984SAxel Dörfler 
721470984SAxel Dörfler 
8*6c00aabcSIngo Weinhold #define B_ENABLE_INCOMPLETE_POSIX_AT_SUPPORT 1
9*6c00aabcSIngo Weinhold 	// make the *at() functions and AT_* macros visible
10*6c00aabcSIngo Weinhold 
1121470984SAxel Dörfler #include <sys/time.h>
126a9eee58SAxel Dörfler 
136a9eee58SAxel Dörfler #include <errno.h>
146a9eee58SAxel Dörfler 
156a9eee58SAxel Dörfler #include <NodeMonitor.h>
166a9eee58SAxel Dörfler 
176a9eee58SAxel Dörfler #include <syscalls.h>
18*6c00aabcSIngo Weinhold #include <syscall_utils.h>
1921470984SAxel Dörfler 
2021470984SAxel Dörfler 
2121470984SAxel Dörfler int
226a9eee58SAxel Dörfler utimes(const char* path, const struct timeval times[2])
2321470984SAxel Dörfler {
246a9eee58SAxel Dörfler 	struct stat stat;
256a9eee58SAxel Dörfler 	status_t status;
2621470984SAxel Dörfler 
2721470984SAxel Dörfler 	if (times != NULL) {
286a9eee58SAxel Dörfler 		stat.st_atim.tv_sec = times[0].tv_sec;
296a9eee58SAxel Dörfler 		stat.st_atim.tv_nsec = times[0].tv_usec * 1000;
3021470984SAxel Dörfler 
316a9eee58SAxel Dörfler 		stat.st_mtim.tv_sec = times[1].tv_sec;
326a9eee58SAxel Dörfler 		stat.st_mtim.tv_nsec = times[1].tv_usec * 1000;
336a9eee58SAxel Dörfler 	} else {
346a9eee58SAxel Dörfler 		bigtime_t now = real_time_clock_usecs();
356a9eee58SAxel Dörfler 		stat.st_atim.tv_sec = stat.st_mtim.tv_sec = now / 1000000;
366a9eee58SAxel Dörfler 		stat.st_atim.tv_nsec = stat.st_mtim.tv_nsec = (now % 1000000) * 1000;
376a9eee58SAxel Dörfler 	}
386a9eee58SAxel Dörfler 
396a9eee58SAxel Dörfler 	status = _kern_write_stat(-1, path, true, &stat, sizeof(struct stat),
406a9eee58SAxel Dörfler 		B_STAT_MODIFICATION_TIME | B_STAT_ACCESS_TIME);
416a9eee58SAxel Dörfler 
426a9eee58SAxel Dörfler 	RETURN_AND_SET_ERRNO(status);
4321470984SAxel Dörfler }
4421470984SAxel Dörfler 
45*6c00aabcSIngo Weinhold 
46*6c00aabcSIngo Weinhold int
47*6c00aabcSIngo Weinhold utimensat(int fd, const char *path, const struct timespec times[2], int flag)
48*6c00aabcSIngo Weinhold {
49*6c00aabcSIngo Weinhold 	struct stat stat;
50*6c00aabcSIngo Weinhold 	status_t status;
51*6c00aabcSIngo Weinhold 	uint32 mask = 0;
52*6c00aabcSIngo Weinhold 
53*6c00aabcSIngo Weinhold 	// Init the stat time fields to the current time, if at least one time is
54*6c00aabcSIngo Weinhold 	// supposed to be set to it.
55*6c00aabcSIngo Weinhold 	if (times == NULL || times[0].tv_nsec == UTIME_NOW
56*6c00aabcSIngo Weinhold 		|| times[1].tv_nsec == UTIME_NOW) {
57*6c00aabcSIngo Weinhold 		bigtime_t now = real_time_clock_usecs();
58*6c00aabcSIngo Weinhold 		stat.st_atim.tv_sec = stat.st_mtim.tv_sec = now / 1000000;
59*6c00aabcSIngo Weinhold 		stat.st_atim.tv_nsec = stat.st_mtim.tv_nsec = (now % 1000000) * 1000;
60*6c00aabcSIngo Weinhold 	}
61*6c00aabcSIngo Weinhold 
62*6c00aabcSIngo Weinhold 	if (times != NULL) {
63*6c00aabcSIngo Weinhold 		// access time
64*6c00aabcSIngo Weinhold 		if (times[0].tv_nsec != UTIME_OMIT) {
65*6c00aabcSIngo Weinhold 			mask |= B_STAT_ACCESS_TIME;
66*6c00aabcSIngo Weinhold 
67*6c00aabcSIngo Weinhold 			if (times[0].tv_nsec != UTIME_NOW) {
68*6c00aabcSIngo Weinhold 				if (times[0].tv_nsec < 0 || times[0].tv_nsec > 999999999)
69*6c00aabcSIngo Weinhold 					RETURN_AND_SET_ERRNO(EINVAL);
70*6c00aabcSIngo Weinhold 			}
71*6c00aabcSIngo Weinhold 
72*6c00aabcSIngo Weinhold 			stat.st_atim = times[0];
73*6c00aabcSIngo Weinhold 		}
74*6c00aabcSIngo Weinhold 
75*6c00aabcSIngo Weinhold 		// modified time
76*6c00aabcSIngo Weinhold 		if (times[1].tv_nsec != UTIME_OMIT) {
77*6c00aabcSIngo Weinhold 			mask |= B_STAT_MODIFICATION_TIME;
78*6c00aabcSIngo Weinhold 
79*6c00aabcSIngo Weinhold 			if (times[1].tv_nsec != UTIME_NOW) {
80*6c00aabcSIngo Weinhold 				if (times[1].tv_nsec < 0 || times[1].tv_nsec > 999999999)
81*6c00aabcSIngo Weinhold 					RETURN_AND_SET_ERRNO(EINVAL);
82*6c00aabcSIngo Weinhold 			}
83*6c00aabcSIngo Weinhold 
84*6c00aabcSIngo Weinhold 			stat.st_mtim = times[1];
85*6c00aabcSIngo Weinhold 		}
86*6c00aabcSIngo Weinhold 	}
87*6c00aabcSIngo Weinhold 
88*6c00aabcSIngo Weinhold 	// set the times -- as per spec we even need to do this, if both have
89*6c00aabcSIngo Weinhold 	// UTIME_OMIT set
90*6c00aabcSIngo Weinhold 	status = _kern_write_stat(fd, path, (flag & AT_SYMLINK_NOFOLLOW) != 0,
91*6c00aabcSIngo Weinhold 		&stat, sizeof(struct stat), mask);
92*6c00aabcSIngo Weinhold 
93*6c00aabcSIngo Weinhold 	RETURN_AND_SET_ERRNO(status);
94*6c00aabcSIngo Weinhold }
95*6c00aabcSIngo Weinhold 
96*6c00aabcSIngo Weinhold 
97*6c00aabcSIngo Weinhold int
98*6c00aabcSIngo Weinhold futimens(int fd, const struct timespec times[2])
99*6c00aabcSIngo Weinhold {
100*6c00aabcSIngo Weinhold 	return utimensat(fd, NULL, times, 0);
101*6c00aabcSIngo Weinhold }
102