OLD | NEW |
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/files/file_util.h" | 5 #include "base/files/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 827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
838 } | 838 } |
839 if (use_dev_shm) { | 839 if (use_dev_shm) { |
840 *path = FilePath("/dev/shm"); | 840 *path = FilePath("/dev/shm"); |
841 return true; | 841 return true; |
842 } | 842 } |
843 #endif | 843 #endif |
844 return GetTempDir(path); | 844 return GetTempDir(path); |
845 } | 845 } |
846 #endif // !defined(OS_ANDROID) | 846 #endif // !defined(OS_ANDROID) |
847 | 847 |
848 // ----------------------------------------------------------------------------- | 848 #if !defined(OS_MACOSX) |
849 | 849 // Mac has its own implementation, this is for all other Posix systems. |
850 namespace internal { | 850 bool CopyFile(const FilePath& from_path, const FilePath& to_path) { |
851 | |
852 bool MoveUnsafe(const FilePath& from_path, const FilePath& to_path) { | |
853 ThreadRestrictions::AssertIOAllowed(); | 851 ThreadRestrictions::AssertIOAllowed(); |
854 // Windows compatibility: if to_path exists, from_path and to_path | 852 File infile; |
855 // must be the same type, either both files, or both directories. | 853 #if defined(OS_ANDROID) |
856 stat_wrapper_t to_file_info; | 854 if (from_path.IsContentUri()) { |
857 if (CallStat(to_path.value().c_str(), &to_file_info) == 0) { | 855 infile = OpenContentUriForRead(from_path); |
858 stat_wrapper_t from_file_info; | 856 } else { |
859 if (CallStat(from_path.value().c_str(), &from_file_info) == 0) { | 857 infile = File(from_path, File::FLAG_OPEN | File::FLAG_READ); |
860 if (S_ISDIR(to_file_info.st_mode) != S_ISDIR(from_file_info.st_mode)) | |
861 return false; | |
862 } else { | |
863 return false; | |
864 } | |
865 } | 858 } |
866 | 859 #else |
867 if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0) | 860 infile = File(from_path, File::FLAG_OPEN | File::FLAG_READ); |
868 return true; | 861 #endif |
869 | 862 if (!infile.IsValid()) |
870 if (!CopyDirectory(from_path, to_path, true)) | |
871 return false; | 863 return false; |
872 | 864 |
873 DeleteFile(from_path, true); | 865 File outfile(to_path, File::FLAG_WRITE | File::FLAG_CREATE_ALWAYS); |
874 return true; | 866 if (!outfile.IsValid()) |
875 } | |
876 | |
877 #if !defined(OS_MACOSX) | |
878 // Mac has its own implementation, this is for all other Posix systems. | |
879 bool CopyFileUnsafe(const FilePath& from_path, const FilePath& to_path) { | |
880 ThreadRestrictions::AssertIOAllowed(); | |
881 int infile = HANDLE_EINTR(open(from_path.value().c_str(), O_RDONLY)); | |
882 if (infile < 0) | |
883 return false; | 867 return false; |
884 | 868 |
885 int outfile = HANDLE_EINTR(creat(to_path.value().c_str(), 0666)); | |
886 if (outfile < 0) { | |
887 close(infile); | |
888 return false; | |
889 } | |
890 | |
891 const size_t kBufferSize = 32768; | 869 const size_t kBufferSize = 32768; |
892 std::vector<char> buffer(kBufferSize); | 870 std::vector<char> buffer(kBufferSize); |
893 bool result = true; | 871 bool result = true; |
894 | 872 |
895 while (result) { | 873 while (result) { |
896 ssize_t bytes_read = HANDLE_EINTR(read(infile, &buffer[0], buffer.size())); | 874 ssize_t bytes_read = infile.ReadAtCurrentPos(&buffer[0], buffer.size()); |
897 if (bytes_read < 0) { | 875 if (bytes_read < 0) { |
898 result = false; | 876 result = false; |
899 break; | 877 break; |
900 } | 878 } |
901 if (bytes_read == 0) | 879 if (bytes_read == 0) |
902 break; | 880 break; |
903 // Allow for partial writes | 881 // Allow for partial writes |
904 ssize_t bytes_written_per_read = 0; | 882 ssize_t bytes_written_per_read = 0; |
905 do { | 883 do { |
906 ssize_t bytes_written_partial = HANDLE_EINTR(write( | 884 ssize_t bytes_written_partial = outfile.WriteAtCurrentPos( |
907 outfile, | 885 &buffer[bytes_written_per_read], bytes_read - bytes_written_per_read); |
908 &buffer[bytes_written_per_read], | |
909 bytes_read - bytes_written_per_read)); | |
910 if (bytes_written_partial < 0) { | 886 if (bytes_written_partial < 0) { |
911 result = false; | 887 result = false; |
912 break; | 888 break; |
913 } | 889 } |
914 bytes_written_per_read += bytes_written_partial; | 890 bytes_written_per_read += bytes_written_partial; |
915 } while (bytes_written_per_read < bytes_read); | 891 } while (bytes_written_per_read < bytes_read); |
916 } | 892 } |
917 | 893 |
918 if (IGNORE_EINTR(close(infile)) < 0) | |
919 result = false; | |
920 if (IGNORE_EINTR(close(outfile)) < 0) | |
921 result = false; | |
922 | |
923 return result; | 894 return result; |
924 } | 895 } |
925 #endif // !defined(OS_MACOSX) | 896 #endif // !defined(OS_MACOSX) |
926 | 897 |
| 898 // ----------------------------------------------------------------------------- |
| 899 |
| 900 namespace internal { |
| 901 |
| 902 bool MoveUnsafe(const FilePath& from_path, const FilePath& to_path) { |
| 903 ThreadRestrictions::AssertIOAllowed(); |
| 904 // Windows compatibility: if to_path exists, from_path and to_path |
| 905 // must be the same type, either both files, or both directories. |
| 906 stat_wrapper_t to_file_info; |
| 907 if (CallStat(to_path.value().c_str(), &to_file_info) == 0) { |
| 908 stat_wrapper_t from_file_info; |
| 909 if (CallStat(from_path.value().c_str(), &from_file_info) == 0) { |
| 910 if (S_ISDIR(to_file_info.st_mode) != S_ISDIR(from_file_info.st_mode)) |
| 911 return false; |
| 912 } else { |
| 913 return false; |
| 914 } |
| 915 } |
| 916 |
| 917 if (rename(from_path.value().c_str(), to_path.value().c_str()) == 0) |
| 918 return true; |
| 919 |
| 920 if (!CopyDirectory(from_path, to_path, true)) |
| 921 return false; |
| 922 |
| 923 DeleteFile(from_path, true); |
| 924 return true; |
| 925 } |
| 926 |
927 } // namespace internal | 927 } // namespace internal |
928 | 928 |
929 #endif // !defined(OS_NACL_NONSFI) | 929 #endif // !defined(OS_NACL_NONSFI) |
930 } // namespace base | 930 } // namespace base |
OLD | NEW |