Skip to content

fiopen handling of non-standard flags #2093

@FrankHB

Description

@FrankHB

The implementation strategy in https://github.com/microsoft/STL/blob/main/stl/src/fiopen.cpp is quite unnatrual, which leaves to problems for non-standard flags, even the expect behaviors are not well-documented.

What does ios_base::_Nocreate exactly mean?

By

mode |= ios_base::in; // file must exist
, ios_base::_Nocreate implies ios_base::in. But what happens for a write-only mode, i.e. ios_base::out or ios_base::app? Is it the tradition meaning of "nocreate" in this case?

TOCTTOU issue on handling io_base::_Noreplace

This one seems a real bug. Between

&& (fp = _Xfsopen(filename, 0, prot)) != nullptr) { // file must not exist, close and fail
and
if ((fp = _Xfsopen(filename, n, prot)) == nullptr) {
, if a file named by filename is created, the check is voided, so the flag is useless in this case. It looks like the same to the infamous anti-pattern of multiple calls to POSIX open to make sure the exclusive open-and-create semantics. The idiomatic correct way is using O_CREAT | O_EXCL in a single call, to enforce the atomicity.

Related implementation question

The concerned functions are implemented by the stdio extension function _fsopen. Why not use lowio (i.e. _wsopen) instead? This can easily resolve the correctness problems mentioned above, and it could be a bit more efficient due to the simpler mode translation and parsing (in the underlying implementation; once you have the implementation-specific knowledge, it seems not difficult to bypass the redundant passing like __acrt_stdio_parse_mode in _wfdopen) even if an object referenced by FILE* is still needed to be created later.

If lowio is not an appropriate choice for some coding policies I don't know, is it considerable to use C11-style "x" modes in

"r", "w", "w", "a", "rb", "wb", "wb", "ab", "r+", "w+", "a+", "r+b", "w+b", "a+b", nullptr};
?

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requestedvNextBreaks binary compatibility

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions