tempnam.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "test_helpers.h"
  5. static void test_prefix(const char *prefix);
  6. static void test_dir(const char *dir);
  7. static void test_dir_and_prefix(const char *dir, const char *prefix);
  8. int main(void) {
  9. char *first_null = tempnam(NULL, NULL);
  10. if(first_null == NULL) {
  11. // NOTE: assuming that we can at least get one file name
  12. puts("tempnam(NULL, NULL) returned NULL on first try");
  13. exit(EXIT_FAILURE);
  14. }
  15. printf("%s\n", first_null);
  16. char *second_null = tempnam(NULL, NULL);
  17. if(second_null == NULL) {
  18. // NOTE: assuming that we can at least get one file name
  19. puts("tempnam(NULL, NULL) returned NULL on second try");
  20. free(first_null);
  21. exit(EXIT_FAILURE);
  22. }
  23. printf("%s\n", second_null);
  24. free(first_null);
  25. free(second_null);
  26. if(first_null == second_null) {
  27. puts("tempnam(NULL, NULL) returns the same address");
  28. exit(EXIT_FAILURE);
  29. }
  30. // Ensure the "prefix" argument works
  31. test_prefix("this_is_a_test_prefix");
  32. test_prefix("exact");
  33. test_prefix("hi");
  34. test_prefix("");
  35. // Ensure the "dir" argument works
  36. // NOTE: needed because TMPDIR is the first directory checked
  37. unsetenv("TMPDIR");
  38. test_dir("/tmp");
  39. test_dir("");
  40. // NOTE: assumes /root is NOT writable
  41. test_dir("/root");
  42. // Ensure "prefix" and "dir" work together
  43. test_dir_and_prefix("/tmp", "this_is_a_prefix");
  44. test_dir_and_prefix("/tmp", "exact");
  45. test_dir_and_prefix("/root", "exact");
  46. test_dir_and_prefix("/root", "long_prefix");
  47. test_dir_and_prefix("", "prefix");
  48. test_dir_and_prefix("/tmp", "test");
  49. return 0;
  50. }
  51. static void test_prefix(const char *prefix) {
  52. test_dir_and_prefix(NULL, prefix);
  53. }
  54. static void test_dir(const char *dir) {
  55. test_dir_and_prefix(dir, NULL);
  56. }
  57. static void test_dir_and_prefix(const char *dir, const char *prefix) {
  58. char funcbuf[256];
  59. if(dir && prefix) {
  60. snprintf(funcbuf, sizeof(funcbuf), "tempnam(\"%s\", \"%s\")", dir, prefix);
  61. } else if(dir) {
  62. snprintf(funcbuf, sizeof(funcbuf), "tempnam(\"%s\", NULL)", dir);
  63. } else if(prefix) {
  64. snprintf(funcbuf, sizeof(funcbuf), "tempnam(NULL, \"%s\")", prefix);
  65. } else {
  66. strcpy(funcbuf, "tempnam(NULL, NULL)");
  67. }
  68. char *result = tempnam(dir, prefix);
  69. if(!result) {
  70. printf("%s failed\n", funcbuf);
  71. exit(EXIT_FAILURE);
  72. }
  73. printf("%s\n", result);
  74. if(prefix) {
  75. char buf[7] = { '/' };
  76. strncpy(&buf[1], prefix, sizeof(buf) - 2);
  77. buf[6] = 0;
  78. char *prev = NULL;
  79. char *substr = result;
  80. do {
  81. prev = substr;
  82. substr = strstr(&substr[1], buf);
  83. } while(substr);
  84. substr = prev;
  85. if(!substr) {
  86. printf("%s did not add the full (5 bytes at most) prefix\n", funcbuf);
  87. free(result);
  88. exit(EXIT_FAILURE);
  89. } else if(strlen(substr) != strlen(&buf[1]) + L_tmpnam) {
  90. printf("%s has the wrong length\n", funcbuf);
  91. free(result);
  92. exit(EXIT_FAILURE);
  93. }
  94. }
  95. if(dir) {
  96. char *substr = strstr(result, dir);
  97. char *other_substr = strstr(result, P_tmpdir);
  98. if(!substr && !other_substr) {
  99. printf("%s is in an unexpected directory\n", funcbuf);
  100. free(result);
  101. exit(EXIT_FAILURE);
  102. }
  103. }
  104. free(result);
  105. }