123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- #define _GNU_SOURCE
- #include <dirent.h>
- #include <fcntl.h>
- #include <inttypes.h>
- #include <stdio.h>
- #include <sys/stat.h>
- #include <sys/syscall.h>
- #include <unistd.h>
- struct linux_dirent {
- unsigned long d_ino;
- unsigned long d_off;
- unsigned short d_reclen;
- char d_name[];
- };
- struct linux_dirent64 {
- uint64_t d_ino;
- int64_t d_off;
- unsigned short d_reclen;
- unsigned char d_type;
- char d_name[];
- };
- #define BUF_SIZE 512
- int main() {
- int rv, fd, offs;
- const mode_t perm = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
- char buf[BUF_SIZE];
- // setup
- // We test a directory one level below root so ".." is also present in SGX.
- rv = mkdir("root", perm);
- if (rv) {
- perror("mkdir 1");
- return 1;
- }
- rv = mkdir("root/testdir", perm);
- if (rv) {
- perror("mkdir 2");
- return 1;
- }
- rv = creat("root/testdir/file1", perm);
- if (rv < 0) {
- perror("creat 1");
- return 1;
- }
- rv = close(rv);
- if (rv) {
- perror("close 1");
- return 1;
- }
- rv = creat("root/testdir/file2", perm);
- if (rv < 0) {
- perror("creat 2");
- return 1;
- }
- rv = close(rv);
- if (rv) {
- perror("close 2");
- return 1;
- }
- rv = mkdir("root/testdir/dir3", perm);
- if (rv) {
- perror("mkdir 3");
- return 1;
- }
- // enable symlink when implemented, or just use the LTP test
- // rv = symlink("root/testdir/file2", "root/testdir/link4");
- // if (rv) { perror ("symlink"); return 1; }
- printf("getdents: setup ok\n");
- // 32-bit listing
- fd = open("root/testdir", O_RDONLY | O_DIRECTORY);
- if (fd < 0) {
- perror("open 1");
- return 1;
- }
- while (1) {
- int count = syscall(SYS_getdents, fd, buf, BUF_SIZE);
- if (count < 0) {
- perror("getdents32");
- return 1;
- }
- if (count == 0)
- break;
- for (offs = 0; offs < count;) {
- struct linux_dirent* d32 = (struct linux_dirent*)(buf + offs);
- char d_type = *(buf + offs + d32->d_reclen - 1);
- printf("getdents32: %s [0x%x]\n", d32->d_name, d_type);
- offs += d32->d_reclen;
- }
- }
- rv = close(fd);
- if (rv) {
- perror("close 1");
- return 1;
- }
- // 64-bit listing
- fd = open("root/testdir", O_RDONLY | O_DIRECTORY);
- if (fd < 0) {
- perror("open 2");
- return 1;
- }
- while (1) {
- int count = syscall(SYS_getdents64, fd, buf, BUF_SIZE);
- if (count < 0) {
- perror("getdents64");
- return 1;
- }
- if (count == 0)
- break;
- for (offs = 0; offs < count;) {
- struct linux_dirent64* d64 = (struct linux_dirent64*)(buf + offs);
- printf("getdents64: %s [0x%x]\n", d64->d_name, d64->d_type);
- offs += d64->d_reclen;
- }
- }
- rv = close(fd);
- if (rv) {
- perror("close 2");
- return 1;
- }
- // cleanup
- remove("root/testdir/file1");
- remove("root/testdir/file2");
- remove("root/testdir/dir3");
- remove("root/testdir");
- remove("root");
- return 0;
- }
|