getdents.c 2.8 KB

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