Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: base/file_util_posix.cc

Issue 8825: Begin the first small step towards using FilePath everywhere: (Closed)
Patch Set: works on windows Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/file_util_mac.mm ('k') | base/file_util_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <fnmatch.h> 9 #include <fnmatch.h>
10 #include <fts.h> 10 #include <fts.h>
11 #include <libgen.h> 11 #include <libgen.h>
12 #include <stdio.h> 12 #include <stdio.h>
13 #include <string.h> 13 #include <string.h>
14 #include <sys/errno.h> 14 #include <sys/errno.h>
15 #include <sys/stat.h> 15 #include <sys/stat.h>
16 #include <time.h> 16 #include <time.h>
17 17
18 #include <fstream> 18 #include <fstream>
19 19
20 #include "base/basictypes.h" 20 #include "base/basictypes.h"
21 #include "base/file_path.h"
21 #include "base/logging.h" 22 #include "base/logging.h"
22 #include "base/string_util.h" 23 #include "base/string_util.h"
23 24
24 namespace file_util { 25 namespace file_util {
25 26
26 static const wchar_t* kTempFileName = L"com.google.chrome.XXXXXX"; 27 static const wchar_t* kTempFileName = L"com.google.chrome.XXXXXX";
27 28
28 std::wstring GetDirectoryFromPath(const std::wstring& path) { 29 std::wstring GetDirectoryFromPath(const std::wstring& path) {
29 if (EndsWithSeparator(path)) { 30 if (EndsWithSeparator(path)) {
30 std::wstring dir = path; 31 std::wstring dir = path;
31 TrimTrailingSeparator(&dir); 32 TrimTrailingSeparator(&dir);
32 return dir; 33 return dir;
33 } else { 34 } else {
34 char full_path[PATH_MAX]; 35 char full_path[PATH_MAX];
35 base::strlcpy(full_path, WideToUTF8(path).c_str(), arraysize(full_path)); 36 base::strlcpy(full_path, WideToUTF8(path).c_str(), arraysize(full_path));
36 return UTF8ToWide(dirname(full_path)); 37 return UTF8ToWide(dirname(full_path));
37 } 38 }
38 } 39 }
39 40
40 bool AbsolutePath(std::wstring* path) { 41 bool AbsolutePath(FilePath* path) {
41 char full_path[PATH_MAX]; 42 char full_path[PATH_MAX];
42 if (realpath(WideToUTF8(*path).c_str(), full_path) == NULL) 43 if (realpath(path->value().c_str(), full_path) == NULL)
43 return false; 44 return false;
44 *path = UTF8ToWide(full_path); 45 *path = FilePath(full_path);
45 return true; 46 return true;
46 } 47 }
47 48
48 // TODO(erikkay): The Windows version of this accepts paths like "foo/bar/*" 49 // TODO(erikkay): The Windows version of this accepts paths like "foo/bar/*"
49 // which works both with and without the recursive flag. I'm not sure we need 50 // which works both with and without the recursive flag. I'm not sure we need
50 // that functionality. If not, remove from file_util_win.cc, otherwise add it 51 // that functionality. If not, remove from file_util_win.cc, otherwise add it
51 // here. 52 // here.
52 bool Delete(const std::wstring& path, bool recursive) { 53 bool Delete(const FilePath& path, bool recursive) {
53 std::string utf8_path_string = WideToUTF8(path); 54 const char* path_str = path.value().c_str();
54 const char* utf8_path = utf8_path_string.c_str();
55 struct stat64 file_info; 55 struct stat64 file_info;
56 int test = stat64(utf8_path, &file_info); 56 int test = stat64(path_str, &file_info);
57 if (test != 0) { 57 if (test != 0) {
58 // The Windows version defines this condition as success. 58 // The Windows version defines this condition as success.
59 bool ret = (errno == ENOENT || errno == ENOTDIR); 59 bool ret = (errno == ENOENT || errno == ENOTDIR);
60 return ret; 60 return ret;
61 } 61 }
62 if (!S_ISDIR(file_info.st_mode)) 62 if (!S_ISDIR(file_info.st_mode))
63 return (unlink(utf8_path) == 0); 63 return (unlink(path_str) == 0);
64 if (!recursive) 64 if (!recursive)
65 return (rmdir(utf8_path) == 0); 65 return (rmdir(path_str) == 0);
66 66
67 bool success = true; 67 bool success = true;
68 int ftsflags = FTS_PHYSICAL | FTS_NOSTAT; 68 int ftsflags = FTS_PHYSICAL | FTS_NOSTAT;
69 char top_dir[PATH_MAX]; 69 char top_dir[PATH_MAX];
70 if (base::strlcpy(top_dir, utf8_path, 70 if (base::strlcpy(top_dir, path_str,
71 arraysize(top_dir)) >= arraysize(top_dir)) { 71 arraysize(top_dir)) >= arraysize(top_dir)) {
72 return false; 72 return false;
73 } 73 }
74 char* dir_list[2] = { top_dir, NULL }; 74 char* dir_list[2] = { top_dir, NULL };
75 FTS* fts = fts_open(dir_list, ftsflags, NULL); 75 FTS* fts = fts_open(dir_list, ftsflags, NULL);
76 if (fts) { 76 if (fts) {
77 FTSENT* fts_ent = fts_read(fts); 77 FTSENT* fts_ent = fts_read(fts);
78 while (success && fts_ent != NULL) { 78 while (success && fts_ent != NULL) {
79 switch (fts_ent->fts_info) { 79 switch (fts_ent->fts_info) {
80 case FTS_DNR: 80 case FTS_DNR:
(...skipping 17 matching lines...) Expand all
98 DCHECK(false); 98 DCHECK(false);
99 break; 99 break;
100 } 100 }
101 fts_ent = fts_read(fts); 101 fts_ent = fts_read(fts);
102 } 102 }
103 fts_close(fts); 103 fts_close(fts);
104 } 104 }
105 return success; 105 return success;
106 } 106 }
107 107
108 bool Move(const std::wstring& from_path, const std::wstring& to_path) { 108 bool Move(const FilePath& from_path, const FilePath& to_path) {
109 return (rename(WideToUTF8(from_path).c_str(), 109 return (rename(from_path.value().c_str(),
110 WideToUTF8(to_path).c_str()) == 0); 110 to_path.value().c_str()) == 0);
111 } 111 }
112 112
113 bool CopyDirectory(const std::wstring& from_path_wide, 113 bool CopyDirectory(const FilePath& from_path,
114 const std::wstring& to_path_wide, 114 const FilePath& to_path,
115 bool recursive) { 115 bool recursive) {
116 const std::string to_path = WideToUTF8(to_path_wide);
117 const std::string from_path = WideToUTF8(from_path_wide);
118
119 // Some old callers of CopyDirectory want it to support wildcards. 116 // Some old callers of CopyDirectory want it to support wildcards.
120 // After some discussion, we decided to fix those callers. 117 // After some discussion, we decided to fix those callers.
121 // Break loudly here if anyone tries to do this. 118 // Break loudly here if anyone tries to do this.
122 // TODO(evanm): remove this once we're sure it's ok. 119 // TODO(evanm): remove this once we're sure it's ok.
123 DCHECK(to_path.find('*') == std::string::npos); 120 DCHECK(to_path.value().find('*') == std::string::npos);
124 DCHECK(from_path.find('*') == std::string::npos); 121 DCHECK(from_path.value().find('*') == std::string::npos);
125 122
126 char top_dir[PATH_MAX]; 123 char top_dir[PATH_MAX];
127 if (base::strlcpy(top_dir, from_path.c_str(), 124 if (base::strlcpy(top_dir, from_path.value().c_str(),
128 arraysize(top_dir)) >= arraysize(top_dir)) { 125 arraysize(top_dir)) >= arraysize(top_dir)) {
129 return false; 126 return false;
130 } 127 }
131 128
132 char* dir_list[] = { top_dir, NULL }; 129 char* dir_list[] = { top_dir, NULL };
133 FTS* fts = fts_open(dir_list, FTS_PHYSICAL | FTS_NOSTAT, NULL); 130 FTS* fts = fts_open(dir_list, FTS_PHYSICAL | FTS_NOSTAT, NULL);
134 if (!fts) { 131 if (!fts) {
135 LOG(ERROR) << "fts_open failed: " << strerror(errno); 132 LOG(ERROR) << "fts_open failed: " << strerror(errno);
136 return false; 133 return false;
137 } 134 }
138 135
139 int error = 0; 136 int error = 0;
140 FTSENT* ent; 137 FTSENT* ent;
141 while (!error && (ent = fts_read(fts)) != NULL) { 138 while (!error && (ent = fts_read(fts)) != NULL) {
142 // ent->fts_path is the source path, including from_path, so paste 139 // ent->fts_path is the source path, including from_path, so paste
143 // the suffix after from_path onto to_path to create the target_path. 140 // the suffix after from_path onto to_path to create the target_path.
144 const std::string target_path = to_path + &ent->fts_path[from_path.size()]; 141 const std::string target_path =
142 to_path.value() + &ent->fts_path[from_path.value().size()];
145 switch (ent->fts_info) { 143 switch (ent->fts_info) {
146 case FTS_D: // Preorder directory. 144 case FTS_D: // Preorder directory.
147 // If we encounter a subdirectory in a non-recursive copy, prune it 145 // If we encounter a subdirectory in a non-recursive copy, prune it
148 // from the traversal. 146 // from the traversal.
149 if (!recursive && ent->fts_level > 0) { 147 if (!recursive && ent->fts_level > 0) {
150 if (fts_set(fts, ent, FTS_SKIP) != 0) 148 if (fts_set(fts, ent, FTS_SKIP) != 0)
151 error = errno; 149 error = errno;
152 continue; 150 continue;
153 } 151 }
154 152
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 error = errno; 202 error = errno;
205 } 203 }
206 204
207 if (error) { 205 if (error) {
208 LOG(ERROR) << "CopyDirectory(): " << strerror(error); 206 LOG(ERROR) << "CopyDirectory(): " << strerror(error);
209 return false; 207 return false;
210 } 208 }
211 return true; 209 return true;
212 } 210 }
213 211
214 bool PathExists(const std::wstring& path) { 212 bool PathExists(const FilePath& path) {
215 struct stat64 file_info; 213 struct stat64 file_info;
216 return (stat64(WideToUTF8(path).c_str(), &file_info) == 0); 214 return (stat64(path.value().c_str(), &file_info) == 0);
217 } 215 }
218 216
219 bool DirectoryExists(const std::wstring& path) { 217 bool DirectoryExists(const FilePath& path) {
220 struct stat64 file_info; 218 struct stat64 file_info;
221 if (stat64(WideToUTF8(path).c_str(), &file_info) == 0) 219 if (stat64(path.value().c_str(), &file_info) == 0)
222 return S_ISDIR(file_info.st_mode); 220 return S_ISDIR(file_info.st_mode);
223 return false; 221 return false;
224 } 222 }
225 223
226 // TODO(erikkay): implement 224 // TODO(erikkay): implement
227 #if 0 225 #if 0
228 bool GetFileCreationLocalTimeFromHandle(int fd, 226 bool GetFileCreationLocalTimeFromHandle(int fd,
229 LPSYSTEMTIME creation_time) { 227 LPSYSTEMTIME creation_time) {
230 if (!file_handle) 228 if (!file_handle)
231 return false; 229 return false;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 std::string tmpdir_string = WideToUTF8(tmpdir); 281 std::string tmpdir_string = WideToUTF8(tmpdir);
284 // this should be OK since mkdtemp just replaces characters in place 282 // this should be OK since mkdtemp just replaces characters in place
285 char* buffer = const_cast<char*>(tmpdir_string.c_str()); 283 char* buffer = const_cast<char*>(tmpdir_string.c_str());
286 char* dtemp = mkdtemp(buffer); 284 char* dtemp = mkdtemp(buffer);
287 if (!dtemp) 285 if (!dtemp)
288 return false; 286 return false;
289 *new_temp_path = UTF8ToWide(dtemp); 287 *new_temp_path = UTF8ToWide(dtemp);
290 return true; 288 return true;
291 } 289 }
292 290
293 bool CreateDirectory(const std::wstring& full_path) { 291 bool CreateDirectory(const FilePath& full_path) {
294 std::vector<std::wstring> components; 292 std::vector<FilePath> subpaths;
295 PathComponents(full_path, &components); 293
296 std::wstring path; 294 // Collect a list of all parent directories.
297 std::vector<std::wstring>::iterator i = components.begin(); 295 FilePath last_path = full_path;
298 for (; i != components.end(); ++i) { 296 subpaths.push_back(full_path);
299 if (path.length() == 0) 297 for (FilePath path = full_path.DirName();
300 path = *i; 298 path.value() != last_path.value(); path = path.DirName()) {
301 else 299 subpaths.push_back(path);
302 AppendToPath(&path, *i); 300 last_path = path;
303 if (!DirectoryExists(path)) { 301 }
304 if (mkdir(WideToUTF8(path).c_str(), 0777) != 0) 302
303 // Iterate through the parents and create the missing ones.
304 for (std::vector<FilePath>::reverse_iterator i = subpaths.rbegin();
305 i != subpaths.rend(); ++i) {
306 if (!DirectoryExists(*i)) {
307 if (mkdir(i->value().c_str(), 0777) != 0)
305 return false; 308 return false;
306 } 309 }
307 } 310 }
308 return true; 311 return true;
309 } 312 }
310 313
311 bool GetFileInfo(const std::wstring& file_path, FileInfo* results) { 314 bool GetFileInfo(const std::wstring& file_path, FileInfo* results) {
312 struct stat64 file_info; 315 struct stat64 file_info;
313 if (stat64(WideToUTF8(file_path).c_str(), &file_info) != 0) 316 if (stat64(WideToUTF8(file_path).c_str(), &file_info) != 0)
314 return false; 317 return false;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 return -1; 354 return -1;
352 } 355 }
353 bytes_written_total += bytes_written_partial; 356 bytes_written_total += bytes_written_partial;
354 } while (bytes_written_total < size); 357 } while (bytes_written_total < size);
355 358
356 close(fd); 359 close(fd);
357 return bytes_written_total; 360 return bytes_written_total;
358 } 361 }
359 362
360 // Gets the current working directory for the process. 363 // Gets the current working directory for the process.
361 bool GetCurrentDirectory(std::wstring* dir) { 364 bool GetCurrentDirectory(FilePath* dir) {
362 char system_buffer[PATH_MAX] = ""; 365 char system_buffer[PATH_MAX] = "";
363 getcwd(system_buffer, sizeof(system_buffer)); 366 if (!getcwd(system_buffer, sizeof(system_buffer))) {
364 *dir = UTF8ToWide(system_buffer); 367 NOTREACHED();
368 return false;
369 }
370 *dir = FilePath(system_buffer);
365 return true; 371 return true;
366 } 372 }
367 373
368 // Sets the current working directory for the process. 374 // Sets the current working directory for the process.
369 bool SetCurrentDirectory(const std::wstring& current_directory) { 375 bool SetCurrentDirectory(const std::wstring& current_directory) {
370 int ret = chdir(WideToUTF8(current_directory).c_str()); 376 int ret = chdir(WideToUTF8(current_directory).c_str());
371 return (ret == 0); 377 return (ret == 0);
372 } 378 }
373 379
374 FileEnumerator::FileEnumerator(const std::wstring& root_path, 380 FileEnumerator::FileEnumerator(const std::wstring& root_path,
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 return (file_type_ & FileEnumerator::DIRECTORIES) ? cur_file : Next(); 463 return (file_type_ & FileEnumerator::DIRECTORIES) ? cur_file : Next();
458 } else if (fts_ent->fts_info == FTS_F) { 464 } else if (fts_ent->fts_info == FTS_F) {
459 return (file_type_ & FileEnumerator::FILES) ? cur_file : Next(); 465 return (file_type_ & FileEnumerator::FILES) ? cur_file : Next();
460 } 466 }
461 // TODO(erikkay) - verify that the other fts_info types aren't interesting 467 // TODO(erikkay) - verify that the other fts_info types aren't interesting
462 return Next(); 468 return Next();
463 } 469 }
464 470
465 471
466 } // namespace file_util 472 } // namespace file_util
OLDNEW
« no previous file with comments | « base/file_util_mac.mm ('k') | base/file_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698