large_dir_read.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #define _GNU_SOURCE
  2. #include <dirent.h>
  3. #include <err.h>
  4. #include <errno.h>
  5. #include <fcntl.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <sys/stat.h>
  10. #include <sys/types.h>
  11. #include <unistd.h>
  12. static unsigned int FILES_NO = 10000;
  13. static int is_dot_or_dotdot(const char* name) {
  14. return (name[0] == '.' && !name[1]) || (name[0] == '.' && name[1] == '.' && !name[2]);
  15. }
  16. int main(int argc, char* argv[]) {
  17. int fd = 0, ret = 1;
  18. char name[21] = {0};
  19. DIR* dir = NULL;
  20. struct dirent* dent = NULL;
  21. unsigned long i = 0;
  22. char* tmp_name = NULL;
  23. char* old_wd = NULL;
  24. unsigned char* seen = NULL;
  25. setbuf(stdout, NULL);
  26. setbuf(stderr, NULL);
  27. if (argc != 2 && argc != 3) {
  28. fprintf(stderr, "Usage: %s tmp_folder_name [files_count]\n", argv[0]);
  29. return 1;
  30. }
  31. tmp_name = argv[1];
  32. if (argc > 2) {
  33. FILES_NO = atol(argv[2]);
  34. }
  35. if (!(seen = calloc(FILES_NO, sizeof *seen))) {
  36. err(1, "calloc");
  37. }
  38. if ((old_wd = get_current_dir_name()) == NULL) {
  39. err(1, "getcwd");
  40. }
  41. if (mkdir(tmp_name, S_IRWXU | S_IRWXG | S_IRWXO) < 0 || chdir(tmp_name) < 0) {
  42. err(1, "mkdir & chdir");
  43. }
  44. for (i = 0; i < FILES_NO; i++) {
  45. snprintf(name, sizeof(name), "%010lu", i);
  46. fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
  47. if (fd < 0) {
  48. fprintf(stderr, "error: cannot create file %lu: %s\n", i, strerror(errno));
  49. goto cleanup;
  50. }
  51. if (close(fd) < 0) {
  52. fprintf(stderr, "error: close failed with: %s\n", strerror(errno));
  53. goto cleanup;
  54. }
  55. }
  56. dir = opendir(".");
  57. if (!dir) {
  58. fprintf(stderr, "error: cannot open \".\": %s\n", strerror(errno));
  59. goto cleanup;
  60. }
  61. while (1) {
  62. errno = 0;
  63. dent = readdir(dir);
  64. if (!dent) {
  65. if (errno != 0) {
  66. fprintf(stderr, "error: readdir: %s\n", strerror(errno));
  67. goto cleanup;
  68. } else {
  69. break;
  70. }
  71. }
  72. if (is_dot_or_dotdot(dent->d_name)) {
  73. continue;
  74. }
  75. i = atol(dent->d_name);
  76. if (i >= FILES_NO) {
  77. fprintf(stderr, "error: weird file found: \"%s\"\n", dent->d_name);
  78. goto cleanup;
  79. }
  80. if (seen[i]) {
  81. fprintf(stderr, "error: file \"%s\" seen multiple times\n", dent->d_name);
  82. goto cleanup;
  83. }
  84. seen[i] = 1;
  85. }
  86. for (i = 0; i < FILES_NO; i++) {
  87. if (!seen[i]) {
  88. fprintf(stderr, "error: file %lu not seen!\n", i);
  89. goto cleanup;
  90. }
  91. }
  92. puts("Success!");
  93. ret = 0;
  94. cleanup:
  95. if (dir) {
  96. closedir(dir);
  97. }
  98. for (i = 0; i < FILES_NO; i++) {
  99. sprintf(name, "%010lu", i);
  100. if (unlink(name)) {
  101. ret = 1;
  102. fprintf(stderr, "error: could not remove file %s: %s\n", name, strerror(errno));
  103. }
  104. }
  105. if (chdir(old_wd) < 0) {
  106. ret = 1;
  107. fprintf(stderr, "error: could not change directory to original (%s): %s\n", old_wd,
  108. strerror(errno));
  109. }
  110. free(old_wd);
  111. if (rmdir(tmp_name) < 0) {
  112. ret = 1;
  113. fprintf(stderr, "error: could not remove tmp directory (%s): %s\n", tmp_name,
  114. strerror(errno));
  115. }
  116. return ret;
  117. }