xref: /haiku/src/system/libroot/posix/sys/utimes.c (revision ae9019359606f1db67632ef51a77ce70001d3770)
121470984SAxel Dörfler /*
26c00aabcSIngo 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 
821470984SAxel Dörfler #include <sys/time.h>
96a9eee58SAxel Dörfler 
106a9eee58SAxel Dörfler #include <errno.h>
116a9eee58SAxel Dörfler 
126a9eee58SAxel Dörfler #include <NodeMonitor.h>
136a9eee58SAxel Dörfler 
14*ae901935SOliver Tappe #include <errno_private.h>
156a9eee58SAxel Dörfler #include <syscalls.h>
166c00aabcSIngo Weinhold #include <syscall_utils.h>
1721470984SAxel Dörfler 
1821470984SAxel Dörfler 
1921470984SAxel Dörfler int
206a9eee58SAxel Dörfler utimes(const char* path, const struct timeval times[2])
2121470984SAxel Dörfler {
226a9eee58SAxel Dörfler 	struct stat stat;
236a9eee58SAxel Dörfler 	status_t status;
2421470984SAxel Dörfler 
2521470984SAxel Dörfler 	if (times != NULL) {
266a9eee58SAxel Dörfler 		stat.st_atim.tv_sec = times[0].tv_sec;
276a9eee58SAxel Dörfler 		stat.st_atim.tv_nsec = times[0].tv_usec * 1000;
2821470984SAxel Dörfler 
296a9eee58SAxel Dörfler 		stat.st_mtim.tv_sec = times[1].tv_sec;
306a9eee58SAxel Dörfler 		stat.st_mtim.tv_nsec = times[1].tv_usec * 1000;
316a9eee58SAxel Dörfler 	} else {
326a9eee58SAxel Dörfler 		bigtime_t now = real_time_clock_usecs();
336a9eee58SAxel Dörfler 		stat.st_atim.tv_sec = stat.st_mtim.tv_sec = now / 1000000;
346a9eee58SAxel Dörfler 		stat.st_atim.tv_nsec = stat.st_mtim.tv_nsec = (now % 1000000) * 1000;
356a9eee58SAxel Dörfler 	}
366a9eee58SAxel Dörfler 
376a9eee58SAxel Dörfler 	status = _kern_write_stat(-1, path, true, &stat, sizeof(struct stat),
386a9eee58SAxel Dörfler 		B_STAT_MODIFICATION_TIME | B_STAT_ACCESS_TIME);
396a9eee58SAxel Dörfler 
406a9eee58SAxel Dörfler 	RETURN_AND_SET_ERRNO(status);
4121470984SAxel Dörfler }
4221470984SAxel Dörfler 
436c00aabcSIngo Weinhold 
446c00aabcSIngo Weinhold int
456c00aabcSIngo Weinhold utimensat(int fd, const char *path, const struct timespec times[2], int flag)
466c00aabcSIngo Weinhold {
476c00aabcSIngo Weinhold 	struct stat stat;
486c00aabcSIngo Weinhold 	status_t status;
496c00aabcSIngo Weinhold 	uint32 mask = 0;
506c00aabcSIngo Weinhold 
516c00aabcSIngo Weinhold 	// Init the stat time fields to the current time, if at least one time is
526c00aabcSIngo Weinhold 	// supposed to be set to it.
536c00aabcSIngo Weinhold 	if (times == NULL || times[0].tv_nsec == UTIME_NOW
546c00aabcSIngo Weinhold 		|| times[1].tv_nsec == UTIME_NOW) {
556c00aabcSIngo Weinhold 		bigtime_t now = real_time_clock_usecs();
566c00aabcSIngo Weinhold 		stat.st_atim.tv_sec = stat.st_mtim.tv_sec = now / 1000000;
576c00aabcSIngo Weinhold 		stat.st_atim.tv_nsec = stat.st_mtim.tv_nsec = (now % 1000000) * 1000;
586c00aabcSIngo Weinhold 	}
596c00aabcSIngo Weinhold 
606c00aabcSIngo Weinhold 	if (times != NULL) {
616c00aabcSIngo Weinhold 		// access time
626c00aabcSIngo Weinhold 		if (times[0].tv_nsec != UTIME_OMIT) {
636c00aabcSIngo Weinhold 			mask |= B_STAT_ACCESS_TIME;
646c00aabcSIngo Weinhold 
656c00aabcSIngo Weinhold 			if (times[0].tv_nsec != UTIME_NOW) {
666c00aabcSIngo Weinhold 				if (times[0].tv_nsec < 0 || times[0].tv_nsec > 999999999)
676c00aabcSIngo Weinhold 					RETURN_AND_SET_ERRNO(EINVAL);
686c00aabcSIngo Weinhold 			}
696c00aabcSIngo Weinhold 
706c00aabcSIngo Weinhold 			stat.st_atim = times[0];
716c00aabcSIngo Weinhold 		}
726c00aabcSIngo Weinhold 
736c00aabcSIngo Weinhold 		// modified time
746c00aabcSIngo Weinhold 		if (times[1].tv_nsec != UTIME_OMIT) {
756c00aabcSIngo Weinhold 			mask |= B_STAT_MODIFICATION_TIME;
766c00aabcSIngo Weinhold 
776c00aabcSIngo Weinhold 			if (times[1].tv_nsec != UTIME_NOW) {
786c00aabcSIngo Weinhold 				if (times[1].tv_nsec < 0 || times[1].tv_nsec > 999999999)
796c00aabcSIngo Weinhold 					RETURN_AND_SET_ERRNO(EINVAL);
806c00aabcSIngo Weinhold 			}
816c00aabcSIngo Weinhold 
826c00aabcSIngo Weinhold 			stat.st_mtim = times[1];
836c00aabcSIngo Weinhold 		}
848fbb8bd5SJérôme Duval 	} else
858fbb8bd5SJérôme Duval 		mask |= B_STAT_ACCESS_TIME | B_STAT_MODIFICATION_TIME;
866c00aabcSIngo Weinhold 
876c00aabcSIngo Weinhold 	// set the times -- as per spec we even need to do this, if both have
886c00aabcSIngo Weinhold 	// UTIME_OMIT set
891276d521SJérôme Duval 	status = _kern_write_stat(fd, path, (flag & AT_SYMLINK_NOFOLLOW) == 0,
906c00aabcSIngo Weinhold 		&stat, sizeof(struct stat), mask);
916c00aabcSIngo Weinhold 
926c00aabcSIngo Weinhold 	RETURN_AND_SET_ERRNO(status);
936c00aabcSIngo Weinhold }
946c00aabcSIngo Weinhold 
956c00aabcSIngo Weinhold 
966c00aabcSIngo Weinhold int
976c00aabcSIngo Weinhold futimens(int fd, const struct timespec times[2])
986c00aabcSIngo Weinhold {
996c00aabcSIngo Weinhold 	return utimensat(fd, NULL, times, 0);
1006c00aabcSIngo Weinhold }
101