Delete some unused code in src/base. The motivation was that I wanted to fix the one -Wc++11-narrowing warning that clang-cl emitted in File::DeleteOnClose() (...given the warning doesn't fire on win-only code, we apparently deemed this a valuable warning). I saw that the method was dead, so then I went through other File::Flags and removed unused ones, and I removed some unused functions in file_util that kepts some of the remaining flags alive. No behavior change. With this, gn builds with clang-cl without any custom CFLAGS. Bug: none Change-Id: I7663c886022ffecbd8a1811952805467c9a163b4 Reviewed-on: https://gn-review.googlesource.com/c/gn/+/6640 Reviewed-by: Brett Wilson <brettw@chromium.org> Commit-Queue: Brett Wilson <brettw@chromium.org>
diff --git a/src/base/files/file.cc b/src/base/files/file.cc index 8c04016..d82911a 100644 --- a/src/base/files/file.cc +++ b/src/base/files/file.cc
@@ -17,52 +17,40 @@ File::Info::~Info() = default; File::File() - : error_details_(FILE_ERROR_FAILED), created_(false), async_(false) {} + : error_details_(FILE_ERROR_FAILED), created_(false) {} File::File(const FilePath& path, uint32_t flags) - : error_details_(FILE_OK), created_(false), async_(false) { + : error_details_(FILE_OK), created_(false) { Initialize(path, flags); } File::File(PlatformFile platform_file) : file_(platform_file), error_details_(FILE_OK), - created_(false), - async_(false) { + created_(false) { #if defined(OS_POSIX) || defined(OS_FUCHSIA) DCHECK_GE(platform_file, -1); #endif } File::File(Error error_details) - : error_details_(error_details), created_(false), async_(false) {} + : error_details_(error_details), created_(false) {} File::File(File&& other) : file_(other.TakePlatformFile()), error_details_(other.error_details()), - created_(other.created()), - async_(other.async_) {} + created_(other.created()) {} File::~File() { // Go through the AssertIOAllowed logic. Close(); } -// static -File File::CreateForAsyncHandle(PlatformFile platform_file) { - File file(platform_file); - // It would be nice if we could validate that |platform_file| was opened with - // FILE_FLAG_OVERLAPPED on Windows but this doesn't appear to be possible. - file.async_ = true; - return file; -} - File& File::operator=(File&& other) { Close(); SetPlatformFile(other.TakePlatformFile()); error_details_ = other.error_details(); created_ = other.created(); - async_ = other.async_; return *this; }
diff --git a/src/base/files/file.h b/src/base/files/file.h index 838d0b8..673a638 100644 --- a/src/base/files/file.h +++ b/src/base/files/file.h
@@ -30,8 +30,7 @@ #endif // Thin wrapper around an OS-level file. -// Note that this class does not provide any support for asynchronous IO, other -// than the ability to create asynchronous handles on Windows. +// Note that this class does not provide any support for asynchronous IO. // // Note about const: this class does not attempt to determine if the underlying // file system object is affected by a particular method in order to consider @@ -44,36 +43,11 @@ // FLAG_(OPEN|CREATE).* are mutually exclusive. You should specify exactly one // of the five (possibly combining with other flags) when opening or creating // a file. - // FLAG_(WRITE|APPEND) are mutually exclusive. This is so that APPEND behavior - // will be consistent with O_APPEND on POSIX. - // FLAG_EXCLUSIVE_(READ|WRITE) only grant exclusive access to the file on - // creation on POSIX; for existing files, consider using Lock(). enum Flags { FLAG_OPEN = 1 << 0, // Opens a file, only if it exists. - FLAG_CREATE = 1 << 1, // Creates a new file, only if it does not - // already exist. - FLAG_OPEN_ALWAYS = 1 << 2, // May create a new file. FLAG_CREATE_ALWAYS = 1 << 3, // May overwrite an old file. - FLAG_OPEN_TRUNCATED = 1 << 4, // Opens a file and truncates it, only if it - // exists. - FLAG_READ = 1 << 5, - FLAG_WRITE = 1 << 6, - FLAG_APPEND = 1 << 7, - FLAG_EXCLUSIVE_READ = 1 << 8, // EXCLUSIVE is opposite of Windows SHARE. - FLAG_EXCLUSIVE_WRITE = 1 << 9, - FLAG_ASYNC = 1 << 10, - FLAG_TEMPORARY = 1 << 11, // Used on Windows only. - FLAG_HIDDEN = 1 << 12, // Used on Windows only. - FLAG_DELETE_ON_CLOSE = 1 << 13, - FLAG_WRITE_ATTRIBUTES = 1 << 14, // Used on Windows only. - FLAG_SHARE_DELETE = 1 << 15, // Used on Windows only. - FLAG_TERMINAL_DEVICE = 1 << 16, // Serial port flags. - FLAG_BACKUP_SEMANTICS = 1 << 17, // Used on Windows only. - FLAG_EXECUTE = 1 << 18, // Used on Windows only. - FLAG_SEQUENTIAL_SCAN = 1 << 19, // Used on Windows only. - FLAG_CAN_DELETE_ON_CLOSE = 1 << 20, // Requests permission to delete a file - // via DeleteOnClose() (Windows only). - // See DeleteOnClose() for details. + FLAG_READ = 1 << 4, + FLAG_WRITE = 1 << 5, }; // This enum has been recorded in multiple histograms using PlatformFileError @@ -157,9 +131,6 @@ ~File(); - // Takes ownership of |platform_file|. - static File CreateForAsyncHandle(PlatformFile platform_file); - File& operator=(File&& other); // Creates or opens the given file. @@ -216,8 +187,6 @@ // data that was previously there. Returns the number of bytes written, or -1 // on error. Note that this function makes a best effort to write all data on // all platforms. |data| can be nullptr when |size| is 0. - // Ignores the offset and writes to the end of the file if the file was opened - // with FLAG_APPEND. int Write(int64_t offset, const char* data, int size); // Save as above but without seek. @@ -282,44 +251,9 @@ #endif // !defined(OS_FUCHSIA) // Returns a new object referencing this file for use within the current - // process. Handling of FLAG_DELETE_ON_CLOSE varies by OS. On POSIX, the File - // object that was created or initialized with this flag will have unlinked - // the underlying file when it was created or opened. On Windows, the - // underlying file is deleted when the last handle to it is closed. + // process. File Duplicate() const; - bool async() const { return async_; } - -#if defined(OS_WIN) - // Sets or clears the DeleteFile disposition on the handle. Returns true if - // the disposition was set or cleared, as indicated by |delete_on_close|. - // - // Microsoft Windows deletes a file only when the last handle to the - // underlying kernel object is closed when the DeleteFile disposition has been - // set by any handle holder. This disposition is be set by: - // - Calling the Win32 DeleteFile function with the path to a file. - // - Opening/creating a file with FLAG_DELETE_ON_CLOSE. - // - Opening/creating a file with FLAG_CAN_DELETE_ON_CLOSE and subsequently - // calling DeleteOnClose(true). - // - // In all cases, all pre-existing handles to the file must have been opened - // with FLAG_SHARE_DELETE. - // - // So: - // - Use FLAG_SHARE_DELETE when creating/opening a file to allow another - // entity on the system to cause it to be deleted when it is closed. (Note: - // another entity can delete the file the moment after it is closed, so not - // using this permission doesn't provide any protections.) - // - Use FLAG_DELETE_ON_CLOSE for any file that is to be deleted after use. - // The OS will ensure it is deleted even in the face of process termination. - // - Use FLAG_CAN_DELETE_ON_CLOSE in conjunction with DeleteOnClose() to alter - // the DeleteFile disposition on an open handle. This fine-grained control - // allows for marking a file for deletion during processing so that it is - // deleted in the event of untimely process termination, and then clearing - // this state once the file is suitable for persistence. - bool DeleteOnClose(bool delete_on_close); -#endif - #if defined(OS_WIN) static Error OSErrorToFileError(DWORD last_error); #elif defined(OS_POSIX) || defined(OS_FUCHSIA) @@ -346,7 +280,6 @@ Error error_details_; bool created_; - bool async_; DISALLOW_COPY_AND_ASSIGN(File); };
diff --git a/src/base/files/file_posix.cc b/src/base/files/file_posix.cc index 2a73f7e..a60b22b 100644 --- a/src/base/files/file_posix.cc +++ b/src/base/files/file_posix.cc
@@ -289,8 +289,6 @@ return File(File::GetLastFileError()); File other(other_fd); - if (async()) - other.async_ = true; return other; } @@ -327,14 +325,10 @@ } } -// TODO(erikkay): does it make sense to support FLAG_EXCLUSIVE_* here? void File::DoInitialize(const FilePath& path, uint32_t flags) { DCHECK(!IsValid()); int open_flags = 0; - if (flags & FLAG_CREATE) - open_flags = O_CREAT | O_EXCL; - created_ = false; if (flags & FLAG_CREATE_ALWAYS) { @@ -343,13 +337,7 @@ open_flags = O_CREAT | O_TRUNC; } - if (flags & FLAG_OPEN_TRUNCATED) { - DCHECK(!open_flags); - DCHECK(flags & FLAG_WRITE); - open_flags = O_TRUNC; - } - - if (!open_flags && !(flags & FLAG_OPEN) && !(flags & FLAG_OPEN_ALWAYS)) { + if (!open_flags && !(flags & FLAG_OPEN)) { NOTREACHED(); errno = EOPNOTSUPP; error_details_ = FILE_ERROR_FAILED; @@ -360,48 +348,23 @@ open_flags |= O_RDWR; } else if (flags & FLAG_WRITE) { open_flags |= O_WRONLY; - } else if (!(flags & FLAG_READ) && !(flags & FLAG_WRITE_ATTRIBUTES) && - !(flags & FLAG_APPEND) && !(flags & FLAG_OPEN_ALWAYS)) { + } else if (!(flags & FLAG_READ)) { NOTREACHED(); } - if (flags & FLAG_TERMINAL_DEVICE) - open_flags |= O_NOCTTY | O_NDELAY; - - if (flags & FLAG_APPEND && flags & FLAG_READ) - open_flags |= O_APPEND | O_RDWR; - else if (flags & FLAG_APPEND) - open_flags |= O_APPEND | O_WRONLY; - static_assert(O_RDONLY == 0, "O_RDONLY must equal zero"); int mode = S_IRUSR | S_IWUSR; int descriptor = HANDLE_EINTR(open(path.value().c_str(), open_flags, mode)); - if (flags & FLAG_OPEN_ALWAYS) { - if (descriptor < 0) { - open_flags |= O_CREAT; - if (flags & FLAG_EXCLUSIVE_READ || flags & FLAG_EXCLUSIVE_WRITE) - open_flags |= O_EXCL; // together with O_CREAT implies O_NOFOLLOW - - descriptor = HANDLE_EINTR(open(path.value().c_str(), open_flags, mode)); - if (descriptor >= 0) - created_ = true; - } - } - if (descriptor < 0) { error_details_ = File::GetLastFileError(); return; } - if (flags & (FLAG_CREATE_ALWAYS | FLAG_CREATE)) + if (flags & FLAG_CREATE_ALWAYS) created_ = true; - if (flags & FLAG_DELETE_ON_CLOSE) - unlink(path.value().c_str()); - - async_ = ((flags & FLAG_ASYNC) == FLAG_ASYNC); error_details_ = FILE_OK; file_.reset(descriptor); }
diff --git a/src/base/files/file_util.cc b/src/base/files/file_util.cc index 7043b75..c68fe02 100644 --- a/src/base/files/file_util.cc +++ b/src/base/files/file_util.cc
@@ -185,14 +185,6 @@ return false; } -FILE* CreateAndOpenTemporaryFile(FilePath* path) { - FilePath directory; - if (!GetTempDir(&directory)) - return nullptr; - - return CreateAndOpenTemporaryFileInDir(directory, path); -} - bool CreateDirectory(const FilePath& full_path) { return CreateDirectoryAndGetError(full_path, nullptr); }
diff --git a/src/base/files/file_util.h b/src/base/files/file_util.h index 0478c91..27fc998 100644 --- a/src/base/files/file_util.h +++ b/src/base/files/file_util.h
@@ -124,20 +124,6 @@ std::string* contents, size_t max_size); -#if defined(OS_POSIX) || defined(OS_FUCHSIA) - -// Read exactly |bytes| bytes from file descriptor |fd|, storing the result -// in |buffer|. This function is protected against EINTR and partial reads. -// Returns true iff |bytes| bytes have been successfully read from |fd|. -bool ReadFromFD(int fd, char* buffer, size_t bytes); - -// Performs the same function as CreateAndOpenTemporaryFileInDir(), but returns -// the file-descriptor directly, rather than wrapping it into a FILE. Returns -// -1 on failure. -int CreateAndOpenFdForTemporaryFileInDir(const FilePath& dir, FilePath* path); - -#endif // OS_POSIX || OS_FUCHSIA - #if defined(OS_POSIX) // Creates a symbolic link at |symlink| pointing to |target|. Returns @@ -185,29 +171,8 @@ bool IsDirectoryEmpty(const FilePath& dir_path); // Get the temporary directory provided by the system. -// -// WARNING: In general, you should use CreateTemporaryFile variants below -// instead of this function. Those variants will ensure that the proper -// permissions are set so that other users on the system can't edit them while -// they're open (which can lead to security issues). bool GetTempDir(FilePath* path); -// Creates a temporary file. The full path is placed in |path|, and the -// function returns true if was successful in creating the file. The file will -// be empty and all handles closed after this function returns. -bool CreateTemporaryFile(FilePath* path); - -// Same as CreateTemporaryFile but the file is created in |dir|. -bool CreateTemporaryFileInDir(const FilePath& dir, FilePath* temp_file); - -// Create and open a temporary file. File is opened for read/write. -// The full path is placed in |path|. -// Returns a handle to the opened file or NULL if an error occurred. -FILE* CreateAndOpenTemporaryFile(FilePath* path); - -// Similar to CreateAndOpenTemporaryFile, but the file is created in |dir|. -FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir, FilePath* path); - // Create a new directory. If prefix is provided, the new directory name is in // the format of prefixyyyy. // NOTE: prefix is ignored in the POSIX implementation. @@ -380,15 +345,6 @@ bool GetFileSystemType(const FilePath& path, FileSystemType* type); #endif -#if defined(OS_POSIX) || defined(OS_FUCHSIA) -// Get a temporary directory for shared memory files. The directory may depend -// on whether the destination is intended for executable files, which in turn -// depends on how /dev/shmem was mounted. As a result, you must supply whether -// you intend to create executable shmem segments so this function can find -// an appropriate location. -bool GetShmemTempDir(bool executable, FilePath* path); -#endif - } // namespace base #endif // BASE_FILES_FILE_UTIL_H_
diff --git a/src/base/files/file_util_posix.cc b/src/base/files/file_util_posix.cc index 7054880..90362ff 100644 --- a/src/base/files/file_util_posix.cc +++ b/src/base/files/file_util_posix.cc
@@ -113,35 +113,6 @@ return std::string(".org.chromium.Chromium.XXXXXX"); } -#if defined(OS_LINUX) || defined(OS_AIX) -// Determine if /dev/shm files can be mapped and then mprotect'd PROT_EXEC. -// This depends on the mount options used for /dev/shm, which vary among -// different Linux distributions and possibly local configuration. It also -// depends on details of kernel--ChromeOS uses the noexec option for /dev/shm -// but its kernel allows mprotect with PROT_EXEC anyway. -bool DetermineDevShmExecutable() { - bool result = false; - FilePath path; - - ScopedFD fd( - CreateAndOpenFdForTemporaryFileInDir(FilePath("/dev/shm"), &path)); - if (fd.is_valid()) { - DeleteFile(path, false); - long sysconf_result = sysconf(_SC_PAGESIZE); - CHECK_GE(sysconf_result, 0); - size_t pagesize = static_cast<size_t>(sysconf_result); - CHECK_GE(sizeof(pagesize), sizeof(sysconf_result)); - void* mapping = mmap(nullptr, pagesize, PROT_READ, MAP_SHARED, fd.get(), 0); - if (mapping != MAP_FAILED) { - if (mprotect(mapping, pagesize, PROT_READ | PROT_EXEC) == 0) - result = true; - munmap(mapping, pagesize); - } - } - return result; -} -#endif // defined(OS_LINUX) || defined(OS_AIX) - #if !defined(OS_MACOSX) bool CopyFileContents(File* infile, File* outfile) { static constexpr size_t kBufferSize = 32768; @@ -298,28 +269,6 @@ return S_ISDIR(file_info.st_mode); } -bool ReadFromFD(int fd, char* buffer, size_t bytes) { - size_t total_read = 0; - while (total_read < bytes) { - ssize_t bytes_read = - HANDLE_EINTR(read(fd, buffer + total_read, bytes - total_read)); - if (bytes_read <= 0) - break; - total_read += bytes_read; - } - return total_read == bytes; -} - -int CreateAndOpenFdForTemporaryFileInDir(const FilePath& directory, - FilePath* path) { - *path = directory.Append(TempFileName()); - const std::string& tmpdir_string = path->value(); - // this should be OK since mkstemp just replaces characters in place - char* buffer = const_cast<char*>(tmpdir_string.c_str()); - - return HANDLE_EINTR(mkstemp(buffer)); -} - #if !defined(OS_FUCHSIA) bool CreateSymbolicLink(const FilePath& target_path, const FilePath& symlink_path) { @@ -422,33 +371,6 @@ } #endif // !defined(OS_MACOSX) -bool CreateTemporaryFile(FilePath* path) { - FilePath directory; - if (!GetTempDir(&directory)) - return false; - int fd = CreateAndOpenFdForTemporaryFileInDir(directory, path); - if (fd < 0) - return false; - close(fd); - return true; -} - -FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir, FilePath* path) { - int fd = CreateAndOpenFdForTemporaryFileInDir(dir, path); - if (fd < 0) - return nullptr; - - FILE* file = fdopen(fd, "a+"); - if (!file) - close(fd); - return file; -} - -bool CreateTemporaryFileInDir(const FilePath& dir, FilePath* temp_file) { - int fd = CreateAndOpenFdForTemporaryFileInDir(dir, temp_file); - return ((fd >= 0) && !IGNORE_EINTR(close(fd))); -} - static bool CreateTemporaryDirInDirImpl(const FilePath& base_dir, const FilePath::StringType& name_tmpl, FilePath* new_dir) { @@ -723,21 +645,6 @@ return pathconf(path.value().c_str(), _PC_NAME_MAX); } -bool GetShmemTempDir(bool executable, FilePath* path) { -#if defined(OS_LINUX) || defined(OS_AIX) - bool use_dev_shm = true; - if (executable) { - static const bool s_dev_shm_executable = DetermineDevShmExecutable(); - use_dev_shm = s_dev_shm_executable; - } - if (use_dev_shm) { - *path = FilePath("/dev/shm"); - return true; - } -#endif // defined(OS_LINUX) || defined(OS_AIX) - return GetTempDir(path); -} - #if !defined(OS_MACOSX) // Mac has its own implementation, this is for all other Posix systems. bool CopyFile(const FilePath& from_path, const FilePath& to_path) {
diff --git a/src/base/files/file_util_win.cc b/src/base/files/file_util_win.cc index 1556d26..fe5c225 100644 --- a/src/base/files/file_util_win.cc +++ b/src/base/files/file_util_win.cc
@@ -279,79 +279,6 @@ return true; } -bool CreateTemporaryFile(FilePath* path) { - FilePath temp_file; - - if (!GetTempDir(path)) - return false; - - if (CreateTemporaryFileInDir(*path, &temp_file)) { - *path = temp_file; - return true; - } - - return false; -} - -// On POSIX we have semantics to create and open a temporary file -// atomically. -// TODO(jrg): is there equivalent call to use on Windows instead of -// going 2-step? -FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir, FilePath* path) { - if (!CreateTemporaryFileInDir(dir, path)) { - return NULL; - } - // Open file in binary mode, to avoid problems with fwrite. On Windows - // it replaces \n's with \r\n's, which may surprise you. - // Reference: http://msdn.microsoft.com/en-us/library/h9t88zwz(VS.71).aspx - return OpenFile(*path, "wb+"); -} - -bool CreateTemporaryFileInDir(const FilePath& dir, FilePath* temp_file) { - // Use GUID instead of ::GetTempFileName() to generate unique file names. - // "Due to the algorithm used to generate file names, GetTempFileName can - // perform poorly when creating a large number of files with the same prefix. - // In such cases, it is recommended that you construct unique file names based - // on GUIDs." - // https://msdn.microsoft.com/library/windows/desktop/aa364991.aspx - - FilePath temp_name; - bool create_file_success = false; - - // Although it is nearly impossible to get a duplicate name with GUID, we - // still use a loop here in case it happens. - for (int i = 0; i < 100; ++i) { - temp_name = dir.Append(ASCIIToUTF16(base::GenerateGUID()) + u".tmp"); - File file(temp_name, - File::FLAG_CREATE | File::FLAG_READ | File::FLAG_WRITE); - if (file.IsValid()) { - file.Close(); - create_file_success = true; - break; - } - } - - if (!create_file_success) { - DPLOG(WARNING) << "Failed to get temporary file name in " - << UTF16ToUTF8(dir.value()); - return false; - } - - char16_t long_temp_name[MAX_PATH + 1]; - DWORD long_name_len = GetLongPathName(ToWCharT(&temp_name.value()), - ToWCharT(long_temp_name), MAX_PATH); - if (long_name_len > MAX_PATH || long_name_len == 0) { - // GetLongPathName() failed, but we still have a temporary file. - *temp_file = std::move(temp_name); - return true; - } - - FilePath::StringType long_temp_name_str; - long_temp_name_str.assign(long_temp_name, long_name_len); - *temp_file = FilePath(std::move(long_temp_name_str)); - return true; -} - bool CreateTemporaryDirInDir(const FilePath& base_dir, const FilePath::StringType& prefix, FilePath* new_dir) {
diff --git a/src/base/files/file_win.cc b/src/base/files/file_win.cc index 4bce7df..2a65548 100644 --- a/src/base/files/file_win.cc +++ b/src/base/files/file_win.cc
@@ -52,7 +52,6 @@ int File::Read(int64_t offset, char* data, int size) { DCHECK(IsValid()); - DCHECK(!async_); if (size < 0) return -1; @@ -74,7 +73,6 @@ int File::ReadAtCurrentPos(char* data, int size) { DCHECK(IsValid()); - DCHECK(!async_); if (size < 0) return -1; @@ -99,7 +97,6 @@ int File::Write(int64_t offset, const char* data, int size) { DCHECK(IsValid()); - DCHECK(!async_); LARGE_INTEGER offset_li; offset_li.QuadPart = offset; @@ -117,7 +114,6 @@ int File::WriteAtCurrentPos(const char* data, int size) { DCHECK(IsValid()); - DCHECK(!async_); if (size < 0) return -1; @@ -227,17 +223,9 @@ } File other(other_handle); - if (async()) - other.async_ = true; return other; } -bool File::DeleteOnClose(bool delete_on_close) { - FILE_DISPOSITION_INFO disposition = {delete_on_close ? TRUE : FALSE}; - return ::SetFileInformationByHandle(GetPlatformFile(), FileDispositionInfo, - &disposition, sizeof(disposition)) != 0; -} - // Static. File::Error File::OSErrorToFileError(DWORD last_error) { switch (last_error) { @@ -284,28 +272,12 @@ if (flags & FLAG_OPEN) disposition = OPEN_EXISTING; - if (flags & FLAG_CREATE) { - DCHECK(!disposition); - disposition = CREATE_NEW; - } - - if (flags & FLAG_OPEN_ALWAYS) { - DCHECK(!disposition); - disposition = OPEN_ALWAYS; - } - if (flags & FLAG_CREATE_ALWAYS) { DCHECK(!disposition); DCHECK(flags & FLAG_WRITE); disposition = CREATE_ALWAYS; } - if (flags & FLAG_OPEN_TRUNCATED) { - DCHECK(!disposition); - DCHECK(flags & FLAG_WRITE); - disposition = TRUNCATE_EXISTING; - } - if (!disposition) { ::SetLastError(ERROR_INVALID_PARAMETER); error_details_ = FILE_ERROR_FAILED; @@ -316,49 +288,17 @@ DWORD access = 0; if (flags & FLAG_WRITE) access = GENERIC_WRITE; - if (flags & FLAG_APPEND) { - DCHECK(!access); - access = FILE_APPEND_DATA; - } if (flags & FLAG_READ) access |= GENERIC_READ; - if (flags & FLAG_WRITE_ATTRIBUTES) - access |= FILE_WRITE_ATTRIBUTES; - if (flags & FLAG_EXECUTE) - access |= GENERIC_EXECUTE; - if (flags & FLAG_CAN_DELETE_ON_CLOSE) - access |= DELETE; - DWORD sharing = (flags & FLAG_EXCLUSIVE_READ) ? 0 : FILE_SHARE_READ; - if (!(flags & FLAG_EXCLUSIVE_WRITE)) - sharing |= FILE_SHARE_WRITE; - if (flags & FLAG_SHARE_DELETE) - sharing |= FILE_SHARE_DELETE; - + DWORD sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; DWORD create_flags = 0; - if (flags & FLAG_ASYNC) - create_flags |= FILE_FLAG_OVERLAPPED; - if (flags & FLAG_TEMPORARY) - create_flags |= FILE_ATTRIBUTE_TEMPORARY; - if (flags & FLAG_HIDDEN) - create_flags |= FILE_ATTRIBUTE_HIDDEN; - if (flags & FLAG_DELETE_ON_CLOSE) - create_flags |= FILE_FLAG_DELETE_ON_CLOSE; - if (flags & FLAG_BACKUP_SEMANTICS) - create_flags |= FILE_FLAG_BACKUP_SEMANTICS; - if (flags & FLAG_SEQUENTIAL_SCAN) - create_flags |= FILE_FLAG_SEQUENTIAL_SCAN; - file_.Set(CreateFile(ToWCharT(&path.value()), access, sharing, NULL, disposition, create_flags, NULL)); if (file_.IsValid()) { error_details_ = FILE_OK; - async_ = ((flags & FLAG_ASYNC) == FLAG_ASYNC); - - if (flags & (FLAG_OPEN_ALWAYS)) - created_ = (ERROR_ALREADY_EXISTS != GetLastError()); - else if (flags & (FLAG_CREATE_ALWAYS | FLAG_CREATE)) + if (flags & FLAG_CREATE_ALWAYS) created_ = true; } else { error_details_ = GetLastFileError();