protobuf/src/google/protobuf/testing/file.cc
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: kenton@google.com (Kenton Varda)
32 // emulates google3/file/base/file.cc
33 
34 #include <google/protobuf/testing/file.h>
35 #include <stdio.h>
36 #include <sys/stat.h>
37 #include <sys/types.h>
38 #ifdef _MSC_VER
39 #define WIN32_LEAN_AND_MEAN // yeah, right
40 #include <windows.h> // Find*File(). :(
41 // #include <direct.h>
42 #else
43 #include <dirent.h>
44 #include <unistd.h>
45 #endif
46 #include <errno.h>
47 
48 #include <google/protobuf/io/io_win32.h>
49 #include <google/protobuf/stubs/logging.h>
50 
51 namespace google {
52 namespace protobuf {
53 
54 #ifdef _WIN32
55 // Windows doesn't have symbolic links.
56 #define lstat stat
57 // DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
58 // them like we do below.
59 #endif
60 
61 #ifdef _WIN32
62 using google::protobuf::io::win32::access;
63 using google::protobuf::io::win32::chdir;
64 using google::protobuf::io::win32::fopen;
65 using google::protobuf::io::win32::mkdir;
67 #endif
68 
70  return access(name.c_str(), F_OK) == 0;
71 }
72 
74  bool text_mode) {
75  char buffer[1024];
76  FILE* file = fopen(name.c_str(), text_mode ? "rt" : "rb");
77  if (file == NULL) return false;
78 
79  while (true) {
80  size_t n = fread(buffer, 1, sizeof(buffer), file);
81  if (n <= 0) break;
82  output->append(buffer, n);
83  }
84 
85  int error = ferror(file);
86  if (fclose(file) != 0) return false;
87  return error == 0;
88 }
89 
91  GOOGLE_CHECK(ReadFileToString(name, output)) << "Could not read: " << name;
92 }
93 
95  const std::string& name) {
96  FILE* file = fopen(name.c_str(), "wb");
97  if (file == NULL) {
98  GOOGLE_LOG(ERROR) << "fopen(" << name << ", \"wb\"): " << strerror(errno);
99  return false;
100  }
101 
102  if (fwrite(contents.data(), 1, contents.size(), file) != contents.size()) {
103  GOOGLE_LOG(ERROR) << "fwrite(" << name << "): " << strerror(errno);
104  fclose(file);
105  return false;
106  }
107 
108  if (fclose(file) != 0) {
109  return false;
110  }
111  return true;
112 }
113 
115  const std::string& name) {
116  FILE* file = fopen(name.c_str(), "wb");
117  GOOGLE_CHECK(file != NULL)
118  << "fopen(" << name << ", \"wb\"): " << strerror(errno);
119  GOOGLE_CHECK_EQ(fwrite(contents.data(), 1, contents.size(), file),
120  contents.size())
121  << "fwrite(" << name << "): " << strerror(errno);
122  GOOGLE_CHECK(fclose(file) == 0)
123  << "fclose(" << name << "): " << strerror(errno);
124 }
125 
127  if (!name.empty()) {
128  GOOGLE_CHECK_OK(name[name.size() - 1] != '.');
129  }
130  return mkdir(name.c_str(), mode) == 0;
131 }
132 
134  if (CreateDir(path, mode)) return true;
135 
136  if (Exists(path)) return false;
137 
138  // Try creating the parent.
139  std::string::size_type slashpos = path.find_last_of('/');
140  if (slashpos == std::string::npos) {
141  // No parent given.
142  return false;
143  }
144 
145  return RecursivelyCreateDir(path.substr(0, slashpos), mode) &&
146  CreateDir(path, mode);
147 }
148 
149 void File::DeleteRecursively(const std::string& name, void* dummy1,
150  void* dummy2) {
151  if (name.empty()) return;
152 
153  // We don't care too much about error checking here since this is only used
154  // in tests to delete temporary directories that are under /tmp anyway.
155 
156 #ifdef _MSC_VER
157  // This interface is so weird.
158  WIN32_FIND_DATAA find_data;
159  HANDLE find_handle = FindFirstFileA((name + "/*").c_str(), &find_data);
160  if (find_handle == INVALID_HANDLE_VALUE) {
161  // Just delete it, whatever it is.
162  DeleteFileA(name.c_str());
163  RemoveDirectoryA(name.c_str());
164  return;
165  }
166 
167  do {
168  std::string entry_name = find_data.cFileName;
169  if (entry_name != "." && entry_name != "..") {
170  std::string path = name + "/" + entry_name;
171  if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
172  DeleteRecursively(path, NULL, NULL);
173  RemoveDirectoryA(path.c_str());
174  } else {
175  DeleteFileA(path.c_str());
176  }
177  }
178  } while(FindNextFileA(find_handle, &find_data));
179  FindClose(find_handle);
180 
181  RemoveDirectoryA(name.c_str());
182 #else
183  // Use opendir()! Yay!
184  // lstat = Don't follow symbolic links.
185  struct stat stats;
186  if (lstat(name.c_str(), &stats) != 0) return;
187 
188  if (S_ISDIR(stats.st_mode)) {
189  DIR* dir = opendir(name.c_str());
190  if (dir != NULL) {
191  while (true) {
192  struct dirent* entry = readdir(dir);
193  if (entry == NULL) break;
194  std::string entry_name = entry->d_name;
195  if (entry_name != "." && entry_name != "..") {
196  DeleteRecursively(name + "/" + entry_name, NULL, NULL);
197  }
198  }
199  }
200 
201  closedir(dir);
202  rmdir(name.c_str());
203 
204  } else if (S_ISREG(stats.st_mode)) {
205  remove(name.c_str());
206  }
207 #endif
208 }
209 
210 bool File::ChangeWorkingDirectory(const std::string& new_working_directory) {
211  return chdir(new_working_directory.c_str()) == 0;
212 }
213 
214 } // namespace protobuf
215 } // namespace google
rmdir
#define rmdir
Definition: test-fs.c:45
GOOGLE_CHECK_EQ
#define GOOGLE_CHECK_EQ(A, B)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:156
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
error
grpc_error_handle error
Definition: retry_filter.cc:499
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
google::protobuf
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:12
mode
const char int mode
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:135
setup.name
name
Definition: setup.py:542
check_documentation.path
path
Definition: check_documentation.py:57
google::protobuf::File::WriteStringToFileOrDie
static void WriteStringToFileOrDie(const string &contents, const string &name)
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/file.cc:112
google::protobuf::File::WriteStringToFile
static bool WriteStringToFile(const string &contents, const string &name)
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/file.cc:93
absl::string_view::size
constexpr size_type size() const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:277
gen_stats_data.c_str
def c_str(s, encoding='ascii')
Definition: gen_stats_data.py:38
gmock_output_test.output
output
Definition: bloaty/third_party/googletest/googlemock/test/gmock_output_test.py:175
gen_stats_data.stats
list stats
Definition: gen_stats_data.py:58
google::protobuf::File::ReadFileToStringOrDie
static void ReadFileToStringOrDie(const string &name, string *output)
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/file.cc:89
buffer
char buffer[1024]
Definition: libuv/docs/code/idle-compute/main.c:8
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
google::protobuf::ERROR
static const LogLevel ERROR
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/googletest.h:70
google::protobuf::File::ReadFileToString
static bool ReadFileToString(const string &name, string *output, bool text_mode=false)
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/file.cc:73
contents
string_view contents
Definition: elf.cc:597
benchmark.FILE
FILE
Definition: benchmark.py:21
grpc::fclose
fclose(creds_file)
F_OK
#define F_OK
Definition: win.h:655
google::protobuf::File::RecursivelyCreateDir
static bool RecursivelyCreateDir(const string &path, int mode)
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/file.cc:130
INVALID_HANDLE_VALUE
#define INVALID_HANDLE_VALUE
Definition: bloaty/third_party/zlib/contrib/minizip/iowin32.c:21
google::protobuf::File::ChangeWorkingDirectory
static bool ChangeWorkingDirectory(const string &new_working_directory)
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/file.cc:207
GOOGLE_CHECK
#define GOOGLE_CHECK(EXPRESSION)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:153
stat
#define stat
Definition: test-fs.c:50
google::protobuf::File::CreateDir
static bool CreateDir(const string &name, int mode)
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/file.cc:123
access
Definition: bloaty/third_party/zlib/examples/zran.c:75
GOOGLE_LOG
#define GOOGLE_LOG(LEVEL)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:146
absl::string_view::data
constexpr const_pointer data() const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:336
dummy2
int dummy2
Definition: benchmark/test/register_benchmark_test.cc:93
google
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:11
google::protobuf::File::DeleteRecursively
static void DeleteRecursively(const string &name, void *dummy1, void *dummy2)
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/file.cc:146
errno.h
GOOGLE_CHECK_OK
#define GOOGLE_CHECK_OK(A)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:155
google::protobuf::File::Exists
static bool Exists(const string &name)
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/file.cc:69


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:23