xref: /illumos-gate/usr/src/lib/libc/port/sys/utimesys.c (revision 2829495d7d810156bdfd454b8a1ef0f54eac9733)
13b862e9aSRoger A. Faulkner /*
23b862e9aSRoger A. Faulkner  * CDDL HEADER START
33b862e9aSRoger A. Faulkner  *
43b862e9aSRoger A. Faulkner  * The contents of this file are subject to the terms of the
53b862e9aSRoger A. Faulkner  * Common Development and Distribution License (the "License").
63b862e9aSRoger A. Faulkner  * You may not use this file except in compliance with the License.
73b862e9aSRoger A. Faulkner  *
83b862e9aSRoger A. Faulkner  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93b862e9aSRoger A. Faulkner  * or http://www.opensolaris.org/os/licensing.
103b862e9aSRoger A. Faulkner  * See the License for the specific language governing permissions
113b862e9aSRoger A. Faulkner  * and limitations under the License.
123b862e9aSRoger A. Faulkner  *
133b862e9aSRoger A. Faulkner  * When distributing Covered Code, include this CDDL HEADER in each
143b862e9aSRoger A. Faulkner  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153b862e9aSRoger A. Faulkner  * If applicable, add the following below this CDDL HEADER, with the
163b862e9aSRoger A. Faulkner  * fields enclosed by brackets "[]" replaced with your own identifying
173b862e9aSRoger A. Faulkner  * information: Portions Copyright [yyyy] [name of copyright owner]
183b862e9aSRoger A. Faulkner  *
193b862e9aSRoger A. Faulkner  * CDDL HEADER END
203b862e9aSRoger A. Faulkner  */
213b862e9aSRoger A. Faulkner 
223b862e9aSRoger A. Faulkner /*
233b862e9aSRoger A. Faulkner  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
243b862e9aSRoger A. Faulkner  * Use is subject to license terms.
253b862e9aSRoger A. Faulkner  */
263b862e9aSRoger A. Faulkner 
27b7a77849SAndy Fiddaman /*
28b7a77849SAndy Fiddaman  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
29b7a77849SAndy Fiddaman  */
30b7a77849SAndy Fiddaman 
313b862e9aSRoger A. Faulkner #include "lint.h"
323b862e9aSRoger A. Faulkner #include <string.h>
333b862e9aSRoger A. Faulkner #include <utime.h>
343b862e9aSRoger A. Faulkner #include <fcntl.h>
353b862e9aSRoger A. Faulkner #include <sys/stat.h>
363b862e9aSRoger A. Faulkner #include <sys/time.h>
373b862e9aSRoger A. Faulkner #include <sys/syscall.h>
383b862e9aSRoger A. Faulkner 
393b862e9aSRoger A. Faulkner int
futimens(int fd,const timespec_t times[2])403b862e9aSRoger A. Faulkner futimens(int fd, const timespec_t times[2])
413b862e9aSRoger A. Faulkner {
423b862e9aSRoger A. Faulkner 	return (syscall(SYS_utimesys, 0, fd, times));
433b862e9aSRoger A. Faulkner }
443b862e9aSRoger A. Faulkner 
453b862e9aSRoger A. Faulkner int
utimensat(int fd,const char * path,const timespec_t times[2],int flag)463b862e9aSRoger A. Faulkner utimensat(int fd, const char *path, const timespec_t times[2], int flag)
473b862e9aSRoger A. Faulkner {
483b862e9aSRoger A. Faulkner 	return (syscall(SYS_utimesys, 1, fd, path, times, flag));
493b862e9aSRoger A. Faulkner }
503b862e9aSRoger A. Faulkner 
513b862e9aSRoger A. Faulkner #pragma weak _utime = utime
523b862e9aSRoger A. Faulkner int
utime(const char * path,const struct utimbuf * times)533b862e9aSRoger A. Faulkner utime(const char *path, const struct utimbuf *times)
543b862e9aSRoger A. Faulkner {
553b862e9aSRoger A. Faulkner 	struct utimbuf ltimes;
563b862e9aSRoger A. Faulkner 	timespec_t ts[2];
573b862e9aSRoger A. Faulkner 	timespec_t *tsp;
583b862e9aSRoger A. Faulkner 
593b862e9aSRoger A. Faulkner 	if (times == NULL) {
603b862e9aSRoger A. Faulkner 		tsp = NULL;
613b862e9aSRoger A. Faulkner 	} else {
623b862e9aSRoger A. Faulkner 		/* use uucopy() to behave like a system call */
633b862e9aSRoger A. Faulkner 		if (uucopy(times, &ltimes, sizeof (ltimes)) != 0)
643b862e9aSRoger A. Faulkner 			return (-1);	/* uucopy() set errno to EFAULT */
653b862e9aSRoger A. Faulkner 		ts[0].tv_sec = ltimes.actime;
663b862e9aSRoger A. Faulkner 		ts[0].tv_nsec = 0;
673b862e9aSRoger A. Faulkner 		ts[1].tv_sec = ltimes.modtime;
683b862e9aSRoger A. Faulkner 		ts[1].tv_nsec = 0;
693b862e9aSRoger A. Faulkner 		tsp = ts;
703b862e9aSRoger A. Faulkner 	}
713b862e9aSRoger A. Faulkner 	return (utimensat(AT_FDCWD, path, tsp, 0));
723b862e9aSRoger A. Faulkner }
733b862e9aSRoger A. Faulkner 
74b7a77849SAndy Fiddaman static int
utimes_impl(const char * path,const struct timeval times[2],int flag)75b7a77849SAndy Fiddaman utimes_impl(const char *path, const struct timeval times[2], int flag)
763b862e9aSRoger A. Faulkner {
773b862e9aSRoger A. Faulkner 	struct timeval ltimes[2];
783b862e9aSRoger A. Faulkner 	timespec_t ts[2];
793b862e9aSRoger A. Faulkner 	timespec_t *tsp;
803b862e9aSRoger A. Faulkner 
813b862e9aSRoger A. Faulkner 	if (times == NULL) {
823b862e9aSRoger A. Faulkner 		tsp = NULL;
833b862e9aSRoger A. Faulkner 	} else {
843b862e9aSRoger A. Faulkner 		/* use uucopy() to behave like a system call */
853b862e9aSRoger A. Faulkner 		if (uucopy(times, ltimes, sizeof (ltimes)) != 0)
863b862e9aSRoger A. Faulkner 			return (-1);	/* uucopy() set errno to EFAULT */
873b862e9aSRoger A. Faulkner 		ts[0].tv_sec = ltimes[0].tv_sec;
883b862e9aSRoger A. Faulkner 		ts[0].tv_nsec = ltimes[0].tv_usec * 1000;
893b862e9aSRoger A. Faulkner 		ts[1].tv_sec = ltimes[1].tv_sec;
903b862e9aSRoger A. Faulkner 		ts[1].tv_nsec = ltimes[1].tv_usec * 1000;
913b862e9aSRoger A. Faulkner 		tsp = ts;
923b862e9aSRoger A. Faulkner 	}
93b7a77849SAndy Fiddaman 	return (utimensat(AT_FDCWD, path, tsp, flag));
94b7a77849SAndy Fiddaman }
95b7a77849SAndy Fiddaman 
96b7a77849SAndy Fiddaman int
utimes(const char * path,const struct timeval * times)97*2829495dSToomas Soome utimes(const char *path, const struct timeval *times)
98b7a77849SAndy Fiddaman {
99b7a77849SAndy Fiddaman 	return (utimes_impl(path, times, 0));
100b7a77849SAndy Fiddaman }
101b7a77849SAndy Fiddaman 
102b7a77849SAndy Fiddaman int
lutimes(const char * path,const struct timeval * times)103*2829495dSToomas Soome lutimes(const char *path, const struct timeval *times)
104b7a77849SAndy Fiddaman {
105b7a77849SAndy Fiddaman 	return (utimes_impl(path, times, AT_SYMLINK_NOFOLLOW));
1063b862e9aSRoger A. Faulkner }
1073b862e9aSRoger A. Faulkner 
1083b862e9aSRoger A. Faulkner #pragma weak _futimesat = futimesat
1093b862e9aSRoger A. Faulkner int
futimesat(int fd,const char * path,const struct timeval * times)110*2829495dSToomas Soome futimesat(int fd, const char *path, const struct timeval *times)
1113b862e9aSRoger A. Faulkner {
1123b862e9aSRoger A. Faulkner 	struct timeval ltimes[2];
1133b862e9aSRoger A. Faulkner 	timespec_t ts[2];
1143b862e9aSRoger A. Faulkner 	timespec_t *tsp;
1153b862e9aSRoger A. Faulkner 
1163b862e9aSRoger A. Faulkner 	if (times == NULL) {
1173b862e9aSRoger A. Faulkner 		tsp = NULL;
1183b862e9aSRoger A. Faulkner 	} else {
1193b862e9aSRoger A. Faulkner 		/* use uucopy() to behave like a system call */
1203b862e9aSRoger A. Faulkner 		if (uucopy(times, ltimes, sizeof (ltimes)) != 0)
1213b862e9aSRoger A. Faulkner 			return (-1);	/* uucopy() set errno to EFAULT */
1223b862e9aSRoger A. Faulkner 		ts[0].tv_sec = ltimes[0].tv_sec;
1233b862e9aSRoger A. Faulkner 		ts[0].tv_nsec = ltimes[0].tv_usec * 1000;
1243b862e9aSRoger A. Faulkner 		ts[1].tv_sec = ltimes[1].tv_sec;
1253b862e9aSRoger A. Faulkner 		ts[1].tv_nsec = ltimes[1].tv_usec * 1000;
1263b862e9aSRoger A. Faulkner 		tsp = ts;
1273b862e9aSRoger A. Faulkner 	}
1283b862e9aSRoger A. Faulkner 
1293b862e9aSRoger A. Faulkner 	if (path == NULL)
1303b862e9aSRoger A. Faulkner 		return (futimens(fd, tsp));
1313b862e9aSRoger A. Faulkner 
1323b862e9aSRoger A. Faulkner 	return (utimensat(fd, path, tsp, 0));
1333b862e9aSRoger A. Faulkner }
134b7a77849SAndy Fiddaman 
135b7a77849SAndy Fiddaman int
futimes(int fd,const struct timeval * times)136*2829495dSToomas Soome futimes(int fd, const struct timeval *times)
137b7a77849SAndy Fiddaman {
138b7a77849SAndy Fiddaman 	return (futimesat(fd, NULL, times));
139b7a77849SAndy Fiddaman }
140