xref: /haiku/src/system/libroot/posix/sys/utimes.c (revision 55e8238c7286b14593f43460aebf91b89309e38c)
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 
14ae901935SOliver 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
201d3d336aSAlexander von Gluck IV _utimes(const char* path, const struct timeval times[2], bool traverseLink);
211d3d336aSAlexander von Gluck IV 
22edfefa18SJérôme Duval 
23edfefa18SJérôme Duval int
_utimes(const char * path,const struct timeval times[2],bool traverseLink)241d3d336aSAlexander von Gluck IV _utimes(const char* path, const struct timeval times[2], bool traverseLink)
2521470984SAxel Dörfler {
266a9eee58SAxel Dörfler 	struct stat stat;
276a9eee58SAxel Dörfler 	status_t status;
2821470984SAxel Dörfler 
2921470984SAxel Dörfler 	if (times != NULL) {
306a9eee58SAxel Dörfler 		stat.st_atim.tv_sec = times[0].tv_sec;
316a9eee58SAxel Dörfler 		stat.st_atim.tv_nsec = times[0].tv_usec * 1000;
3221470984SAxel Dörfler 
336a9eee58SAxel Dörfler 		stat.st_mtim.tv_sec = times[1].tv_sec;
346a9eee58SAxel Dörfler 		stat.st_mtim.tv_nsec = times[1].tv_usec * 1000;
356a9eee58SAxel Dörfler 	} else {
366a9eee58SAxel Dörfler 		bigtime_t now = real_time_clock_usecs();
376a9eee58SAxel Dörfler 		stat.st_atim.tv_sec = stat.st_mtim.tv_sec = now / 1000000;
386a9eee58SAxel Dörfler 		stat.st_atim.tv_nsec = stat.st_mtim.tv_nsec = (now % 1000000) * 1000;
396a9eee58SAxel Dörfler 	}
406a9eee58SAxel Dörfler 
41be149e8cSAlexander von Gluck IV 	// traverseLeafLink == true
42*55e8238cSAugustin Cavalier 	status = _kern_write_stat(AT_FDCWD, path, traverseLink, &stat,
431d3d336aSAlexander von Gluck IV 		sizeof(struct stat), B_STAT_MODIFICATION_TIME | B_STAT_ACCESS_TIME);
446a9eee58SAxel Dörfler 
456a9eee58SAxel Dörfler 	RETURN_AND_SET_ERRNO(status);
4621470984SAxel Dörfler }
4721470984SAxel Dörfler 
486c00aabcSIngo Weinhold 
496c00aabcSIngo Weinhold int
utimes(const char * path,const struct timeval times[2])501d3d336aSAlexander von Gluck IV utimes(const char* path, const struct timeval times[2])
51be149e8cSAlexander von Gluck IV {
521d3d336aSAlexander von Gluck IV 	return _utimes(path, times, true);
53be149e8cSAlexander von Gluck IV }
54be149e8cSAlexander von Gluck IV 
55be149e8cSAlexander von Gluck IV 
56be149e8cSAlexander von Gluck IV int
utimensat(int fd,const char * path,const struct timespec times[2],int flag)576c00aabcSIngo Weinhold utimensat(int fd, const char *path, const struct timespec times[2], int flag)
586c00aabcSIngo Weinhold {
596c00aabcSIngo Weinhold 	struct stat stat;
606c00aabcSIngo Weinhold 	status_t status;
616c00aabcSIngo Weinhold 	uint32 mask = 0;
626c00aabcSIngo Weinhold 
636c00aabcSIngo Weinhold 	// Init the stat time fields to the current time, if at least one time is
646c00aabcSIngo Weinhold 	// supposed to be set to it.
656c00aabcSIngo Weinhold 	if (times == NULL || times[0].tv_nsec == UTIME_NOW
666c00aabcSIngo Weinhold 		|| times[1].tv_nsec == UTIME_NOW) {
676c00aabcSIngo Weinhold 		bigtime_t now = real_time_clock_usecs();
686c00aabcSIngo Weinhold 		stat.st_atim.tv_sec = stat.st_mtim.tv_sec = now / 1000000;
696c00aabcSIngo Weinhold 		stat.st_atim.tv_nsec = stat.st_mtim.tv_nsec = (now % 1000000) * 1000;
706c00aabcSIngo Weinhold 	}
716c00aabcSIngo Weinhold 
726c00aabcSIngo Weinhold 	if (times != NULL) {
736c00aabcSIngo Weinhold 		// access time
746c00aabcSIngo Weinhold 		if (times[0].tv_nsec != UTIME_OMIT) {
756c00aabcSIngo Weinhold 			mask |= B_STAT_ACCESS_TIME;
766c00aabcSIngo Weinhold 
776c00aabcSIngo Weinhold 			if (times[0].tv_nsec != UTIME_NOW) {
786c00aabcSIngo Weinhold 				if (times[0].tv_nsec < 0 || times[0].tv_nsec > 999999999)
796c00aabcSIngo Weinhold 					RETURN_AND_SET_ERRNO(EINVAL);
806c00aabcSIngo Weinhold 			}
816c00aabcSIngo Weinhold 
826c00aabcSIngo Weinhold 			stat.st_atim = times[0];
836c00aabcSIngo Weinhold 		}
846c00aabcSIngo Weinhold 
856c00aabcSIngo Weinhold 		// modified time
866c00aabcSIngo Weinhold 		if (times[1].tv_nsec != UTIME_OMIT) {
876c00aabcSIngo Weinhold 			mask |= B_STAT_MODIFICATION_TIME;
886c00aabcSIngo Weinhold 
896c00aabcSIngo Weinhold 			if (times[1].tv_nsec != UTIME_NOW) {
906c00aabcSIngo Weinhold 				if (times[1].tv_nsec < 0 || times[1].tv_nsec > 999999999)
916c00aabcSIngo Weinhold 					RETURN_AND_SET_ERRNO(EINVAL);
926c00aabcSIngo Weinhold 			}
936c00aabcSIngo Weinhold 
946c00aabcSIngo Weinhold 			stat.st_mtim = times[1];
956c00aabcSIngo Weinhold 		}
968fbb8bd5SJérôme Duval 	} else
978fbb8bd5SJérôme Duval 		mask |= B_STAT_ACCESS_TIME | B_STAT_MODIFICATION_TIME;
986c00aabcSIngo Weinhold 
996c00aabcSIngo Weinhold 	// set the times -- as per spec we even need to do this, if both have
1006c00aabcSIngo Weinhold 	// UTIME_OMIT set
1011276d521SJérôme Duval 	status = _kern_write_stat(fd, path, (flag & AT_SYMLINK_NOFOLLOW) == 0,
1026c00aabcSIngo Weinhold 		&stat, sizeof(struct stat), mask);
1036c00aabcSIngo Weinhold 
1046c00aabcSIngo Weinhold 	RETURN_AND_SET_ERRNO(status);
1056c00aabcSIngo Weinhold }
1066c00aabcSIngo Weinhold 
1076c00aabcSIngo Weinhold 
1086c00aabcSIngo Weinhold int
futimens(int fd,const struct timespec times[2])1096c00aabcSIngo Weinhold futimens(int fd, const struct timespec times[2])
1106c00aabcSIngo Weinhold {
1116c00aabcSIngo Weinhold 	return utimensat(fd, NULL, times, 0);
1126c00aabcSIngo Weinhold }
113