getdents.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #define _GNU_SOURCE
  2. #include <dirent.h>
  3. #include <fcntl.h>
  4. #include <inttypes.h>
  5. #include <stdio.h>
  6. #include <sys/stat.h>
  7. #include <sys/syscall.h>
  8. #include <unistd.h>
  9. struct linux_dirent {
  10. unsigned long d_ino;
  11. unsigned long d_off;
  12. unsigned short d_reclen;
  13. char d_name[];
  14. };
  15. struct linux_dirent64 {
  16. uint64_t d_ino;
  17. int64_t d_off;
  18. unsigned short d_reclen;
  19. unsigned char d_type;
  20. char d_name[];
  21. };
  22. #define BUF_SIZE 512
  23. int main() {
  24. int rv, fd, offs;
  25. const mode_t perm = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
  26. char buf[BUF_SIZE];
  27. // setup
  28. // We test a directory one level below root so ".." is also present in SGX.
  29. rv = mkdir("root", perm);
  30. if (rv) {
  31. perror("mkdir 1");
  32. return 1;
  33. }
  34. rv = mkdir("root/testdir", perm);
  35. if (rv) {
  36. perror("mkdir 2");
  37. return 1;
  38. }
  39. rv = creat("root/testdir/file1", perm);
  40. if (rv < 0) {
  41. perror("creat 1");
  42. return 1;
  43. }
  44. rv = close(rv);
  45. if (rv) {
  46. perror("close 1");
  47. return 1;
  48. }
  49. rv = creat("root/testdir/file2", perm);
  50. if (rv < 0) {
  51. perror("creat 2");
  52. return 1;
  53. }
  54. rv = close(rv);
  55. if (rv) {
  56. perror("close 2");
  57. return 1;
  58. }
  59. rv = mkdir("root/testdir/dir3", perm);
  60. if (rv) {
  61. perror("mkdir 3");
  62. return 1;
  63. }
  64. // enable symlink when implemented, or just use the LTP test
  65. // rv = symlink("root/testdir/file2", "root/testdir/link4");
  66. // if (rv) { perror ("symlink"); return 1; }
  67. printf("getdents: setup ok\n");
  68. // 32-bit listing
  69. fd = open("root/testdir", O_RDONLY | O_DIRECTORY);
  70. if (fd < 0) {
  71. perror("open 1");
  72. return 1;
  73. }
  74. while (1) {
  75. int count = syscall(SYS_getdents, fd, buf, BUF_SIZE);
  76. if (count < 0) {
  77. perror("getdents32");
  78. return 1;
  79. }
  80. if (count == 0)
  81. break;
  82. for (offs = 0; offs < count;) {
  83. struct linux_dirent* d32 = (struct linux_dirent*)(buf + offs);
  84. char d_type = *(buf + offs + d32->d_reclen - 1);
  85. printf("getdents32: %s [0x%x]\n", d32->d_name, d_type);
  86. offs += d32->d_reclen;
  87. }
  88. }
  89. rv = close(fd);
  90. if (rv) {
  91. perror("close 1");
  92. return 1;
  93. }
  94. // 64-bit listing
  95. fd = open("root/testdir", O_RDONLY | O_DIRECTORY);
  96. if (fd < 0) {
  97. perror("open 2");
  98. return 1;
  99. }
  100. while (1) {
  101. int count = syscall(SYS_getdents64, fd, buf, BUF_SIZE);
  102. if (count < 0) {
  103. perror("getdents64");
  104. return 1;
  105. }
  106. if (count == 0)
  107. break;
  108. for (offs = 0; offs < count;) {
  109. struct linux_dirent64* d64 = (struct linux_dirent64*)(buf + offs);
  110. printf("getdents64: %s [0x%x]\n", d64->d_name, d64->d_type);
  111. offs += d64->d_reclen;
  112. }
  113. }
  114. rv = close(fd);
  115. if (rv) {
  116. perror("close 2");
  117. return 1;
  118. }
  119. // cleanup
  120. remove("root/testdir/file1");
  121. remove("root/testdir/file2");
  122. remove("root/testdir/dir3");
  123. remove("root/testdir");
  124. remove("root");
  125. return 0;
  126. }