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