getdents.c 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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) { perror ("mkdir 1"); return 1; }
  30. rv = mkdir("root/testdir", perm);
  31. if (rv) { perror ("mkdir 2"); return 1; }
  32. rv = creat("root/testdir/file1", perm);
  33. if (rv < 0) { perror ("creat 1"); return 1; }
  34. rv = close(rv);
  35. if (rv) { perror ("close 1"); return 1; }
  36. rv = creat("root/testdir/file2", perm);
  37. if (rv < 0) { perror ("creat 2"); return 1; }
  38. rv = close(rv);
  39. if (rv) { perror ("close 2"); return 1; }
  40. rv = mkdir("root/testdir/dir3", perm);
  41. if (rv) { perror ("mkdir 3"); return 1; }
  42. // enable symlink when implemented, or just use the LTP test
  43. // rv = symlink("root/testdir/file2", "root/testdir/link4");
  44. // if (rv) { perror ("symlink"); return 1; }
  45. printf("getdents: setup ok\n");
  46. // 32-bit listing
  47. fd = open("root/testdir", O_RDONLY | O_DIRECTORY);
  48. if (fd < 0) { perror ("open 1"); return 1; }
  49. while (1) {
  50. int count = syscall(SYS_getdents, fd, buf, BUF_SIZE);
  51. if (count < 0) { perror ("getdents32"); return 1; }
  52. if (count == 0) break;
  53. for (offs = 0; offs < count; ) {
  54. struct linux_dirent *d32 = (struct linux_dirent *) (buf + offs);
  55. char d_type = *(buf + offs + d32->d_reclen - 1);
  56. printf("getdents32: %s [0x%x]\n", d32->d_name, d_type);
  57. offs += d32->d_reclen;
  58. }
  59. }
  60. rv = close(fd);
  61. if (rv) { perror ("close 1"); return 1; }
  62. // 64-bit listing
  63. fd = open("root/testdir", O_RDONLY | O_DIRECTORY);
  64. if (fd < 0) { perror ("open 2"); return 1; }
  65. while (1) {
  66. int count = syscall(SYS_getdents64, fd, buf, BUF_SIZE);
  67. if (count < 0) { perror ("getdents64"); return 1; }
  68. if (count == 0) break;
  69. for (offs = 0; offs < count; ) {
  70. struct linux_dirent64 *d64 = (struct linux_dirent64 *) (buf + offs);
  71. printf("getdents64: %s [0x%x]\n", d64->d_name, d64->d_type);
  72. offs += d64->d_reclen;
  73. }
  74. }
  75. rv = close(fd);
  76. if (rv) { perror ("close 2"); return 1; }
  77. // cleanup
  78. remove("root/testdir/file1");
  79. remove("root/testdir/file2");
  80. remove("root/testdir/dir3");
  81. remove("root/testdir");
  82. remove("root");
  83. return 0;
  84. }