OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 27 matching lines...) Expand all Loading... |
38 #if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) | 38 #if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) |
39 #include <ctype.h> | 39 #include <ctype.h> |
40 #include <algorithm> | 40 #include <algorithm> |
41 #endif | 41 #endif |
42 | 42 |
43 #if defined(__native_client__) && !defined(__GLIBC__) | 43 #if defined(__native_client__) && !defined(__GLIBC__) |
44 #include <sys/syslimits.h> | 44 #include <sys/syslimits.h> |
45 #endif | 45 #endif |
46 | 46 |
47 #include "webrtc/base/arraysize.h" | 47 #include "webrtc/base/arraysize.h" |
| 48 #include "webrtc/base/checks.h" |
48 #include "webrtc/base/fileutils.h" | 49 #include "webrtc/base/fileutils.h" |
49 #include "webrtc/base/pathutils.h" | 50 #include "webrtc/base/pathutils.h" |
50 #include "webrtc/base/stream.h" | 51 #include "webrtc/base/stream.h" |
51 #include "webrtc/base/stringutils.h" | 52 #include "webrtc/base/stringutils.h" |
52 | 53 |
53 #if defined(WEBRTC_MAC) | 54 #if defined(WEBRTC_MAC) |
54 // Defined in applefilesystem.mm. No header file to discourage use | 55 // Defined in applefilesystem.mm. No header file to discourage use |
55 // elsewhere; other places should use GetApp{Data,Temp}Folder() in | 56 // elsewhere; other places should use GetApp{Data,Temp}Folder() in |
56 // this file. Don't copy/paste. I mean it. | 57 // this file. Don't copy/paste. I mean it. |
57 char* AppleDataDirectory(); | 58 char* AppleDataDirectory(); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 delete fs; | 130 delete fs; |
130 fs = NULL; | 131 fs = NULL; |
131 } | 132 } |
132 return fs; | 133 return fs; |
133 } | 134 } |
134 | 135 |
135 bool UnixFilesystem::DeleteFile(const Pathname &filename) { | 136 bool UnixFilesystem::DeleteFile(const Pathname &filename) { |
136 LOG(LS_INFO) << "Deleting file:" << filename.pathname(); | 137 LOG(LS_INFO) << "Deleting file:" << filename.pathname(); |
137 | 138 |
138 if (!IsFile(filename)) { | 139 if (!IsFile(filename)) { |
139 ASSERT(IsFile(filename)); | 140 RTC_DCHECK(IsFile(filename)); |
140 return false; | 141 return false; |
141 } | 142 } |
142 return ::unlink(filename.pathname().c_str()) == 0; | 143 return ::unlink(filename.pathname().c_str()) == 0; |
143 } | 144 } |
144 | 145 |
145 bool UnixFilesystem::DeleteEmptyFolder(const Pathname &folder) { | 146 bool UnixFilesystem::DeleteEmptyFolder(const Pathname &folder) { |
146 LOG(LS_INFO) << "Deleting folder" << folder.pathname(); | 147 LOG(LS_INFO) << "Deleting folder" << folder.pathname(); |
147 | 148 |
148 if (!IsFolder(folder)) { | 149 if (!IsFolder(folder)) { |
149 ASSERT(IsFolder(folder)); | 150 RTC_DCHECK(IsFolder(folder)); |
150 return false; | 151 return false; |
151 } | 152 } |
152 std::string no_slash(folder.pathname(), 0, folder.pathname().length()-1); | 153 std::string no_slash(folder.pathname(), 0, folder.pathname().length()-1); |
153 return ::rmdir(no_slash.c_str()) == 0; | 154 return ::rmdir(no_slash.c_str()) == 0; |
154 } | 155 } |
155 | 156 |
156 bool UnixFilesystem::GetTemporaryFolder(Pathname &pathname, bool create, | 157 bool UnixFilesystem::GetTemporaryFolder(Pathname &pathname, bool create, |
157 const std::string *append) { | 158 const std::string *append) { |
158 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_MAC) | 159 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_MAC) |
159 ASSERT(provided_app_temp_folder_ != NULL); | 160 RTC_DCHECK(provided_app_temp_folder_ != NULL); |
160 pathname.SetPathname(provided_app_temp_folder_, ""); | 161 pathname.SetPathname(provided_app_temp_folder_, ""); |
161 #else | 162 #else |
162 if (const char* tmpdir = getenv("TMPDIR")) { | 163 if (const char* tmpdir = getenv("TMPDIR")) { |
163 pathname.SetPathname(tmpdir, ""); | 164 pathname.SetPathname(tmpdir, ""); |
164 } else if (const char* tmp = getenv("TMP")) { | 165 } else if (const char* tmp = getenv("TMP")) { |
165 pathname.SetPathname(tmp, ""); | 166 pathname.SetPathname(tmp, ""); |
166 } else { | 167 } else { |
167 #ifdef P_tmpdir | 168 #ifdef P_tmpdir |
168 pathname.SetPathname(P_tmpdir, ""); | 169 pathname.SetPathname(P_tmpdir, ""); |
169 #else // !P_tmpdir | 170 #else // !P_tmpdir |
170 pathname.SetPathname("/tmp/", ""); | 171 pathname.SetPathname("/tmp/", ""); |
171 #endif // !P_tmpdir | 172 #endif // !P_tmpdir |
172 } | 173 } |
173 #endif // defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) | 174 #endif // defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) |
174 if (append) { | 175 if (append) { |
175 ASSERT(!append->empty()); | 176 RTC_DCHECK(!append->empty()); |
176 pathname.AppendFolder(*append); | 177 pathname.AppendFolder(*append); |
177 } | 178 } |
178 return !create || CreateFolder(pathname); | 179 return !create || CreateFolder(pathname); |
179 } | 180 } |
180 | 181 |
181 std::string UnixFilesystem::TempFilename(const Pathname &dir, | 182 std::string UnixFilesystem::TempFilename(const Pathname &dir, |
182 const std::string &prefix) { | 183 const std::string &prefix) { |
183 int len = dir.pathname().size() + prefix.size() + 2 + 6; | 184 int len = dir.pathname().size() + prefix.size() + 2 + 6; |
184 char *tempname = new char[len]; | 185 char *tempname = new char[len]; |
185 | 186 |
186 snprintf(tempname, len, "%s/%sXXXXXX", dir.pathname().c_str(), | 187 snprintf(tempname, len, "%s/%sXXXXXX", dir.pathname().c_str(), |
187 prefix.c_str()); | 188 prefix.c_str()); |
188 int fd = ::mkstemp(tempname); | 189 int fd = ::mkstemp(tempname); |
189 if (fd != -1) | 190 if (fd != -1) |
190 ::close(fd); | 191 ::close(fd); |
191 std::string ret(tempname); | 192 std::string ret(tempname); |
192 delete[] tempname; | 193 delete[] tempname; |
193 | 194 |
194 return ret; | 195 return ret; |
195 } | 196 } |
196 | 197 |
197 bool UnixFilesystem::MoveFile(const Pathname &old_path, | 198 bool UnixFilesystem::MoveFile(const Pathname &old_path, |
198 const Pathname &new_path) { | 199 const Pathname &new_path) { |
199 if (!IsFile(old_path)) { | 200 if (!IsFile(old_path)) { |
200 ASSERT(IsFile(old_path)); | 201 RTC_DCHECK(IsFile(old_path)); |
201 return false; | 202 return false; |
202 } | 203 } |
203 LOG(LS_VERBOSE) << "Moving " << old_path.pathname() | 204 LOG(LS_VERBOSE) << "Moving " << old_path.pathname() |
204 << " to " << new_path.pathname(); | 205 << " to " << new_path.pathname(); |
205 if (rename(old_path.pathname().c_str(), new_path.pathname().c_str()) != 0) { | 206 if (rename(old_path.pathname().c_str(), new_path.pathname().c_str()) != 0) { |
206 if (errno != EXDEV) | 207 if (errno != EXDEV) |
207 return false; | 208 return false; |
208 if (!CopyFile(old_path, new_path)) | 209 if (!CopyFile(old_path, new_path)) |
209 return false; | 210 return false; |
210 if (!DeleteFile(old_path)) | 211 if (!DeleteFile(old_path)) |
(...skipping 29 matching lines...) Expand all Loading... |
240 while (source->Read(buf, sizeof(buf), &len, NULL) == SR_SUCCESS) | 241 while (source->Read(buf, sizeof(buf), &len, NULL) == SR_SUCCESS) |
241 dest->Write(buf, len, NULL, NULL); | 242 dest->Write(buf, len, NULL, NULL); |
242 | 243 |
243 delete source; | 244 delete source; |
244 delete dest; | 245 delete dest; |
245 return true; | 246 return true; |
246 } | 247 } |
247 | 248 |
248 bool UnixFilesystem::IsTemporaryPath(const Pathname& pathname) { | 249 bool UnixFilesystem::IsTemporaryPath(const Pathname& pathname) { |
249 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_MAC) | 250 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_MAC) |
250 ASSERT(provided_app_temp_folder_ != NULL); | 251 RTC_DCHECK(provided_app_temp_folder_ != NULL); |
251 #endif | 252 #endif |
252 | 253 |
253 const char* const kTempPrefixes[] = { | 254 const char* const kTempPrefixes[] = { |
254 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_MAC) | 255 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_MAC) |
255 provided_app_temp_folder_, | 256 provided_app_temp_folder_, |
256 #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) | 257 #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) |
257 "/private/tmp/", "/private/var/tmp/", "/private/var/folders/", | 258 "/private/tmp/", "/private/var/tmp/", "/private/var/folders/", |
258 #endif // WEBRTC_MAC && !defined(WEBRTC_IOS) | 259 #endif // WEBRTC_MAC && !defined(WEBRTC_IOS) |
259 #else | 260 #else |
260 "/tmp/", "/var/tmp/", | 261 "/tmp/", "/var/tmp/", |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 default: | 310 default: |
310 return false; | 311 return false; |
311 } | 312 } |
312 return true; | 313 return true; |
313 } | 314 } |
314 | 315 |
315 bool UnixFilesystem::GetAppDataFolder(Pathname* path, bool per_user) { | 316 bool UnixFilesystem::GetAppDataFolder(Pathname* path, bool per_user) { |
316 // On macOS and iOS, there is no requirement that the path contains the | 317 // On macOS and iOS, there is no requirement that the path contains the |
317 // organization. | 318 // organization. |
318 #if !defined(WEBRTC_MAC) | 319 #if !defined(WEBRTC_MAC) |
319 ASSERT(!organization_name_.empty()); | 320 RTC_DCHECK(!organization_name_.empty()); |
320 #endif | 321 #endif |
321 ASSERT(!application_name_.empty()); | 322 RTC_DCHECK(!application_name_.empty()); |
322 | 323 |
323 // First get the base directory for app data. | 324 // First get the base directory for app data. |
324 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_MAC) | 325 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_MAC) |
325 ASSERT(provided_app_data_folder_ != NULL); | 326 RTC_DCHECK(provided_app_data_folder_ != NULL); |
326 path->SetPathname(provided_app_data_folder_, ""); | 327 path->SetPathname(provided_app_data_folder_, ""); |
327 #elif defined(WEBRTC_LINUX) // && !WEBRTC_MAC && !WEBRTC_ANDROID | 328 #elif defined(WEBRTC_LINUX) // && !WEBRTC_MAC && !WEBRTC_ANDROID |
328 if (per_user) { | 329 if (per_user) { |
329 // We follow the recommendations in | 330 // We follow the recommendations in |
330 // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html | 331 // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html |
331 // It specifies separate directories for data and config files, but | 332 // It specifies separate directories for data and config files, but |
332 // GetAppDataFolder() does not distinguish. We just return the config dir | 333 // GetAppDataFolder() does not distinguish. We just return the config dir |
333 // path. | 334 // path. |
334 const char* xdg_config_home = getenv("XDG_CONFIG_HOME"); | 335 const char* xdg_config_home = getenv("XDG_CONFIG_HOME"); |
335 if (xdg_config_home) { | 336 if (xdg_config_home) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 if (0 != ::chmod(path->pathname().c_str(), 0700)) { | 383 if (0 != ::chmod(path->pathname().c_str(), 0700)) { |
383 LOG_ERR(LS_ERROR) << "Can't set mode on " << path; | 384 LOG_ERR(LS_ERROR) << "Can't set mode on " << path; |
384 return false; | 385 return false; |
385 } | 386 } |
386 #endif | 387 #endif |
387 return true; | 388 return true; |
388 } | 389 } |
389 | 390 |
390 bool UnixFilesystem::GetAppTempFolder(Pathname* path) { | 391 bool UnixFilesystem::GetAppTempFolder(Pathname* path) { |
391 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_MAC) | 392 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_MAC) |
392 ASSERT(provided_app_temp_folder_ != NULL); | 393 RTC_DCHECK(provided_app_temp_folder_ != NULL); |
393 path->SetPathname(provided_app_temp_folder_); | 394 path->SetPathname(provided_app_temp_folder_); |
394 return true; | 395 return true; |
395 #else | 396 #else |
396 ASSERT(!application_name_.empty()); | 397 RTC_DCHECK(!application_name_.empty()); |
397 // TODO: Consider whether we are worried about thread safety. | 398 // TODO: Consider whether we are worried about thread safety. |
398 if (app_temp_path_ != NULL && strlen(app_temp_path_) > 0) { | 399 if (app_temp_path_ != NULL && strlen(app_temp_path_) > 0) { |
399 path->SetPathname(app_temp_path_); | 400 path->SetPathname(app_temp_path_); |
400 return true; | 401 return true; |
401 } | 402 } |
402 | 403 |
403 // Create a random directory as /tmp/<appname>-<pid>-<timestamp> | 404 // Create a random directory as /tmp/<appname>-<pid>-<timestamp> |
404 char buffer[128]; | 405 char buffer[128]; |
405 sprintfn(buffer, arraysize(buffer), "-%d-%d", | 406 sprintfn(buffer, arraysize(buffer), "-%d-%d", |
406 static_cast<int>(getpid()), | 407 static_cast<int>(getpid()), |
407 static_cast<int>(time(0))); | 408 static_cast<int>(time(0))); |
408 std::string folder(application_name_); | 409 std::string folder(application_name_); |
409 folder.append(buffer); | 410 folder.append(buffer); |
410 if (!GetTemporaryFolder(*path, true, &folder)) | 411 if (!GetTemporaryFolder(*path, true, &folder)) |
411 return false; | 412 return false; |
412 | 413 |
413 delete [] app_temp_path_; | 414 delete [] app_temp_path_; |
414 app_temp_path_ = CopyString(path->pathname()); | 415 app_temp_path_ = CopyString(path->pathname()); |
415 // TODO: atexit(DeleteFolderAndContents(app_temp_path_)); | 416 // TODO: atexit(DeleteFolderAndContents(app_temp_path_)); |
416 return true; | 417 return true; |
417 #endif | 418 #endif |
418 } | 419 } |
419 | 420 |
420 bool UnixFilesystem::GetDiskFreeSpace(const Pathname& path, | 421 bool UnixFilesystem::GetDiskFreeSpace(const Pathname& path, |
421 int64_t* freebytes) { | 422 int64_t* freebytes) { |
422 #ifdef __native_client__ | 423 #ifdef __native_client__ |
423 return false; | 424 return false; |
424 #else // __native_client__ | 425 #else // __native_client__ |
425 ASSERT(NULL != freebytes); | 426 RTC_DCHECK(NULL != freebytes); |
426 // TODO: Consider making relative paths absolute using cwd. | 427 // TODO: Consider making relative paths absolute using cwd. |
427 // TODO: When popping off a symlink, push back on the components of the | 428 // TODO: When popping off a symlink, push back on the components of the |
428 // symlink, so we don't jump out of the target disk inadvertently. | 429 // symlink, so we don't jump out of the target disk inadvertently. |
429 Pathname existing_path(path.folder(), ""); | 430 Pathname existing_path(path.folder(), ""); |
430 while (!existing_path.folder().empty() && IsAbsent(existing_path)) { | 431 while (!existing_path.folder().empty() && IsAbsent(existing_path)) { |
431 existing_path.SetFolder(existing_path.parent_folder()); | 432 existing_path.SetFolder(existing_path.parent_folder()); |
432 } | 433 } |
433 #if defined(WEBRTC_ANDROID) | 434 #if defined(WEBRTC_ANDROID) |
434 struct statfs vfs; | 435 struct statfs vfs; |
435 memset(&vfs, 0, sizeof(vfs)); | 436 memset(&vfs, 0, sizeof(vfs)); |
(...skipping 29 matching lines...) Expand all Loading... |
465 | 466 |
466 } // namespace rtc | 467 } // namespace rtc |
467 | 468 |
468 #if defined(__native_client__) | 469 #if defined(__native_client__) |
469 extern "C" int __attribute__((weak)) | 470 extern "C" int __attribute__((weak)) |
470 link(const char* oldpath, const char* newpath) { | 471 link(const char* oldpath, const char* newpath) { |
471 errno = EACCES; | 472 errno = EACCES; |
472 return -1; | 473 return -1; |
473 } | 474 } |
474 #endif | 475 #endif |
OLD | NEW |