Permalink
Browse files

implemented fstatat() syscall + testsuite

fstatat(2) seems to be implemented either by

* __NR_fstatat (only MIPS?)
* __NR_fstatat64 (32 bit archs)
* __NF_newfstatat (64 bit archs)

Changeset adds this syscall and a test case which checks some other
*at() functions too
  • Loading branch information...
1 parent e905051 commit 25938b345a2072535930fd354cb5675df1262336 @ensc committed Apr 4, 2012
Showing with 133 additions and 2 deletions.
  1. +2 −0 include/fcntl.h
  2. +5 −0 syscalls.s/fstatat.S
  3. +5 −0 syscalls.s/fstatat64.S
  4. +7 −0 syscalls.s/newfstatat.S
  5. +1 −0 test/.gitignore
  6. +1 −1 test/Makefile
  7. +111 −0 test/atfile.c
  8. +1 −1 test/runtests.sh
View
@@ -614,8 +614,10 @@ struct flock64
extern int fcntl (int __fd, int __cmd, ...) __THROW;
#ifndef __NO_STAT64
extern int fcntl64 (int __fd, int __cmd, ...) __THROW;
+extern int fstatat64(int dirfd, const char *pathname, struct stat *buf, int flags) __THROW;
#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64
#define fcntl fcntl64
+#define fstatat fstatat64
#endif
#endif
View
@@ -0,0 +1,5 @@
+#include "syscalls.h"
+
+#ifdef __NR_fstatat
+syscall(fstatat,fstatat)
+#endif
View
@@ -0,0 +1,5 @@
+#include "syscalls.h"
+
+#ifdef __NR_fstatat64
+syscall(fstatat64,fstatat64)
+#endif
View
@@ -2,4 +2,11 @@
#ifdef __NR_newfstatat
syscall(newfstatat,newfstatat)
+
+#ifdef __NR_fstatat64
+# error __NR_newfstatat and __NR_fstatat64 must not be defined both
+#endif
+
+fstatat = newfstatat
+.globl fstatat
#endif
View
@@ -3,6 +3,7 @@
/argv
/asprintf
/atexit
+/atfile
/bsearch
/byteswap
/calloc
View
@@ -7,7 +7,7 @@ CFLAGS=-nostdinc -Wall
LCOMPAT=-lcompat
-TESTPROGRAMS=adjtime alarm argv asprintf atexit bsearch byteswap calloc confstr cycles empty fadvise flush fnmatch \
+TESTPROGRAMS=adjtime alarm argv asprintf atexit atfile bsearch byteswap calloc confstr cycles empty fadvise flush fnmatch \
fputc ftruncate ftw fwrite getaddrinfo getenv getgrnam gethostbyaddr gethostbyname \
gethostbyname_r getmntent getopt getpass getpwnam getservbyname getservbyport getusershell \
glob grent hasmntopt hello iconv if_nameindex ltostr malloc-debugger math md5_testharness \
View
@@ -0,0 +1,111 @@
+#define _GNU_SOURCE
+#define _XOPEN_SOURCE 700
+#define _FILE_OFFSET_BITS 64
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdio.h>
+#include <sys/stat.h>
+
+#define TMPDIR "/tmp"
+
+#define TEST(_op) do { \
+ int rc = (_op); \
+ if (rc < 0) { \
+ printf("%s:%u: %s: %u/%s\n", __FILE__, __LINE__, \
+ # _op, errno, strerror(errno)); \
+ abort(); \
+ } \
+ } while (0)
+
+#define memeq(_a, _b) \
+ ((memcmp(_a, _b, sizeof *(_a)) == 0 ? 0 : -1))
+
+#define memne(_a, _b) \
+ ((memcmp(_a, _b, sizeof *(_a)) == 0 ? -1 : 0))
+
+int main(void)
+{
+ char dname_buf[] = "/tmp/test-mmap.XXXXXX";
+ char *dname;
+ int dir_fd;
+ int file_fd;
+ struct stat st[5];
+
+ /* check whether *at(2) syscalls are available */
+ dir_fd = openat(AT_FDCWD, "/", O_DIRECTORY|O_RDONLY);
+ if (dir_fd == -1 && errno == ENOSYS)
+ return EXIT_SUCCESS; /* kernel too old */
+
+ assert(dir_fd != -1);
+ close(dir_fd);
+
+ /* create a tree like
+ * /
+ * +- tmp/
+ * +- <tmpname>/
+ * |- test/
+ * |- some-file
+ * +- some-link -> some-file
+ */
+ dname = mkdtemp(dname_buf);
+ assert(dname != NULL);
+
+ dir_fd = open(dname, O_DIRECTORY|O_RDONLY);
+ assert(dir_fd != -1);
+
+ TEST(mkdirat(dir_fd, "test", 0700));
+ TEST(chdir(dname));
+ TEST(chdir("test"));
+
+ file_fd = openat(dir_fd, "some-file", O_WRONLY|O_CREAT, 0400);
+ assert(file_fd != -1);
+
+ write(file_fd, "some text\n", 10);
+ TEST(close(file_fd));
+
+ TEST(symlinkat("some-file", dir_fd, "some-link"));
+ TEST(symlinkat("dangling", dir_fd, "dangling-link"));
+
+ /* now check, whether attributes of 'some-file' and 'some-link'
+ * returned by stat(2), lstat(2) and fstatat(2) are consistent */
+ TEST(stat("../some-file", &st[0]));
+ TEST(lstat("../some-link", &st[1]));
+
+ TEST(fstatat(dir_fd, "some-file", &st[2], 0));
+ TEST(fstatat(dir_fd, "some-link", &st[3], AT_SYMLINK_NOFOLLOW));
+ TEST(fstatat(dir_fd, "some-link", &st[4], 0));
+
+ TEST(faccessat(dir_fd, "some-file", R_OK, 0));
+ TEST((faccessat(dir_fd, "some-file", W_OK, 0) == -1 &&
+ errno == EACCES) ? 0 : -1);;
+
+ if (1)
+ fputs("skipping faccessat(..., AT_SYMLINK_NOFOLLOW) checks for now...\n",
+ stderr);
+ else {
+ /* this is broken for dietlibc; the 'flags' parameter is not checked
+ * by the kernel but must be handled by the libc itself */
+ TEST(faccessat(dir_fd, "some-link", W_OK, AT_SYMLINK_NOFOLLOW));
+ TEST(faccessat(dir_fd, "dangling-link", R_OK, AT_SYMLINK_NOFOLLOW));
+ }
+
+ assert(st[0].st_mode == (0400 | S_IFREG));
+ assert(S_ISLNK(st[1].st_mode));
+
+ TEST(memne(&st[0], &st[1]));
+ TEST(memeq(&st[0], &st[2]));
+ TEST(memeq(&st[0], &st[4]));
+ TEST(memeq(&st[1], &st[3]));
+
+ /* and cleanup the mess... */
+ TEST(unlinkat(dir_fd, "some-link", 0));
+ TEST(unlinkat(dir_fd, "some-file", 0));
+ TEST(unlinkat(dir_fd, "dangling-link", 0));
+ TEST(unlinkat(dir_fd, "test", AT_REMOVEDIR));
+ TEST(rmdir(dname));
+
+ return EXIT_SUCCESS;
+}
View
@@ -1,6 +1,6 @@
SUBDIRS="dirent inet stdio string stdlib time"
-TESTPROGRAMS="adjtime alarm argv atexit bsearch byteswap calloc confstr empty fadvise flush fputc ffs fnmatch ftruncate ftw fwrite getaddrinfo getenv getdelim getgrnam gethostbyaddr gethostbyname gethostbyname_r getmntent getopt getpwnam getservbyname getservbyport getusershell glob grent hasmntopt hello iconv if_nameindex ltostr malloc-debugger math md5_testharness memccpy memchr memcmp memrchr memusage mktime mmap_test pipe printf printftest protoent prototypes putenv pwent rand48 readdir regex select sendfile servent setjmp siglist sigsetjmp speed spent sprintf sscanf stdarg strcasecmp strcmp strncat strncpy strptime strrchr strstr strtol sysconf sysenter ungetc utime waitpid"
+TESTPROGRAMS="adjtime alarm argv atexit atfile bsearch byteswap calloc confstr empty fadvise flush fputc ffs fnmatch ftruncate ftw fwrite getaddrinfo getenv getdelim getgrnam gethostbyaddr gethostbyname gethostbyname_r getmntent getopt getpwnam getservbyname getservbyport getusershell glob grent hasmntopt hello iconv if_nameindex ltostr malloc-debugger math md5_testharness memccpy memchr memcmp memrchr memusage mktime mmap_test pipe printf printftest protoent prototypes putenv pwent rand48 readdir regex select sendfile servent setjmp siglist sigsetjmp speed spent sprintf sscanf stdarg strcasecmp strcmp strncat strncpy strptime strrchr strstr strtol sysconf sysenter ungetc utime waitpid"
STDIN="read1"
PASS="getpass"

0 comments on commit 25938b3

Please sign in to comment.