scoped_tmpfile.cc
1 // Copyright 2022 Google LLC 2 // 3 // Redistribution and use in source and binary forms, with or without 4 // modification, are permitted provided that the following conditions are 5 // met: 6 // 7 // * Redistributions of source code must retain the above copyright 8 // notice, this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above 10 // copyright notice, this list of conditions and the following disclaimer 11 // in the documentation and/or other materials provided with the 12 // distribution. 13 // * Neither the name of Google LLC nor the names of its 14 // contributors may be used to endorse or promote products derived from 15 // this software without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 // Utility class for creating a temporary file that is deleted in the 30 // destructor. 31 32 #ifdef HAVE_CONFIG_H 33 #include <config.h> // Must come first 34 #endif 35 36 #include "common/linux/scoped_tmpfile.h" 37 38 #include <fcntl.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <sys/types.h> 42 #include <unistd.h> 43 44 #include "common/linux/eintr_wrapper.h" 45 46 #if !defined(__ANDROID__) 47 #define TEMPDIR "/tmp" 48 #else 49 #define TEMPDIR "/data/local/tmp" 50 #endif 51 52 namespace google_breakpad { 53 54 ScopedTmpFile::ScopedTmpFile() = default; 55 56 ScopedTmpFile::~ScopedTmpFile() { 57 if (fd_ >= 0) { 58 close(fd_); 59 fd_ = -1; 60 } 61 } 62 63 bool ScopedTmpFile::InitEmpty() { 64 // Prevent calling Init when fd_ is already valid, leaking the file. 65 if (fd_ != -1) { 66 return false; 67 } 68 69 // Respect the TMPDIR environment variable. 70 const char* tempdir = getenv("TMPDIR"); 71 if (!tempdir) { 72 tempdir = TEMPDIR; 73 } 74 75 // Create a temporary file that is not linked in to the filesystem, and that 76 // is only accessible by the current user. 77 fd_ = open(tempdir, O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); 78 79 return fd_ >= 0; 80 } 81 82 bool ScopedTmpFile::InitString(const char* text) { 83 return InitData(text, strlen(text)); 84 } 85 86 bool ScopedTmpFile::InitData(const void* data, size_t data_len) { 87 if (!InitEmpty()) { 88 return false; 89 } 90 91 return SetContents(data, data_len); 92 } 93 94 bool ScopedTmpFile::SetContents(const void* data, size_t data_len) { 95 ssize_t r = HANDLE_EINTR(write(fd_, data, data_len)); 96 if (r != static_cast<ssize_t>(data_len)) { 97 return false; 98 } 99 100 return 0 == lseek(fd_, 0, SEEK_SET); 101 } 102 103 } // namespace google_breakpad