fork download
  1. #include <cstdio> // mkdtemp()
  2. #include <cstdlib> // getenv()
  3. #include <iostream> // cout, endl
  4. #include <vector>
  5.  
  6. namespace {
  7.  
  8. /// <summary>Creates a unique temporary directory for use by the unit tests</summary>
  9. class TemporaryDirectoryScope {
  10.  
  11. /// <summary>Creates the unique temporary directory</summary>
  12. public: TemporaryDirectoryScope() :
  13. path(createTemporaryDirectory()) {}
  14.  
  15. public: ~TemporaryDirectoryScope() { /* omitted */ }
  16.  
  17. /// <summary>Gives the path of the unique temporary directory</summary>
  18. /// <returns>The absolute path of the unique temporary directory</returns>
  19. public: const std::string &GetPath() const { return this->path; }
  20.  
  21. #if defined(NUCLEX_PIXELS_WIN32)
  22. #else // Any Linux/Posix compatible system
  23.  
  24. /// <summary>Creates a unique temporary directory and returns its path</summary>
  25. /// <returns>The path to the unique temporary directory</returns>
  26. private: static std::string createTemporaryDirectory() {
  27. std::vector<char> temporaryDirectoryPath;
  28. temporaryDirectoryPath.reserve(16 + 32);
  29.  
  30. // First, look up the system's temporary directory
  31. appendTempDirectory(temporaryDirectoryPath);
  32.  
  33. // Append a path component separator if appendTempDirectory() didn't provide one
  34. // and the temp path isn't empty (i.e. user wants temp files loaded into CWD ?_?)
  35. if(temporaryDirectoryPath.size() > 0) {
  36. if(temporaryDirectoryPath[temporaryDirectoryPath.size() - 1] != '/') {
  37. temporaryDirectoryPath.push_back('/');
  38. }
  39. }
  40.  
  41. // Then append our directory name template to it
  42. const char directoryNameTemplate[] = u8"nuclex-pixels-unittest-XXXXXX";
  43. {
  44. const char *iterator = directoryNameTemplate;
  45. while(*iterator != 0) {
  46. temporaryDirectoryPath.push_back(*iterator);
  47. ++iterator;
  48. }
  49. }
  50.  
  51. // DEBUGGING. REMOVE.
  52. std::cout <<
  53. u8"Passing the following to mkdtemp(): " <<
  54. std::string(&temporaryDirectoryPath[0], temporaryDirectoryPath.size()) <<
  55. std::endl;
  56.  
  57. // Let mkdtemp() sort out a unique directory name for us (and create it!)
  58. const char *directoryName = ::mkdtemp(&temporaryDirectoryPath[0]);
  59. if(directoryName == nullptr) {
  60. perror("mkdtemp() failed."); // DEBUGGING. REMOVE.
  61. throw std::runtime_error("mkdtemp() failed.");
  62. }
  63.  
  64. return std::string(&temporaryDirectoryPath[0], temporaryDirectoryPath.size());
  65. }
  66.  
  67. /// <summary>Appenfs the user's/system's preferred temp directory to a path</summary>
  68. /// <param name="path">Path vector the temp directory will be appended to</param>
  69. private: static void appendTempDirectory(std::vector<char> &path) {
  70.  
  71. // Obtain the most likely system temp directory
  72. const char *tempDirectory = ::getenv(u8"TMPDIR");
  73. if(tempDirectory == nullptr) {
  74. tempDirectory = ::getenv(u8"TMP");
  75. if(tempDirectory == nullptr) {
  76. tempDirectory = ::getenv(u8"TEMP");
  77. if(tempDirectory == nullptr) {
  78. // This is safe (part of the file system standard and Linux standard base),
  79. // but we wanted to honor any possible user preferences first.
  80. tempDirectory = u8"/tmp";
  81. }
  82. }
  83. }
  84.  
  85. // Append the temporary directory to the path vector
  86. while(*tempDirectory != 0) {
  87. path.push_back(*tempDirectory);
  88. ++tempDirectory;
  89. }
  90.  
  91. }
  92. #endif
  93.  
  94. /// <summary>Path of the temporary directory</summary>
  95. private: std::string path;
  96.  
  97. };
  98.  
  99. } // anonymous namespace
  100.  
  101. int main() {
  102. TemporaryDirectoryScope myTempDir;
  103.  
  104. std::cout <<
  105. u8"Determined temporary directory is " <<
  106. myTempDir.GetPath() <<
  107. std::endl;
  108. }
Success #stdin #stdout 0s 4312KB
stdin
Standard input is empty
stdout
Passing the following to mkdtemp(): /tmp/LY2gfB/nuclex-pixels-unittest-XXXXXX
Determined temporary directory is /tmp/LY2gfB/nuclex-pixels-unittest-zXYbHy