5

Is there a way for a function receiving a value of type FILE * to get the open mode used on the call to fopen() used to create the stream?

This question was motivated by the need to extend a C++ class that works as a wrapper to stdio's FILE pointers, in a way that I can clone an already open stream into a new wrapped one, while the original would continue to be used unwrapped by other parts of the program.

Under POSIX, I know that I can use fileno() to get the stream's underlying file descriptor in order to clone (dup()) it, but using the underlying descriptor's file flags would not be an exact replacement for the stream open mode, since it is possible that the stream would have stricter access restrictions than the descriptor it's bound to. So, do you have any suggestions?

Paulo1205
  • 918
  • 4
  • 9
  • 2
    There is no portable way, no. For any given implementation of the stdio library, there probably exists code of the form `if(fp->_flag & _FP_READ)` to test whether a stream is open for (say) reading, but obviously that field name `_flag` and that bitmask name `_FP_READ` are 100% completely and totally implementation-specific and nonportable. – Steve Summit Sep 06 '19 at 13:16
  • I suppose you could do some odious combination of kludges such as (a) try reading a character from the stream and (b) if it succeeds, quickly `ungetc` the character and assume the stream's open for reading, and (c) if it fails assume the stream's open for writing, but I seriously doubt that'd be reliable or a good idea. – Steve Summit Sep 06 '19 at 13:20
  • @SteveSummit Even those approaches can fail. The `FILE` structure can be opaque, and the C standard mentions that [`ungetc()` at the beginning of a binary stream is deprecated](https://port70.net/~nsz/c/c11/n1570.html#Forewordp7). Nor do I know of any similar non-destructive test for write or append mode. And the `ungetc()` test is inherently unsafe in multithreaded environments. – Andrew Henle Sep 06 '19 at 13:38
  • @AndrewHenle Of course. (But "probably exists" and "seriously doubt that'd be reliable" were less typing. :-) ) – Steve Summit Sep 06 '19 at 13:40
  • 1
    Hook `fopen()` using the ["*LD_PRELOAD trick*"](https://stackoverflow.com/questions/426230/what-is-the-ld-preload-trick)? – alk Sep 06 '19 at 14:33
  • 1
    I'm coming to realize that cloning/`dup()`ìng the stream might be less than useful, at least on Linux, since both files would share the same file pointer, preventing working on each file independently from the other. The problem would get even worse: knowing the origin of the file altogether, so that it could be opened afresh. So maybe I'll just retire that intended interface. – Paulo1205 Sep 06 '19 at 15:55

0 Answers0