Browse Source

futimens: add function

Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Bernhard Reutner-Fischer 14 years ago
parent
commit
ef85033ac8

+ 1 - 0
include/sys/stat.h

@@ -375,6 +375,7 @@ extern int utimensat (int __fd, __const char *__path,
 		      __const struct timespec __times[2],
 		      int __flags)
      __THROW __nonnull ((2));
+libc_hidden_proto(utimensat)
 #endif
 
 #ifdef __USE_XOPEN2K8

+ 23 - 0
libc/sysdeps/linux/common/futimens.c

@@ -0,0 +1,23 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * futimens() implementation for uClibc
+ *
+ * Copyright (C) 2009 Bernhard Reutner-Fischer <uclibc@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#define __need_timespec
+#include <time.h>
+#ifdef __NR_utimensat
+extern int utimensat (int __fd, __const char *__path,
+	__const struct timespec __times[2],
+	int __flags) __THROW;
+libc_hidden_proto(utimensat)
+
+int futimens (int fd, __const struct timespec ts[2])
+{
+	return utimensat(fd, 0, ts, 0);
+}
+#endif

+ 2 - 0
libc/sysdeps/linux/common/utimensat.c

@@ -11,6 +11,8 @@
 
 #ifdef __NR_utimensat
 _syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags)
+libc_hidden_def(utimensat)
 #else
 /* should add emulation with utimens() and /proc/self/fd/ ... */
 #endif
+

+ 2 - 0
test/.gitignore

@@ -237,6 +237,8 @@ string/tst-strxfrm
 termios/termios
 time/clocktest
 time/test_time
+time/tst-ftime_l
+time/tst-futimens1
 time/tst-mktime
 time/tst-mktime3
 time/tst-strptime2

+ 90 - 0
test/time/tst-futimens1.c

@@ -0,0 +1,90 @@
+/* vi: set sw=4 ts=4: */
+/* testcase
+ * Copyright (C) 2009 Bernhard Reutner-Fischer <uClibc@uClibc.org>
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+struct
+{
+	char *name; /* name of file to open */
+	int flags; /* flags for file descriptor */
+	const struct timespec ts[2];
+	int err; /* expected errno */
+} tests [] =
+{
+	{"futimens.tst", (O_CREAT|O_TRUNC), {{0,0},{0,0}}, 0},
+	{"futimens.tst", (O_CREAT|O_TRUNC), {{99,0},{0,0}}, 0},
+	{"futimens.tst", (O_CREAT|O_TRUNC), {{0,99},{0,0}}, 0},
+	{"futimens.tst", (O_CREAT|O_TRUNC), {{0,0},{99,0}}, 0},
+	{"futimens.tst", (O_CREAT|O_TRUNC), {{0,0},{0,99}}, 0},
+	{"futimens.tst", (O_CREAT|O_TRUNC), {{11,2},{3,4}}, 0},
+};
+int do_test(int argc, char **argv) {
+	char *name;
+	int i, errors;
+	errors = argc - argc + 0;
+
+	for (i=0; i < (int) (sizeof(tests)/sizeof(tests[0])); ++i) {
+		int err, fd;
+		struct stat sb;
+		name = tests[i].name;
+		if (*name != '.')
+			unlink(name);
+		fd = open(name, tests[i].flags);
+		if (fd < 0)
+			abort();
+		errno = 0;
+		err = futimens(fd, tests[i].ts);
+		if ((errno && !err) || (!errno && err)) {
+			err = errno;
+			printf("%s: FAILED test %d (errno and return value disagree)\n",
+				argv[0], i);
+			++errors;
+		} else
+			err = errno;
+		if (err != tests[i].err) {
+			printf("%s: FAILED test %d (expected errno %d, got %d)\n",
+				argv[0], i, tests[i].err, err);
+			++errors;
+			continue;
+		}
+		if (stat(name, &sb) < 0) {
+			printf("%s: FAILED test %d (verification)\n", argv[0], i);
+			++errors;
+			continue;
+		} else {
+			unsigned wrong = tests[i].ts[0].tv_sec != sb.st_atim.tv_sec ||
+						tests[i].ts[0].tv_nsec != sb.st_atim.tv_nsec ||
+						tests[i].ts[1].tv_sec != sb.st_mtim.tv_sec ||
+						tests[i].ts[1].tv_nsec != sb.st_mtim.tv_nsec;
+			if (wrong) {
+				++errors;
+				if (tests[i].ts[0].tv_sec != sb.st_atim.tv_sec)
+					printf("%s: FAILED test %d (access time, sec: expected %ld, got %ld)\n",
+						argv[0], i, tests[i].ts[0].tv_sec, sb.st_atim.tv_sec);
+				if (tests[i].ts[0].tv_nsec != sb.st_atim.tv_nsec)
+					printf("%s: FAILED test %d (access time, nsec: expected %ld, got %ld)\n",
+						argv[0], i, tests[i].ts[0].tv_nsec, sb.st_atim.tv_nsec);
+
+				if (tests[i].ts[1].tv_sec != sb.st_mtim.tv_sec)
+					printf("%s: FAILED test %d (modification time, sec: expected %ld, got %ld)\n",
+						argv[0], i, tests[i].ts[1].tv_sec, sb.st_mtim.tv_sec);
+				if (tests[i].ts[1].tv_nsec != sb.st_mtim.tv_nsec)
+					printf("%s: FAILED test %d (modification time, nsec: expected %ld, got %ld)\n",
+						argv[0], i, tests[i].ts[1].tv_nsec, sb.st_mtim.tv_nsec);
+			}
+		}
+	}
+	if (*name != '.')
+		unlink(name);
+	printf("%d errors.\n", errors);
+	return (!errors) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+#include <test-skeleton.c>