Почему `mkdtemp ()` терпит неудачу при вызове в googletest? - PullRequest
1 голос
/ 03 ноября 2019

Я создал небольшой класс RAII, который создает уникальный временный каталог и снова удаляет его после уничтожения. В Linux для достижения этой цели используется mkdtemp():

// temporaryDirectoryPath is an std::vector<char>
// containing u8"/tmp/nuclex-pixels-unittest-XXXXXX"

// Let mkdtemp() sort out a unique directory name for us (and create it!)
const char *directoryName = ::mkdtemp(&temporaryDirectoryPath[0]);
if(directoryName == nullptr) {
  perror("mkdtemp() failed."); // DEBUGGING. REMOVE.
  throw std::runtime_error("mkdtemp() failed.");
}

Это прекрасно работает, когда запускается сам по себе: исполняемый код на ideone.com


Однако, если я использую тот же код внутри GoogleTest 1.8.1 модульного теста, объявленного так:

TEST(MyTestFixture, CanFlumbleTempDirectory) {
  TemporaryDirectoryScope temporaryDirectory;
  // Could call temporaryDirectory.GetPath() here...
}

Сбой:

Passing the following to mkdtemp(): /tmp/nuclex-pixels-unittest-XXXXXX
mkdtemp() failed.: Invalid argument

Как GoogleTest может мешать mkdtemp()?

1 Ответ

2 голосов
/ 03 ноября 2019

Строка, которую вы передаете mkdtemp, не является надежно завершенной нулем:

      // Then append our directory name template to it
      const char directoryNameTemplate[] = u8"nuclex-pixels-unittest-XXXXXX";
      {
        const char *iterator = directoryNameTemplate;
        while(*iterator != 0) {
          temporaryDirectoryPath.push_back(*iterator);
          ++iterator;
        }
      }

std::vector<char> не выполняет неявное нулевое завершение, в отличие от std::string. Это работает случайно, если после суффикса "XXXXXX" окажется нулевой байт. То, что это так, зависит от среды выполнения.

...