diff options
| -rw-r--r-- | include/sys/stat.h | 1 | ||||
| -rw-r--r-- | libc/sysdeps/linux/common/futimens.c | 23 | ||||
| -rw-r--r-- | libc/sysdeps/linux/common/utimensat.c | 2 | ||||
| -rw-r--r-- | test/.gitignore | 2 | ||||
| -rw-r--r-- | test/time/tst-futimens1.c | 90 | 
5 files changed, 118 insertions, 0 deletions
| diff --git a/include/sys/stat.h b/include/sys/stat.h index d84ace5a2..170a4e633 100644 --- a/include/sys/stat.h +++ b/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 diff --git a/libc/sysdeps/linux/common/futimens.c b/libc/sysdeps/linux/common/futimens.c new file mode 100644 index 000000000..090dfa69c --- /dev/null +++ b/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 diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c index 3c5af8586..2cfb8247d 100644 --- a/libc/sysdeps/linux/common/utimensat.c +++ b/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 + diff --git a/test/.gitignore b/test/.gitignore index d438af7d0..1e7cd584e 100644 --- a/test/.gitignore +++ b/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 diff --git a/test/time/tst-futimens1.c b/test/time/tst-futimens1.c new file mode 100644 index 000000000..a452de2c7 --- /dev/null +++ b/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> | 
