stream: extend open/create disposition flags

User could not create file only if it did not exist.

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2023-09-20 11:13:12 +02:00
parent 50fea81f83
commit 475e6734a7
2 changed files with 39 additions and 24 deletions

View File

@ -1,4 +1,4 @@
/* /*
SPDX-License-Identifier: MIT SPDX-License-Identifier: MIT
Copyright © 2023 Amebis Copyright © 2023 Amebis
*/ */
@ -124,7 +124,7 @@ namespace UnitTests
dat.close(); dat.close();
} }
for (uint32_t i = 0; i < count; ++i) { for (uint32_t i = 0; i < count; ++i) {
dat.open(filename[i].c_str(), mode_for_reading | share_none | mode_binary); dat.open(filename[i].c_str(), mode_for_reading | mode_open_existing | share_none | mode_binary);
Assert::IsTrue(dat.ok()); Assert::IsTrue(dat.ok());
for (;;) { for (;;) {
uint32_t x; uint32_t x;

View File

@ -1,4 +1,4 @@
/* /*
SPDX-License-Identifier: MIT SPDX-License-Identifier: MIT
Copyright © 2023 Amebis Copyright © 2023 Amebis
*/ */
@ -2407,24 +2407,30 @@ namespace stdex
mode_for_reading = 1 << 0, ///< Open for reading mode_for_reading = 1 << 0, ///< Open for reading
mode_for_writing = 1 << 1, ///< Open for writing mode_for_writing = 1 << 1, ///< Open for writing
mode_for_chmod = 1 << 2, ///< Open for changing file attributes mode_for_chmod = 1 << 2, ///< Open for changing file attributes
mode_create = 1 << 3, ///< Create file
mode_preserve_existing = mode_create | (1 << 4), ///< If file already exists, open existing; otherwise, create a new one. mode_open_existing = 0 << 3, ///< Open file, fail if not exists
mode_append = 1 << 5, ///< Seek to the end of file after opening mode_truncate_existing = 1 << 3, ///< Truncate file, fail if not exists
mode_preserve_existing = 2 << 3, ///< Open file if exists; create file if not exists
mode_create_new = 3 << 3, ///< Create file, fail if exists
mode_create = 4 << 3, ///< Create file if not exists; open and truncate if exists
mode_disposition_mask = 7 << 3, ///< Bitwise mask for creation disposition
mode_append = 1 << 6, ///< Seek to the end of file after opening
mode_text = 0, ///< Open as text file mode_text = 0, ///< Open as text file
mode_binary = 1 << 6, ///< Open as binary file mode_binary = 1 << 7, ///< Open as binary file
share_none = 0, ///< Open for exclusive access (default) share_none = 0, ///< Open for exclusive access (default)
share_reading = 1 << 7, ///< Allow others to read our file share_reading = 1 << 8, ///< Allow others to read our file
share_writing = 1 << 8, ///< Allow others to write to our file share_writing = 1 << 9, ///< Allow others to write to our file
share_deleting = 1 << 9, ///< Allow others to mark our file for deletion share_deleting = 1 << 10, ///< Allow others to mark our file for deletion
share_all = share_reading | share_writing | share_deleting, // Allow others all operations on our file share_all = share_reading | share_writing | share_deleting, // Allow others all operations on our file
inherit_handle = 1 << 10, ///< Inherit handle in child processes (Windows-specific) inherit_handle = 1 << 11, ///< Inherit handle in child processes (Windows-specific)
hint_write_thru = 1 << 11, ///< Write operations will not go through any intermediate cache, they will go directly to disk. (Windows-specific) hint_write_thru = 1 << 12, ///< Write operations will not go through any intermediate cache, they will go directly to disk. (Windows-specific)
hint_no_buffering = 1 << 12, ///< The file or device is being opened with no system caching for data reads and writes. (Windows-specific) hint_no_buffering = 1 << 13, ///< The file or device is being opened with no system caching for data reads and writes. (Windows-specific)
hint_random_access = 1 << 13, ///< Access is intended to be random. (Windows-specific) hint_random_access = 1 << 14, ///< Access is intended to be random. (Windows-specific)
hint_sequential_access = 1 << 14, ///< Access is intended to be sequential from beginning to end. (Windows-specific) hint_sequential_access = 1 << 15, ///< Access is intended to be sequential from beginning to end. (Windows-specific)
}; };
#pragma warning(push) #pragma warning(push)
@ -2474,10 +2480,12 @@ namespace stdex
sa.bInheritHandle = mode & inherit_handle ? true : false; sa.bInheritHandle = mode & inherit_handle ? true : false;
DWORD dwCreationDisposition; DWORD dwCreationDisposition;
switch (mode & mode_preserve_existing) { switch (mode & mode_disposition_mask) {
case mode_create: dwCreationDisposition = CREATE_ALWAYS; break; case mode_open_existing: dwCreationDisposition = OPEN_EXISTING; break;
case mode_truncate_existing: dwCreationDisposition = TRUNCATE_EXISTING; break;
case mode_preserve_existing: dwCreationDisposition = OPEN_ALWAYS; break; case mode_preserve_existing: dwCreationDisposition = OPEN_ALWAYS; break;
case 0: dwCreationDisposition = OPEN_EXISTING; break; case mode_create_new: dwCreationDisposition = CREATE_NEW; break;
case mode_create: dwCreationDisposition = CREATE_ALWAYS; break;
default: throw std::invalid_argument("invalid mode"); default: throw std::invalid_argument("invalid mode");
} }
@ -2495,7 +2503,14 @@ namespace stdex
case mode_for_writing: flags |= O_WRONLY; break; case mode_for_writing: flags |= O_WRONLY; break;
case mode_for_reading | mode_for_writing: flags |= O_RDWR; break; case mode_for_reading | mode_for_writing: flags |= O_RDWR; break;
} }
if (mode & mode_create) flags |= mode & mode_preserve_existing ? O_CREAT : (O_CREAT | O_EXCL); switch (mode & mode_disposition_mask) {
case mode_open_existing: break;
case mode_truncate_existing: flags |= O_TRUNC; break;
case mode_preserve_existing: flags |= O_CREAT; break;
case mode_create_new: flags |= O_CREAT | O_EXCL; break;
case mode_create: flags |= O_CREAT | O_TRUNC; break;
default: throw std::invalid_argument("invalid mode");
}
if (mode & hint_write_thru) flags |= O_DSYNC; if (mode & hint_write_thru) flags |= O_DSYNC;
#ifndef __APPLE__ #ifndef __APPLE__
if (mode & hint_no_buffering) flags |= O_RSYNC; if (mode & hint_no_buffering) flags |= O_RSYNC;