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