aboutsummaryrefslogtreecommitdiff
path: root/tools/build/futimens.c
diff options
context:
space:
mode:
authorJilles Tjoelker <jilles@FreeBSD.org>2016-06-09 21:57:34 +0000
committerJilles Tjoelker <jilles@FreeBSD.org>2016-06-09 21:57:34 +0000
commitd80f1dd1d78ddebee8de9cfba9413032a1fedba8 (patch)
treece5fb651e3647bbcbb5e7528ba715e2412bd1056 /tools/build/futimens.c
parentad02cb0399e29eff2ae8458ba7dc72d078fc522c (diff)
downloadsrc-d80f1dd1d78ddebee8de9cfba9413032a1fedba8.tar.gz
src-d80f1dd1d78ddebee8de9cfba9413032a1fedba8.zip
build: Add legacy support for futimens() and utimensat().
In order to allow using utimensat() in install(1), add futimens() and utimensat() to -legacy. The files futimens.c and utimensat.c are modified copies of the files under lib/libc/sys/ since the libc versions use symbols that do not exist in the libc on the build system (sys_futimens and sys_utimensat) . I expect the next non-sweeping change to both sets of files to be to delete them, anyway. This will allow reverting r299942 (which is a revert of r299850) enabling nanosecond timestamps in install(1). Reviewed by: bdrewery
Notes
Notes: svn path=/head/; revision=301763
Diffstat (limited to 'tools/build/futimens.c')
-rw-r--r--tools/build/futimens.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/tools/build/futimens.c b/tools/build/futimens.c
new file mode 100644
index 000000000000..7d1cae701e97
--- /dev/null
+++ b/tools/build/futimens.c
@@ -0,0 +1,96 @@
+/*-
+ * Copyright (c) 2015 Jilles Tjoelker
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <time.h>
+
+#ifndef UTIME_NOW
+#define UTIME_NOW -1
+#define UTIME_OMIT -2
+#endif
+
+int
+futimens(int fd, const struct timespec times[2])
+{
+ struct timeval now, tv[2], *tvp;
+ struct stat sb;
+ int osreldate;
+
+ if (times == NULL || (times[0].tv_nsec == UTIME_NOW &&
+ times[1].tv_nsec == UTIME_NOW))
+ tvp = NULL;
+ else if (times[0].tv_nsec == UTIME_OMIT &&
+ times[1].tv_nsec == UTIME_OMIT)
+ return (0);
+ else {
+ if ((times[0].tv_nsec < 0 || times[0].tv_nsec > 999999999) &&
+ times[0].tv_nsec != UTIME_NOW &&
+ times[0].tv_nsec != UTIME_OMIT) {
+ errno = EINVAL;
+ return (-1);
+ }
+ if ((times[1].tv_nsec < 0 || times[1].tv_nsec > 999999999) &&
+ times[1].tv_nsec != UTIME_NOW &&
+ times[1].tv_nsec != UTIME_OMIT) {
+ errno = EINVAL;
+ return (-1);
+ }
+ tv[0].tv_sec = times[0].tv_sec;
+ tv[0].tv_usec = times[0].tv_nsec / 1000;
+ tv[1].tv_sec = times[1].tv_sec;
+ tv[1].tv_usec = times[1].tv_nsec / 1000;
+ tvp = tv;
+ if (times[0].tv_nsec == UTIME_OMIT ||
+ times[1].tv_nsec == UTIME_OMIT) {
+ if (fstat(fd, &sb) == -1)
+ return (-1);
+ if (times[0].tv_nsec == UTIME_OMIT) {
+ tv[0].tv_sec = sb.st_atim.tv_sec;
+ tv[0].tv_usec = sb.st_atim.tv_nsec / 1000;
+ }
+ if (times[1].tv_nsec == UTIME_OMIT) {
+ tv[1].tv_sec = sb.st_mtim.tv_sec;
+ tv[1].tv_usec = sb.st_mtim.tv_nsec / 1000;
+ }
+ }
+ if (times[0].tv_nsec == UTIME_NOW ||
+ times[1].tv_nsec == UTIME_NOW) {
+ if (gettimeofday(&now, NULL) == -1)
+ return (-1);
+ if (times[0].tv_nsec == UTIME_NOW)
+ tv[0] = now;
+ if (times[1].tv_nsec == UTIME_NOW)
+ tv[1] = now;
+ }
+ }
+ return (futimes(fd, tvp));
+}