Skip to content

Commit 6edbbd0

Browse files
committed
Change file open for posix-win equivalence (random and _SH_DENYWR).
1 parent 566e769 commit 6edbbd0

File tree

1 file changed

+39
-8
lines changed

1 file changed

+39
-8
lines changed

src/file/utilities.cpp

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -244,20 +244,51 @@ code copy_directory_ex(const path& from, const path& to) NOEXCEPT
244244

245245
int open(const path& filename) NOEXCEPT
246246
{
247+
// TODO: provide as parameter for random vs. sequential accesss.
248+
auto random{ true };
249+
247250
const auto path = system::to_extended_path(filename);
248251
int file_descriptor{};
249252

250-
// _wsopen_s and open set errno on failure.
251-
// _wsopen_s and wstring do not throw (but are unannotated).
252253
#if defined(HAVE_MSC)
253-
// sets file_descriptor = -1 on error.
254-
_wsopen_s(&file_descriptor, path.c_str(),
255-
O_RDWR | _O_BINARY | _O_RANDOM, _SH_DENYWR, _S_IREAD | _S_IWRITE);
254+
// _wsopen_s and wstring do not throw (but are unannotated).
255+
// sets file_descriptor = -1 and errno on error.
256+
::_wsopen_s(&file_descriptor, path.c_str(),
257+
O_RDWR | _O_BINARY | (random ? _O_RANDOM : _O_SEQUENTIAL),
258+
_SH_DENYWR, _S_IREAD | _S_IWRITE);
256259
#else
257-
// returns -1 on failure.
258-
file_descriptor = ::open(path.c_str(),
259-
O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
260+
// open sets errno on failure.
261+
file_descriptor = ::open(path.c_str(), O_RDWR, S_IRUSR | S_IWUSR);
262+
if (file_descriptor != -1)
263+
{
264+
// _O_RANDOM equivalent, posix_fadvise returns error on failure.
265+
const auto advice = random ? POSIX_FADV_RANDOM : POSIX_FADV_SEQUENTIAL;
266+
const auto result = ::posix_fadvise(file_descriptor, 0, 0, advice);
267+
if (!is_zero(result))
268+
{
269+
close(file_descriptor);
270+
file_descriptor = -1;
271+
errno = result;
272+
}
273+
else
274+
{
275+
// _SH_DENYWR equivalent.
276+
const struct flock lock
277+
{
278+
.l_type = F_WRLCK, .l_whence = SEEK_SET, .l_start = 0, .l_len = 0
279+
};
280+
281+
if (::fcntl(file_descriptor, F_SETLK, &lock) == -1)
282+
{
283+
const auto last = errno;
284+
close(file_descriptor);
285+
file_descriptor = -1;
286+
errno = last;
287+
}
288+
}
289+
}
260290
#endif
291+
261292
return file_descriptor;
262293
}
263294

0 commit comments

Comments
 (0)