getdents.c 3.1 KB

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