1 #include <sys/cdefs.h> 2 #include "namespace.h" 3 #include <lib.h> 4 5 #include <sys/stat.h> 6 #include <fcntl.h> 7 #include <string.h> 8 #include <limits.h> 9 #include <errno.h> 10 11 /* Implement a very large but not complete subset of the utimensat() 12 * Posix:2008/XOpen-7 function. 13 * Are handled the following cases: 14 * . utimensat(AT_FDCWD, "/some/absolute/path", , ) 15 * . utimensat(AT_FDCWD, "some/path", , ) 16 * . utimensat(fd, "/some/absolute/path", , ) although fd is useless here 17 * Are not handled the following cases: 18 * . utimensat(fd, "some/path", , ) path to a file relative to some open fd 19 */ 20 int utimensat(int fd, const char *name, const struct timespec tv[2], 21 int flags) 22 { 23 message m; 24 static const struct timespec now[2] = { {0, UTIME_NOW}, {0, UTIME_NOW} }; 25 26 if (tv == NULL) tv = now; 27 28 if (name == NULL) { 29 errno = EINVAL; 30 return -1; 31 } 32 if (name[0] == '\0') { /* POSIX requirement */ 33 errno = ENOENT; 34 return -1; 35 } 36 if (fd != AT_FDCWD && name[0] != '/') { /* Not supported */ 37 errno = EINVAL; 38 return -1; 39 } 40 41 if ((unsigned)flags > SHRT_MAX) { 42 errno = EINVAL; 43 return -1; 44 } 45 46 memset(&m, 0, sizeof(m)); 47 m.m_vfs_utimens.len = strlen(name) + 1; 48 m.m_vfs_utimens.name = __UNCONST(name); 49 m.m_vfs_utimens.atime = tv[0].tv_sec; 50 m.m_vfs_utimens.mtime = tv[1].tv_sec; 51 m.m_vfs_utimens.ansec = tv[0].tv_nsec; 52 m.m_vfs_utimens.mnsec = tv[1].tv_nsec; 53 m.m_vfs_utimens.flags = flags; 54 55 return(_syscall(VFS_PROC_NR, VFS_UTIMENS, &m)); 56 } 57