Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/file_util.h" | 5 #include "base/file_util.h" |
| 6 | 6 |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <fnmatch.h> | 8 #include <fnmatch.h> |
| 9 #include <fts.h> | 9 #include <fts.h> |
| 10 #include <libgen.h> | 10 #include <libgen.h> |
| 11 #include <sys/errno.h> | 11 #include <sys/errno.h> |
| 12 #include <sys/stat.h> | 12 #include <sys/stat.h> |
| 13 #include <time.h> | 13 #include <time.h> |
| 14 | 14 |
| 15 #include <fstream> | 15 #include <fstream> |
| 16 | 16 |
| 17 #include "base/basictypes.h" | 17 #include "base/basictypes.h" |
| 18 #include "base/logging.h" | 18 #include "base/logging.h" |
| 19 #include "base/string_util.h" | 19 #include "base/string_util.h" |
| 20 | 20 |
| 21 namespace file_util { | 21 namespace file_util { |
| 22 | 22 |
| 23 static const wchar_t* kTempFileName = L"com.google.chrome.XXXXXX"; | |
|
Dean McNamee
2008/09/12 13:59:46
Seems a waste to make this wide, just when we're g
| |
| 24 | |
| 23 std::wstring GetDirectoryFromPath(const std::wstring& path) { | 25 std::wstring GetDirectoryFromPath(const std::wstring& path) { |
| 24 if (EndsWithSeparator(path)) { | 26 if (EndsWithSeparator(path)) { |
| 25 std::wstring dir = path; | 27 std::wstring dir = path; |
| 26 TrimTrailingSeparator(&dir); | 28 TrimTrailingSeparator(&dir); |
| 27 return dir; | 29 return dir; |
| 28 } else { | 30 } else { |
| 29 char full_path[PATH_MAX]; | 31 char full_path[PATH_MAX]; |
| 30 base::strlcpy(full_path, WideToUTF8(path).c_str(), arraysize(full_path)); | 32 base::strlcpy(full_path, WideToUTF8(path).c_str(), arraysize(full_path)); |
| 31 return UTF8ToWide(dirname(full_path)); | 33 return UTF8ToWide(dirname(full_path)); |
| 32 } | 34 } |
| 33 } | 35 } |
| 34 | 36 |
| 35 bool AbsolutePath(std::wstring* path) { | 37 bool AbsolutePath(std::wstring* path) { |
| 36 char full_path[PATH_MAX]; | 38 char full_path[PATH_MAX]; |
| 37 if (realpath(WideToUTF8(*path).c_str(), full_path) == NULL) | 39 if (realpath(WideToUTF8(*path).c_str(), full_path) == NULL) |
| 38 return false; | 40 return false; |
| 39 *path = UTF8ToWide(full_path); | 41 *path = UTF8ToWide(full_path); |
| 40 return true; | 42 return true; |
| 41 } | 43 } |
| 42 | 44 |
| 43 // TODO(erikkay): The Windows version of this accepts paths like "foo/bar/*" | 45 // TODO(erikkay): The Windows version of this accepts paths like "foo/bar/*" |
| 44 // which works both with and without the recursive flag. I'm not sure we need | 46 // which works both with and without the recursive flag. I'm not sure we need |
| 45 // that functionality. If not, remove from file_util_win.cc, otherwise add it | 47 // that functionality. If not, remove from file_util_win.cc, otherwise add it |
| 46 // here. | 48 // here. |
| 47 bool Delete(const std::wstring& path, bool recursive) { | 49 bool Delete(const std::wstring& path, bool recursive) { |
| 48 const char* utf8_path = WideToUTF8(path).c_str(); | 50 std::string utf8_path_string = WideToUTF8(path); |
| 51 const char* utf8_path = utf8_path_string.c_str(); | |
| 49 struct stat64 file_info; | 52 struct stat64 file_info; |
| 50 int test = stat64(utf8_path, &file_info); | 53 int test = stat64(utf8_path, &file_info); |
| 51 if (test != 0) { | 54 if (test != 0) { |
| 52 // The Windows version defines this condition as success. | 55 // The Windows version defines this condition as success. |
| 53 bool ret = (errno == ENOENT || errno == ENOTDIR); | 56 bool ret = (errno == ENOENT || errno == ENOTDIR); |
| 54 return ret; | 57 return ret; |
| 55 } | 58 } |
| 56 if (!S_ISDIR(file_info.st_mode)) | 59 if (!S_ISDIR(file_info.st_mode)) |
| 57 return (unlink(utf8_path) == 0); | 60 return (unlink(utf8_path) == 0); |
| 58 if (!recursive) | 61 if (!recursive) |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 136 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, | 139 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, |
| 137 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)); | 140 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)); |
| 138 return GetFileCreationLocalTimeFromHandle(file_handle.Get(), creation_time); | 141 return GetFileCreationLocalTimeFromHandle(file_handle.Get(), creation_time); |
| 139 } | 142 } |
| 140 #endif | 143 #endif |
| 141 | 144 |
| 142 bool CreateTemporaryFileName(std::wstring* temp_file) { | 145 bool CreateTemporaryFileName(std::wstring* temp_file) { |
| 143 std::wstring tmpdir; | 146 std::wstring tmpdir; |
| 144 if (!GetTempDir(&tmpdir)) | 147 if (!GetTempDir(&tmpdir)) |
| 145 return false; | 148 return false; |
| 146 tmpdir.append(L"com.google.chrome.XXXXXX"); | 149 AppendToPath(&tmpdir, kTempFileName); |
| 147 // this should be OK since mktemp just replaces characters in place | 150 std::string tmpdir_string = WideToUTF8(tmpdir); |
| 148 char* buffer = const_cast<char*>(WideToUTF8(tmpdir).c_str()); | 151 // this should be OK since mkstemp just replaces characters in place |
| 149 *temp_file = UTF8ToWide(mktemp(buffer)); | 152 char* buffer = const_cast<char*>(tmpdir_string.c_str()); |
| 150 int fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, 0666); | 153 int fd = mkstemp(buffer); |
| 151 if (fd < 0) | 154 if (fd < 0) |
| 152 return false; | 155 return false; |
| 153 close(fd); | 156 *temp_file = UTF8ToWide(buffer); |
| 157 close(fd); | |
| 154 return true; | 158 return true; |
| 155 } | 159 } |
| 156 | 160 |
| 157 bool CreateNewTempDirectory(const std::wstring& prefix, | 161 bool CreateNewTempDirectory(const std::wstring& prefix, |
| 158 std::wstring* new_temp_path) { | 162 std::wstring* new_temp_path) { |
| 159 std::wstring tmpdir; | 163 std::wstring tmpdir; |
| 160 if (!GetTempDir(&tmpdir)) | 164 if (!GetTempDir(&tmpdir)) |
| 161 return false; | 165 return false; |
| 162 tmpdir.append(L"/com.google.chrome.XXXXXX"); | 166 AppendToPath(&tmpdir, kTempFileName); |
| 167 std::string tmpdir_string = WideToUTF8(tmpdir); | |
| 163 // this should be OK since mkdtemp just replaces characters in place | 168 // this should be OK since mkdtemp just replaces characters in place |
| 164 char* buffer = const_cast<char*>(WideToUTF8(tmpdir).c_str()); | 169 char* buffer = const_cast<char*>(tmpdir_string.c_str()); |
| 165 char* dtemp = mkdtemp(buffer); | 170 char* dtemp = mkdtemp(buffer); |
| 166 if (!dtemp) | 171 if (!dtemp) |
| 167 return false; | 172 return false; |
| 168 *new_temp_path = UTF8ToWide(dtemp); | 173 *new_temp_path = UTF8ToWide(dtemp); |
| 169 return true; | 174 return true; |
| 170 } | 175 } |
| 171 | 176 |
| 172 bool CreateDirectory(const std::wstring& full_path) { | 177 bool CreateDirectory(const std::wstring& full_path) { |
| 173 std::vector<std::wstring> components; | 178 std::vector<std::wstring> components; |
| 174 PathComponents(full_path, &components); | 179 PathComponents(full_path, &components); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 199 int fd = open(WideToUTF8(filename).c_str(), O_RDONLY); | 204 int fd = open(WideToUTF8(filename).c_str(), O_RDONLY); |
| 200 if (fd < 0) | 205 if (fd < 0) |
| 201 return -1; | 206 return -1; |
| 202 | 207 |
| 203 int ret_value = read(fd, data, size); | 208 int ret_value = read(fd, data, size); |
| 204 close(fd); | 209 close(fd); |
| 205 return ret_value; | 210 return ret_value; |
| 206 } | 211 } |
| 207 | 212 |
| 208 int WriteFile(const std::wstring& filename, const char* data, int size) { | 213 int WriteFile(const std::wstring& filename, const char* data, int size) { |
| 209 int fd = open(WideToUTF8(filename).c_str(), O_WRONLY | O_CREAT | O_TRUNC, | 214 int fd = creat(WideToUTF8(filename).c_str(), 0666); |
| 210 0666); | |
| 211 if (fd < 0) | 215 if (fd < 0) |
| 212 return -1; | 216 return -1; |
| 213 | 217 |
| 214 int ret_value = write(fd, data, size); | 218 // Allow for partial writes |
| 219 ssize_t bytes_written_total = 0; | |
| 220 do { | |
| 221 ssize_t bytes_written_partial = write(fd, | |
| 222 data + bytes_written_total, | |
| 223 size - bytes_written_total); | |
| 224 if (bytes_written_partial < 0) { | |
| 225 close(fd); | |
| 226 return -1; | |
| 227 } | |
| 228 bytes_written_total += bytes_written_partial; | |
| 229 } while (bytes_written_total < size); | |
| 230 | |
| 215 close(fd); | 231 close(fd); |
| 216 return ret_value; | 232 return bytes_written_total; |
| 217 } | 233 } |
| 218 | 234 |
| 219 // Gets the current working directory for the process. | 235 // Gets the current working directory for the process. |
| 220 bool GetCurrentDirectory(std::wstring* dir) { | 236 bool GetCurrentDirectory(std::wstring* dir) { |
| 221 char system_buffer[PATH_MAX] = ""; | 237 char system_buffer[PATH_MAX] = ""; |
| 222 getcwd(system_buffer, sizeof(system_buffer)); | 238 getcwd(system_buffer, sizeof(system_buffer)); |
| 223 *dir = UTF8ToWide(system_buffer); | 239 *dir = UTF8ToWide(system_buffer); |
| 224 return true; | 240 return true; |
| 225 } | 241 } |
| 226 | 242 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 294 return Next(); | 310 return Next(); |
| 295 } | 311 } |
| 296 | 312 |
| 297 // Level 0 is the top, which is always skipped. | 313 // Level 0 is the top, which is always skipped. |
| 298 if (fts_ent->fts_level == 0) | 314 if (fts_ent->fts_level == 0) |
| 299 return Next(); | 315 return Next(); |
| 300 | 316 |
| 301 // Patterns are only matched on the items in the top-most directory. | 317 // Patterns are only matched on the items in the top-most directory. |
| 302 // (see Windows implementation) | 318 // (see Windows implementation) |
| 303 if (fts_ent->fts_level == 1 && pattern_.length() > 0) { | 319 if (fts_ent->fts_level == 1 && pattern_.length() > 0) { |
| 304 const char* utf8_pattern = WideToUTF8(pattern_).c_str(); | 320 if (fnmatch(WideToUTF8(pattern_).c_str(), fts_ent->fts_path, 0) != 0) { |
| 305 if (fnmatch(utf8_pattern, fts_ent->fts_path, 0) != 0) { | |
| 306 if (fts_ent->fts_info == FTS_D) | 321 if (fts_ent->fts_info == FTS_D) |
| 307 fts_set(fts_, fts_ent, FTS_SKIP); | 322 fts_set(fts_, fts_ent, FTS_SKIP); |
| 308 return Next(); | 323 return Next(); |
| 309 } | 324 } |
| 310 } | 325 } |
| 311 | 326 |
| 312 std::wstring cur_file(UTF8ToWide(fts_ent->fts_path)); | 327 std::wstring cur_file(UTF8ToWide(fts_ent->fts_path)); |
| 313 if (fts_ent->fts_info == FTS_D) { | 328 if (fts_ent->fts_info == FTS_D) { |
| 314 // If not recursive, then prune children. | 329 // If not recursive, then prune children. |
| 315 if (!recursive_) | 330 if (!recursive_) |
| 316 fts_set(fts_, fts_ent, FTS_SKIP); | 331 fts_set(fts_, fts_ent, FTS_SKIP); |
| 317 return (file_type_ & FileEnumerator::DIRECTORIES) ? cur_file : Next(); | 332 return (file_type_ & FileEnumerator::DIRECTORIES) ? cur_file : Next(); |
| 318 } else if (fts_ent->fts_info == FTS_F) { | 333 } else if (fts_ent->fts_info == FTS_F) { |
| 319 return (file_type_ & FileEnumerator::FILES) ? cur_file : Next(); | 334 return (file_type_ & FileEnumerator::FILES) ? cur_file : Next(); |
| 320 } | 335 } |
| 321 // TODO(erikkay) - verify that the other fts_info types aren't interesting | 336 // TODO(erikkay) - verify that the other fts_info types aren't interesting |
| 322 return Next(); | 337 return Next(); |
| 323 } | 338 } |
| 324 | 339 |
| 325 | 340 |
| 326 } // namespace file_util | 341 } // namespace file_util |
| 327 | 342 |
| 328 | 343 |
| OLD | NEW |