mktemp.cpp 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. #include "tempfile.h"
  2. #include <util/folder/dirut.h>
  3. #include <util/generic/yexception.h>
  4. #include <cstring>
  5. #ifdef _win32_
  6. #include "winint.h"
  7. #include <io.h>
  8. #else
  9. #include <unistd.h>
  10. #endif
  11. extern "C" int mkstemps(char* path, int slen);
  12. TString MakeTempName(const char* wrkDir, const char* prefix, const char* extension) {
  13. TString filePath;
  14. if (wrkDir && *wrkDir) {
  15. filePath += wrkDir;
  16. } else {
  17. filePath += GetSystemTempDir();
  18. }
  19. #ifdef _win32_
  20. // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettempfilenamea?redirectedfrom=MSDN
  21. const unsigned int DirPathMaxLen = 247;
  22. if (filePath.length() <= DirPathMaxLen) {
  23. // it always takes up to 3 characters, no more
  24. char winFilePath[MAX_PATH];
  25. if (GetTempFileName(filePath.c_str(), (prefix) ? (prefix) : "yan", 0,
  26. winFilePath)) {
  27. return winFilePath;
  28. }
  29. }
  30. #endif // _win32_
  31. if (filePath.back() != '/') {
  32. filePath += '/';
  33. }
  34. if (prefix) {
  35. filePath += prefix;
  36. }
  37. filePath += "XXXXXX"; // mkstemps requirement
  38. size_t extensionPartLength = 0;
  39. if (extension && *extension) {
  40. if (extension[0] != '.') {
  41. filePath += '.';
  42. extensionPartLength += 1;
  43. }
  44. filePath += extension;
  45. extensionPartLength += strlen(extension);
  46. }
  47. int fd = mkstemps(const_cast<char*>(filePath.data()), extensionPartLength);
  48. if (fd >= 0) {
  49. close(fd);
  50. return filePath;
  51. }
  52. ythrow TSystemError() << "can not create temp name(" << wrkDir << ", " << prefix << ", " << extension << ")";
  53. }