TestLibCMkTemp.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. * Copyright (c) 2021, the SerenityOS developers.
  3. * Copyright (c) 2021, Brian Gianforcaro <bgianf@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/String.h>
  8. #include <LibCore/File.h>
  9. #include <LibTest/TestCase.h>
  10. #include <fcntl.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <sys/mman.h>
  15. #include <sys/wait.h>
  16. #include <unistd.h>
  17. TEST_CASE(test_mktemp_unique_filename)
  18. {
  19. u8* ptr = (u8*)mmap(nullptr, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  20. EXPECT(ptr != MAP_FAILED);
  21. if (fork() == 0) {
  22. char path[] = "/tmp/test.mktemp.XXXXXX";
  23. auto temp_path = String::formatted("{}", mktemp(path));
  24. EXPECT(temp_path.characters());
  25. unlink(path);
  26. memcpy(&ptr[0], temp_path.characters(), temp_path.length());
  27. exit(EXIT_SUCCESS);
  28. } else {
  29. wait(NULL);
  30. auto path1 = String::formatted("{}", reinterpret_cast<char const*>(ptr));
  31. char path[] = "/tmp/test.mktemp.XXXXXX";
  32. auto path2 = String::formatted("{}", mktemp(path));
  33. EXPECT(path2.characters());
  34. unlink(path);
  35. EXPECT_NE(path1, path2);
  36. }
  37. munmap(ptr, sizeof(*ptr));
  38. }
  39. TEST_CASE(test_mkdtemp_unique_filename)
  40. {
  41. u8* ptr = (u8*)mmap(nullptr, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  42. EXPECT_NE(ptr, MAP_FAILED);
  43. if (fork() == 0) {
  44. char path[] = "/tmp/test.mkdtemp.XXXXXX";
  45. auto temp_path = String::formatted("{}", mkdtemp(path));
  46. EXPECT(temp_path.characters());
  47. rmdir(path);
  48. memcpy(&ptr[0], temp_path.characters(), temp_path.length());
  49. exit(EXIT_SUCCESS);
  50. } else {
  51. wait(NULL);
  52. auto path1 = String::formatted("{}", reinterpret_cast<char const*>(ptr));
  53. char path[] = "/tmp/test.mkdtemp.XXXXXX";
  54. auto path2 = String::formatted("{}", mkdtemp(path));
  55. EXPECT(path2.characters());
  56. rmdir(path);
  57. EXPECT_NE(path1, path2);
  58. }
  59. munmap(ptr, sizeof(*ptr));
  60. }
  61. TEST_CASE(test_mkstemp_unique_filename)
  62. {
  63. u8* ptr = (u8*)mmap(nullptr, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  64. EXPECT_NE(ptr, MAP_FAILED);
  65. if (fork() == 0) {
  66. char path[] = "/tmp/test.mkstemp.XXXXXX";
  67. auto fd = mkstemp(path);
  68. EXPECT_NE(fd, -1);
  69. auto temp_path_or_error = Core::File::read_link(String::formatted("/proc/{}/fd/{}", getpid(), fd));
  70. EXPECT(!temp_path_or_error.is_error());
  71. auto temp_path = temp_path_or_error.release_value();
  72. EXPECT(temp_path.characters());
  73. close(fd);
  74. unlink(path);
  75. memcpy(&ptr[0], temp_path.characters(), temp_path.length());
  76. exit(EXIT_SUCCESS);
  77. } else {
  78. wait(NULL);
  79. auto path1 = String::formatted("{}", reinterpret_cast<char const*>(ptr));
  80. char path[] = "/tmp/test.mkstemp.XXXXXX";
  81. auto fd = mkstemp(path);
  82. EXPECT(fd != -1);
  83. auto path2_or_error = Core::File::read_link(String::formatted("/proc/{}/fd/{}", getpid(), fd));
  84. EXPECT(!path2_or_error.is_error());
  85. auto path2 = path2_or_error.release_value();
  86. EXPECT(path2.characters());
  87. close(fd);
  88. unlink(path);
  89. EXPECT_NE(path1, path2);
  90. }
  91. munmap(ptr, sizeof(*ptr));
  92. }
  93. TEST_CASE(test_mkstemps_unique_filename)
  94. {
  95. u8* ptr = (u8*)mmap(nullptr, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  96. EXPECT_NE(ptr, MAP_FAILED);
  97. if (fork() == 0) {
  98. char path[] = "/tmp/test.mkstemps.prefixXXXXXXsuffix";
  99. auto fd = mkstemps(path, 6);
  100. EXPECT_NE(fd, -1);
  101. auto temp_path_or_error = Core::File::read_link(String::formatted("/proc/{}/fd/{}", getpid(), fd));
  102. EXPECT(!temp_path_or_error.is_error());
  103. auto temp_path = temp_path_or_error.release_value();
  104. EXPECT(temp_path.characters());
  105. close(fd);
  106. unlink(path);
  107. EXPECT(temp_path.starts_with("/tmp/test.mkstemps.prefix"sv));
  108. EXPECT(temp_path.ends_with("suffix"sv));
  109. EXPECT_EQ(strlen(path), temp_path.length());
  110. memcpy(&ptr[0], temp_path.characters(), temp_path.length());
  111. exit(EXIT_SUCCESS);
  112. } else {
  113. wait(NULL);
  114. auto path1 = String::formatted("{}", reinterpret_cast<char const*>(ptr));
  115. char path[] = "/tmp/test.mkstemps.prefixXXXXXXsuffix";
  116. auto fd = mkstemps(path, 6);
  117. EXPECT(fd != -1);
  118. auto path2_or_error = Core::File::read_link(String::formatted("/proc/{}/fd/{}", getpid(), fd));
  119. EXPECT(!path2_or_error.is_error());
  120. auto path2 = path2_or_error.release_value();
  121. EXPECT(path2.characters());
  122. close(fd);
  123. unlink(path);
  124. EXPECT(path2.starts_with("/tmp/test.mkstemps.prefix"sv));
  125. EXPECT(path2.ends_with("suffix"sv));
  126. EXPECT_EQ(strlen(path), path2.length());
  127. EXPECT_NE(path1, path2);
  128. }
  129. munmap(ptr, sizeof(*ptr));
  130. }