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