xref: /haiku/src/system/libroot/posix/sys/utimes.c (revision 8fbb8bd5b608d3b1f35ce5f4236c374d1796f000)
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 
146a9eee58SAxel Dörfler #include <syscalls.h>
156c00aabcSIngo Weinhold #include <syscall_utils.h>
1621470984SAxel Dörfler 
1721470984SAxel Dörfler 
1821470984SAxel Dörfler int
196a9eee58SAxel Dörfler utimes(const char* path, const struct timeval times[2])
2021470984SAxel Dörfler {
216a9eee58SAxel Dörfler 	struct stat stat;
226a9eee58SAxel Dörfler 	status_t status;
2321470984SAxel Dörfler 
2421470984SAxel Dörfler 	if (times != NULL) {
256a9eee58SAxel Dörfler 		stat.st_atim.tv_sec = times[0].tv_sec;
266a9eee58SAxel Dörfler 		stat.st_atim.tv_nsec = times[0].tv_usec * 1000;
2721470984SAxel Dörfler 
286a9eee58SAxel Dörfler 		stat.st_mtim.tv_sec = times[1].tv_sec;
296a9eee58SAxel Dörfler 		stat.st_mtim.tv_nsec = times[1].tv_usec * 1000;
306a9eee58SAxel Dörfler 	} else {
316a9eee58SAxel Dörfler 		bigtime_t now = real_time_clock_usecs();
326a9eee58SAxel Dörfler 		stat.st_atim.tv_sec = stat.st_mtim.tv_sec = now / 1000000;
336a9eee58SAxel Dörfler 		stat.st_atim.tv_nsec = stat.st_mtim.tv_nsec = (now % 1000000) * 1000;
346a9eee58SAxel Dörfler 	}
356a9eee58SAxel Dörfler 
366a9eee58SAxel Dörfler 	status = _kern_write_stat(-1, path, true, &stat, sizeof(struct stat),
376a9eee58SAxel Dörfler 		B_STAT_MODIFICATION_TIME | B_STAT_ACCESS_TIME);
386a9eee58SAxel Dörfler 
396a9eee58SAxel Dörfler 	RETURN_AND_SET_ERRNO(status);
4021470984SAxel Dörfler }
4121470984SAxel Dörfler 
426c00aabcSIngo Weinhold 
436c00aabcSIngo Weinhold int
446c00aabcSIngo Weinhold utimensat(int fd, const char *path, const struct timespec times[2], int flag)
456c00aabcSIngo Weinhold {
466c00aabcSIngo Weinhold 	struct stat stat;
476c00aabcSIngo Weinhold 	status_t status;
486c00aabcSIngo Weinhold 	uint32 mask = 0;
496c00aabcSIngo Weinhold 
506c00aabcSIngo Weinhold 	// Init the stat time fields to the current time, if at least one time is
516c00aabcSIngo Weinhold 	// supposed to be set to it.
526c00aabcSIngo Weinhold 	if (times == NULL || times[0].tv_nsec == UTIME_NOW
536c00aabcSIngo Weinhold 		|| times[1].tv_nsec == UTIME_NOW) {
546c00aabcSIngo Weinhold 		bigtime_t now = real_time_clock_usecs();
556c00aabcSIngo Weinhold 		stat.st_atim.tv_sec = stat.st_mtim.tv_sec = now / 1000000;
566c00aabcSIngo Weinhold 		stat.st_atim.tv_nsec = stat.st_mtim.tv_nsec = (now % 1000000) * 1000;
576c00aabcSIngo Weinhold 	}
586c00aabcSIngo Weinhold 
596c00aabcSIngo Weinhold 	if (times != NULL) {
606c00aabcSIngo Weinhold 		// access time
616c00aabcSIngo Weinhold 		if (times[0].tv_nsec != UTIME_OMIT) {
626c00aabcSIngo Weinhold 			mask |= B_STAT_ACCESS_TIME;
636c00aabcSIngo Weinhold 
646c00aabcSIngo Weinhold 			if (times[0].tv_nsec != UTIME_NOW) {
656c00aabcSIngo Weinhold 				if (times[0].tv_nsec < 0 || times[0].tv_nsec > 999999999)
666c00aabcSIngo Weinhold 					RETURN_AND_SET_ERRNO(EINVAL);
676c00aabcSIngo Weinhold 			}
686c00aabcSIngo Weinhold 
696c00aabcSIngo Weinhold 			stat.st_atim = times[0];
706c00aabcSIngo Weinhold 		}
716c00aabcSIngo Weinhold 
726c00aabcSIngo Weinhold 		// modified time
736c00aabcSIngo Weinhold 		if (times[1].tv_nsec != UTIME_OMIT) {
746c00aabcSIngo Weinhold 			mask |= B_STAT_MODIFICATION_TIME;
756c00aabcSIngo Weinhold 
766c00aabcSIngo Weinhold 			if (times[1].tv_nsec != UTIME_NOW) {
776c00aabcSIngo Weinhold 				if (times[1].tv_nsec < 0 || times[1].tv_nsec > 999999999)
786c00aabcSIngo Weinhold 					RETURN_AND_SET_ERRNO(EINVAL);
796c00aabcSIngo Weinhold 			}
806c00aabcSIngo Weinhold 
816c00aabcSIngo Weinhold 			stat.st_mtim = times[1];
826c00aabcSIngo Weinhold 		}
83*8fbb8bd5SJérôme Duval 	} else
84*8fbb8bd5SJérôme Duval 		mask |= B_STAT_ACCESS_TIME | B_STAT_MODIFICATION_TIME;
856c00aabcSIngo Weinhold 
866c00aabcSIngo Weinhold 	// set the times -- as per spec we even need to do this, if both have
876c00aabcSIngo Weinhold 	// UTIME_OMIT set
881276d521SJérôme Duval 	status = _kern_write_stat(fd, path, (flag & AT_SYMLINK_NOFOLLOW) == 0,
896c00aabcSIngo Weinhold 		&stat, sizeof(struct stat), mask);
906c00aabcSIngo Weinhold 
916c00aabcSIngo Weinhold 	RETURN_AND_SET_ERRNO(status);
926c00aabcSIngo Weinhold }
936c00aabcSIngo Weinhold 
946c00aabcSIngo Weinhold 
956c00aabcSIngo Weinhold int
966c00aabcSIngo Weinhold futimens(int fd, const struct timespec times[2])
976c00aabcSIngo Weinhold {
986c00aabcSIngo Weinhold 	return utimensat(fd, NULL, times, 0);
996c00aabcSIngo Weinhold }
100