1 /* 2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2006-2009, Axel Dörfler, axeld@pinc-software.de. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 8 #include <sys/time.h> 9 10 #include <errno.h> 11 12 #include <NodeMonitor.h> 13 14 #include <syscalls.h> 15 #include <syscall_utils.h> 16 17 18 int 19 utimes(const char* path, const struct timeval times[2]) 20 { 21 struct stat stat; 22 status_t status; 23 24 if (times != NULL) { 25 stat.st_atim.tv_sec = times[0].tv_sec; 26 stat.st_atim.tv_nsec = times[0].tv_usec * 1000; 27 28 stat.st_mtim.tv_sec = times[1].tv_sec; 29 stat.st_mtim.tv_nsec = times[1].tv_usec * 1000; 30 } else { 31 bigtime_t now = real_time_clock_usecs(); 32 stat.st_atim.tv_sec = stat.st_mtim.tv_sec = now / 1000000; 33 stat.st_atim.tv_nsec = stat.st_mtim.tv_nsec = (now % 1000000) * 1000; 34 } 35 36 status = _kern_write_stat(-1, path, true, &stat, sizeof(struct stat), 37 B_STAT_MODIFICATION_TIME | B_STAT_ACCESS_TIME); 38 39 RETURN_AND_SET_ERRNO(status); 40 } 41 42 43 int 44 utimensat(int fd, const char *path, const struct timespec times[2], int flag) 45 { 46 struct stat stat; 47 status_t status; 48 uint32 mask = 0; 49 50 // Init the stat time fields to the current time, if at least one time is 51 // supposed to be set to it. 52 if (times == NULL || times[0].tv_nsec == UTIME_NOW 53 || times[1].tv_nsec == UTIME_NOW) { 54 bigtime_t now = real_time_clock_usecs(); 55 stat.st_atim.tv_sec = stat.st_mtim.tv_sec = now / 1000000; 56 stat.st_atim.tv_nsec = stat.st_mtim.tv_nsec = (now % 1000000) * 1000; 57 } 58 59 if (times != NULL) { 60 // access time 61 if (times[0].tv_nsec != UTIME_OMIT) { 62 mask |= B_STAT_ACCESS_TIME; 63 64 if (times[0].tv_nsec != UTIME_NOW) { 65 if (times[0].tv_nsec < 0 || times[0].tv_nsec > 999999999) 66 RETURN_AND_SET_ERRNO(EINVAL); 67 } 68 69 stat.st_atim = times[0]; 70 } 71 72 // modified time 73 if (times[1].tv_nsec != UTIME_OMIT) { 74 mask |= B_STAT_MODIFICATION_TIME; 75 76 if (times[1].tv_nsec != UTIME_NOW) { 77 if (times[1].tv_nsec < 0 || times[1].tv_nsec > 999999999) 78 RETURN_AND_SET_ERRNO(EINVAL); 79 } 80 81 stat.st_mtim = times[1]; 82 } 83 } else 84 mask |= B_STAT_ACCESS_TIME | B_STAT_MODIFICATION_TIME; 85 86 // set the times -- as per spec we even need to do this, if both have 87 // UTIME_OMIT set 88 status = _kern_write_stat(fd, path, (flag & AT_SYMLINK_NOFOLLOW) == 0, 89 &stat, sizeof(struct stat), mask); 90 91 RETURN_AND_SET_ERRNO(status); 92 } 93 94 95 int 96 futimens(int fd, const struct timespec times[2]) 97 { 98 return utimensat(fd, NULL, times, 0); 99 } 100