Adding some rationale on this topic, the iostream constructors lack functionality available when opening file descriptors.  For example open(2) has flags such as O_EXCL, O_TMPFILE.  The file descriptor could also be created via calls such as mkstemp(3), pipe(2), accept(2).  It would be useful to take ownership of file descriptors via iostreams to gain access to its capabilities and reduce risk of file descriptor leaks or double closes via RAII.

Looking at std::format [C++20], it outputs strings.  std::print [C++23], outputs to FILE*.  Does this suggest iostream gets sidelined and FILE* becomes more preferable?  If so, we'd revert to fdopen and use workarounds such as unique_ptr with a custom deleter to ensure safe closes.

On Fri, Sep 2, 2022 at 11:32 AM Peter C++ via Std-Proposals <std-proposals@lists.isocpp.org> wrote:


I think it is doable and desirable. i even was of the impression it would already work,but at least not as of what is in the std.

issues:
- too few people understand iostreams ( i am one of the few who contributed over the last few revisions)
Great, I've come to the right place to discuss this proposal!
 
- ownership-transfer of an int ( ope. file descriptor) could only by convention
Yes, no type safety with int file descriptors, hence the desire to have them consumed into a safer type (std::iostream).

- on linux there is a workaround
- should adoption also work from a FILE*?
Adopting a file descriptor is straightforward since there's no buffered data.  Adopting a FILE* would be more complex.  For example there could be buffered, unwritten data.  Should it be flushed upon construction of the iostream object or should the buffered data be adopted into the iostreams buffers?  I'd suggest only adopting file descriptors (for now).
 
- can there be destruction without close?
iostream offers close without destruction, but on destruction if it owns an open file, then it closes it.   With the proposed iostream equivalent of fdopen, once the object is constructed, it would be no different than one constructed via today's set of constructors.  Hence I'd suggest it owns the file descriptor until .close() or destructed.  One could consider the addition of a .release() member function that relinquishes ownership and returns the file descriptor, however I would avoid that since not all iostream objects would have an internal file descriptor (e.g. on non-POSIX platforms).



Sent from Peter Sommerlad's iPad
+41 79 432 23 32

On 2 Sep 2022, at 11:37, Paul Fee via Std-Proposals <std-proposals@lists.isocpp.org> wrote:


Hello,

POSIX defines fdopen(), which takes ownership of a low level file descriptor and returns a FILE* with which a user can perform buffered I/O.  There doesn't appear to be a similar feature in C++, though non-standard workarounds exist, such as __gnu_cxx::stdio_filebuf.


Are there issues that would block standardisation of such a facility?  Perhaps it's because fdopen() is part of POSIX rather than ISO C, hence file descriptors themselves may not be universally portable.  Does that in turn mean that the standard library can't provide functionality that depends on a POSIX feature?  Would it be feasible to provide this feature only on platforms where file descriptors exist?

Thanks,
Paul
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals