• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/utils/io/tmpfile.h"
16 
17 #include <unistd.h>
18 #include <limits>
19 
20 #include "src/debug.h"
21 
22 namespace tint {
23 namespace utils {
24 
25 namespace {
26 
TmpFilePath(std::string ext)27 std::string TmpFilePath(std::string ext) {
28   char const* dir = getenv("TMPDIR");
29   if (dir == nullptr) {
30     dir = "/tmp";
31   }
32 
33   // mkstemps requires an `int` for the file extension name but STL represents
34   // size_t. Pre-C++20 there the behavior for unsigned-to-signed conversion
35   // (when the source value exceeds the representable range) is implementation
36   // defined. While such a large file extension is unlikely in practice, we
37   // enforce this here at runtime.
38   TINT_ASSERT(Utils, ext.length() <=
39                          static_cast<size_t>(std::numeric_limits<int>::max()));
40   std::string name = std::string(dir) + "/tint_XXXXXX" + ext;
41   int file = mkstemps(&name[0], static_cast<int>(ext.length()));
42   if (file != -1) {
43     close(file);
44     return name;
45   }
46   return "";
47 }
48 
49 }  // namespace
50 
TmpFile(std::string extension)51 TmpFile::TmpFile(std::string extension)
52     : path_(TmpFilePath(std::move(extension))) {}
53 
~TmpFile()54 TmpFile::~TmpFile() {
55   if (!path_.empty()) {
56     remove(path_.c_str());
57   }
58 }
59 
Append(const void * data,size_t size) const60 bool TmpFile::Append(const void* data, size_t size) const {
61   if (auto* file = fopen(path_.c_str(), "ab")) {
62     fwrite(data, size, 1, file);
63     fclose(file);
64     return true;
65   }
66   return false;
67 }
68 
69 }  // namespace utils
70 }  // namespace tint
71