1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. 29 */ 30 31 #include "lint.h" 32 #include <string.h> 33 #include <utime.h> 34 #include <fcntl.h> 35 #include <sys/stat.h> 36 #include <sys/time.h> 37 #include <sys/syscall.h> 38 39 int 40 futimens(int fd, const timespec_t times[2]) 41 { 42 return (syscall(SYS_utimesys, 0, fd, times)); 43 } 44 45 int 46 utimensat(int fd, const char *path, const timespec_t times[2], int flag) 47 { 48 return (syscall(SYS_utimesys, 1, fd, path, times, flag)); 49 } 50 51 #pragma weak _utime = utime 52 int 53 utime(const char *path, const struct utimbuf *times) 54 { 55 struct utimbuf ltimes; 56 timespec_t ts[2]; 57 timespec_t *tsp; 58 59 if (times == NULL) { 60 tsp = NULL; 61 } else { 62 /* use uucopy() to behave like a system call */ 63 if (uucopy(times, <imes, sizeof (ltimes)) != 0) 64 return (-1); /* uucopy() set errno to EFAULT */ 65 ts[0].tv_sec = ltimes.actime; 66 ts[0].tv_nsec = 0; 67 ts[1].tv_sec = ltimes.modtime; 68 ts[1].tv_nsec = 0; 69 tsp = ts; 70 } 71 return (utimensat(AT_FDCWD, path, tsp, 0)); 72 } 73 74 static int 75 utimes_impl(const char *path, const struct timeval times[2], int flag) 76 { 77 struct timeval ltimes[2]; 78 timespec_t ts[2]; 79 timespec_t *tsp; 80 81 if (times == NULL) { 82 tsp = NULL; 83 } else { 84 /* use uucopy() to behave like a system call */ 85 if (uucopy(times, ltimes, sizeof (ltimes)) != 0) 86 return (-1); /* uucopy() set errno to EFAULT */ 87 ts[0].tv_sec = ltimes[0].tv_sec; 88 ts[0].tv_nsec = ltimes[0].tv_usec * 1000; 89 ts[1].tv_sec = ltimes[1].tv_sec; 90 ts[1].tv_nsec = ltimes[1].tv_usec * 1000; 91 tsp = ts; 92 } 93 return (utimensat(AT_FDCWD, path, tsp, flag)); 94 } 95 96 int 97 utimes(const char *path, const struct timeval *times) 98 { 99 return (utimes_impl(path, times, 0)); 100 } 101 102 int 103 lutimes(const char *path, const struct timeval *times) 104 { 105 return (utimes_impl(path, times, AT_SYMLINK_NOFOLLOW)); 106 } 107 108 #pragma weak _futimesat = futimesat 109 int 110 futimesat(int fd, const char *path, const struct timeval *times) 111 { 112 struct timeval ltimes[2]; 113 timespec_t ts[2]; 114 timespec_t *tsp; 115 116 if (times == NULL) { 117 tsp = NULL; 118 } else { 119 /* use uucopy() to behave like a system call */ 120 if (uucopy(times, ltimes, sizeof (ltimes)) != 0) 121 return (-1); /* uucopy() set errno to EFAULT */ 122 ts[0].tv_sec = ltimes[0].tv_sec; 123 ts[0].tv_nsec = ltimes[0].tv_usec * 1000; 124 ts[1].tv_sec = ltimes[1].tv_sec; 125 ts[1].tv_nsec = ltimes[1].tv_usec * 1000; 126 tsp = ts; 127 } 128 129 if (path == NULL) 130 return (futimens(fd, tsp)); 131 132 return (utimensat(fd, path, tsp, 0)); 133 } 134 135 int 136 futimes(int fd, const struct timeval *times) 137 { 138 return (futimesat(fd, NULL, times)); 139 } 140