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

Side by Side Diff: base/file_util_posix.cc

Issue 18332014: Move Copy* into the base namespace. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: windows Created 7 years, 5 months 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 | Annotate | Revision Log
« 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <dirent.h> 7 #include <dirent.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <fcntl.h> 9 #include <fcntl.h>
10 #include <libgen.h> 10 #include <libgen.h>
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 } 190 }
191 191
192 while (success && !directories.empty()) { 192 while (success && !directories.empty()) {
193 FilePath dir = FilePath(directories.top()); 193 FilePath dir = FilePath(directories.top());
194 directories.pop(); 194 directories.pop();
195 success = (rmdir(dir.value().c_str()) == 0); 195 success = (rmdir(dir.value().c_str()) == 0);
196 } 196 }
197 return success; 197 return success;
198 } 198 }
199 199
200 bool MoveUnsafe(const FilePath& from_path, const FilePath& to_path) {
201 ThreadRestrictions::AssertIOAllowed();
202 // Windows compatibility: if to_path exists, from_path and to_path
203 // must be the same type, either both files, or both directories.
204 stat_wrapper_t to_file_info;
205 if (CallStat(to_path.value().c_str(), &to_file_info) == 0) {
206 stat_wrapper_t from_file_info;
207 if (CallStat(from_path.value().c_str(), &from_file_info) == 0) {
208 if (S_ISDIR(to_file_info.st_mode) != S_ISDIR(from_file_info.st_mode))
209 return false;
210 } else {
211 return false;
212 }
213 }
214
215 if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0)
216 return true;
217
218 if (!file_util::CopyDirectory(from_path, to_path, true))
219 return false;
220
221 Delete(from_path, true);
222 return true;
223 }
224
225 bool ReplaceFile(const FilePath& from_path, 200 bool ReplaceFile(const FilePath& from_path,
226 const FilePath& to_path, 201 const FilePath& to_path,
227 PlatformFileError* error) { 202 PlatformFileError* error) {
228 ThreadRestrictions::AssertIOAllowed(); 203 ThreadRestrictions::AssertIOAllowed();
229 if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0) 204 if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0)
230 return true; 205 return true;
231 if (error) 206 if (error)
232 *error = ErrnoToPlatformFileError(errno); 207 *error = ErrnoToPlatformFileError(errno);
233 return false; 208 return false;
234 } 209 }
235 210
236 } // namespace base
237
238 // -----------------------------------------------------------------------------
239
240 namespace file_util {
241
242 using base::stat_wrapper_t;
243 using base::CallStat;
244 using base::CallLstat;
245 using base::FileEnumerator;
246 using base::FilePath;
247 using base::MakeAbsoluteFilePath;
248 using base::RealPath;
249 using base::VerifySpecificPathControlledByUser;
250
251 bool CopyDirectory(const FilePath& from_path, 211 bool CopyDirectory(const FilePath& from_path,
252 const FilePath& to_path, 212 const FilePath& to_path,
253 bool recursive) { 213 bool recursive) {
254 base::ThreadRestrictions::AssertIOAllowed(); 214 ThreadRestrictions::AssertIOAllowed();
255 // Some old callers of CopyDirectory want it to support wildcards. 215 // Some old callers of CopyDirectory want it to support wildcards.
256 // After some discussion, we decided to fix those callers. 216 // After some discussion, we decided to fix those callers.
257 // Break loudly here if anyone tries to do this. 217 // Break loudly here if anyone tries to do this.
258 // TODO(evanm): remove this once we're sure it's ok. 218 // TODO(evanm): remove this once we're sure it's ok.
259 DCHECK(to_path.value().find('*') == std::string::npos); 219 DCHECK(to_path.value().find('*') == std::string::npos);
260 DCHECK(from_path.value().find('*') == std::string::npos); 220 DCHECK(from_path.value().find('*') == std::string::npos);
261 221
262 char top_dir[PATH_MAX]; 222 char top_dir[PATH_MAX];
263 if (base::strlcpy(top_dir, from_path.value().c_str(), 223 if (strlcpy(top_dir, from_path.value().c_str(),
264 arraysize(top_dir)) >= arraysize(top_dir)) { 224 arraysize(top_dir)) >= arraysize(top_dir)) {
265 return false; 225 return false;
266 } 226 }
267 227
268 // This function does not properly handle destinations within the source 228 // This function does not properly handle destinations within the source
269 FilePath real_to_path = to_path; 229 FilePath real_to_path = to_path;
270 if (PathExists(real_to_path)) { 230 if (file_util::PathExists(real_to_path)) {
271 real_to_path = MakeAbsoluteFilePath(real_to_path); 231 real_to_path = MakeAbsoluteFilePath(real_to_path);
272 if (real_to_path.empty()) 232 if (real_to_path.empty())
273 return false; 233 return false;
274 } else { 234 } else {
275 real_to_path = MakeAbsoluteFilePath(real_to_path.DirName()); 235 real_to_path = MakeAbsoluteFilePath(real_to_path.DirName());
276 if (real_to_path.empty()) 236 if (real_to_path.empty())
277 return false; 237 return false;
278 } 238 }
279 FilePath real_from_path = MakeAbsoluteFilePath(from_path); 239 FilePath real_from_path = MakeAbsoluteFilePath(from_path);
280 if (real_from_path.empty()) 240 if (real_from_path.empty())
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 } 302 }
343 303
344 current = traversal.Next(); 304 current = traversal.Next();
345 if (!current.empty()) 305 if (!current.empty())
346 from_stat = traversal.GetInfo().stat(); 306 from_stat = traversal.GetInfo().stat();
347 } 307 }
348 308
349 return success; 309 return success;
350 } 310 }
351 311
312 } // namespace base
313
314 // -----------------------------------------------------------------------------
315
316 namespace file_util {
317
318 using base::stat_wrapper_t;
319 using base::CallStat;
320 using base::CallLstat;
321 using base::FileEnumerator;
322 using base::FilePath;
323 using base::MakeAbsoluteFilePath;
324 using base::RealPath;
325 using base::VerifySpecificPathControlledByUser;
326
352 bool PathExists(const FilePath& path) { 327 bool PathExists(const FilePath& path) {
353 base::ThreadRestrictions::AssertIOAllowed(); 328 base::ThreadRestrictions::AssertIOAllowed();
354 return access(path.value().c_str(), F_OK) == 0; 329 return access(path.value().c_str(), F_OK) == 0;
355 } 330 }
356 331
357 bool PathIsWritable(const FilePath& path) { 332 bool PathIsWritable(const FilePath& path) {
358 base::ThreadRestrictions::AssertIOAllowed(); 333 base::ThreadRestrictions::AssertIOAllowed();
359 return access(path.value().c_str(), W_OK) == 0; 334 return access(path.value().c_str(), W_OK) == 0;
360 } 335 }
361 336
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 return FilePath(home_dir); 789 return FilePath(home_dir);
815 #endif 790 #endif
816 791
817 FilePath rv; 792 FilePath rv;
818 if (file_util::GetTempDir(&rv)) 793 if (file_util::GetTempDir(&rv))
819 return rv; 794 return rv;
820 795
821 // Last resort. 796 // Last resort.
822 return FilePath("/tmp"); 797 return FilePath("/tmp");
823 } 798 }
824
825 bool CopyFileUnsafe(const FilePath& from_path, const FilePath& to_path) {
826 base::ThreadRestrictions::AssertIOAllowed();
827 int infile = HANDLE_EINTR(open(from_path.value().c_str(), O_RDONLY));
828 if (infile < 0)
829 return false;
830
831 int outfile = HANDLE_EINTR(creat(to_path.value().c_str(), 0666));
832 if (outfile < 0) {
833 ignore_result(HANDLE_EINTR(close(infile)));
834 return false;
835 }
836
837 const size_t kBufferSize = 32768;
838 std::vector<char> buffer(kBufferSize);
839 bool result = true;
840
841 while (result) {
842 ssize_t bytes_read = HANDLE_EINTR(read(infile, &buffer[0], buffer.size()));
843 if (bytes_read < 0) {
844 result = false;
845 break;
846 }
847 if (bytes_read == 0)
848 break;
849 // Allow for partial writes
850 ssize_t bytes_written_per_read = 0;
851 do {
852 ssize_t bytes_written_partial = HANDLE_EINTR(write(
853 outfile,
854 &buffer[bytes_written_per_read],
855 bytes_read - bytes_written_per_read));
856 if (bytes_written_partial < 0) {
857 result = false;
858 break;
859 }
860 bytes_written_per_read += bytes_written_partial;
861 } while (bytes_written_per_read < bytes_read);
862 }
863
864 if (HANDLE_EINTR(close(infile)) < 0)
865 result = false;
866 if (HANDLE_EINTR(close(outfile)) < 0)
867 result = false;
868
869 return result;
870 }
871 #endif // !defined(OS_MACOSX) 799 #endif // !defined(OS_MACOSX)
872 800
873 bool VerifyPathControlledByUser(const FilePath& base, 801 bool VerifyPathControlledByUser(const FilePath& base,
874 const FilePath& path, 802 const FilePath& path,
875 uid_t owner_uid, 803 uid_t owner_uid,
876 const std::set<gid_t>& group_gids) { 804 const std::set<gid_t>& group_gids) {
877 if (base != path && !base.IsParent(path)) { 805 if (base != path && !base.IsParent(path)) {
878 DLOG(ERROR) << "|base| must be a subdirectory of |path|. base = \"" 806 DLOG(ERROR) << "|base| must be a subdirectory of |path|. base = \""
879 << base.value() << "\", path = \"" << path.value() << "\""; 807 << base.value() << "\", path = \"" << path.value() << "\"";
880 return false; 808 return false;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
939 kFileSystemRoot, path, kRootUid, allowed_group_ids); 867 kFileSystemRoot, path, kRootUid, allowed_group_ids);
940 } 868 }
941 #endif // defined(OS_MACOSX) && !defined(OS_IOS) 869 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
942 870
943 int GetMaximumPathComponentLength(const FilePath& path) { 871 int GetMaximumPathComponentLength(const FilePath& path) {
944 base::ThreadRestrictions::AssertIOAllowed(); 872 base::ThreadRestrictions::AssertIOAllowed();
945 return pathconf(path.value().c_str(), _PC_NAME_MAX); 873 return pathconf(path.value().c_str(), _PC_NAME_MAX);
946 } 874 }
947 875
948 } // namespace file_util 876 } // namespace file_util
877
878 namespace base {
879 namespace internal {
880
881 bool MoveUnsafe(const FilePath& from_path, const FilePath& to_path) {
882 ThreadRestrictions::AssertIOAllowed();
883 // Windows compatibility: if to_path exists, from_path and to_path
884 // must be the same type, either both files, or both directories.
885 stat_wrapper_t to_file_info;
886 if (CallStat(to_path.value().c_str(), &to_file_info) == 0) {
887 stat_wrapper_t from_file_info;
888 if (CallStat(from_path.value().c_str(), &from_file_info) == 0) {
889 if (S_ISDIR(to_file_info.st_mode) != S_ISDIR(from_file_info.st_mode))
890 return false;
891 } else {
892 return false;
893 }
894 }
895
896 if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0)
897 return true;
898
899 if (!CopyDirectory(from_path, to_path, true))
900 return false;
901
902 Delete(from_path, true);
903 return true;
904 }
905
906 #if !defined(OS_MACOSX)
907 // Mac has its own implementation, this is for all other Posix systems.
908 bool CopyFileUnsafe(const FilePath& from_path, const FilePath& to_path) {
909 ThreadRestrictions::AssertIOAllowed();
910 int infile = HANDLE_EINTR(open(from_path.value().c_str(), O_RDONLY));
911 if (infile < 0)
912 return false;
913
914 int outfile = HANDLE_EINTR(creat(to_path.value().c_str(), 0666));
915 if (outfile < 0) {
916 ignore_result(HANDLE_EINTR(close(infile)));
917 return false;
918 }
919
920 const size_t kBufferSize = 32768;
921 std::vector<char> buffer(kBufferSize);
922 bool result = true;
923
924 while (result) {
925 ssize_t bytes_read = HANDLE_EINTR(read(infile, &buffer[0], buffer.size()));
926 if (bytes_read < 0) {
927 result = false;
928 break;
929 }
930 if (bytes_read == 0)
931 break;
932 // Allow for partial writes
933 ssize_t bytes_written_per_read = 0;
934 do {
935 ssize_t bytes_written_partial = HANDLE_EINTR(write(
936 outfile,
937 &buffer[bytes_written_per_read],
938 bytes_read - bytes_written_per_read));
939 if (bytes_written_partial < 0) {
940 result = false;
941 break;
942 }
943 bytes_written_per_read += bytes_written_partial;
944 } while (bytes_written_per_read < bytes_read);
945 }
946
947 if (HANDLE_EINTR(close(infile)) < 0)
948 result = false;
949 if (HANDLE_EINTR(close(outfile)) < 0)
950 result = false;
951
952 return result;
953 }
954 #endif // !defined(OS_MACOSX)
955
956 } // namespace internal
957 } // namespace base
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