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