I am a bit confused about this question:
What would happen with c code if you would try to close
stdin
orstdout
instead of a file?
My guess is that the buffer will be depleted, am I right?
CodePudding user response:
The C standard does not say there is any special treatment for closing stdin
or stdout
or any special restrictions on closing them.
The documentation for fclose
in C 2018 7.21.5.1 2 says:
A successful call to the
fclose
function causes thestream
pointed to by stream to be flushed and the associated file to be closed. Any unwritten buffered data for the stream are delivered to the host environment to be written to the file; any unread buffered data are discarded. Whether or not the call succeeds, the stream is disassociated from the file and any buffer set by thesetbuf
orsetvbuf
function is disassociated from the stream (and deallocated if it was automatically allocated).
“Deplete” is not a term used in the C standard. When used about an input buffer, it refers to the program drawing data from the buffer that has been previously filled with input (such as from a user typing a line of text in a terminal) to the point where there is no data left in the buffer. Given the behavior of fclose
, the data in the buffer is discarded, not depleted.
Closing the Unix or other operating system file that is used to implement the C stream, as with close
instead of fclose
, might result in the C buffer remaining, so that further C library calls such as getchar()
will draw data from the buffer until it is depleted, after which such routines are likely to report an I/O error.
CodePudding user response:
When a program starts up, the identifiers stdin
, stdout
, and stderr
are guaranteed to hold the addresses of file objects associated with those streams. When a program terminates, an implementation will do whatever is necessary to close the streams, *but there is no guarantee that it will use the current values of stdin
, stdout
, and stderr
for that purpose.
An implementation may document that if a program does something like:
void swap_stdout(FILE *file_to_use_instead)
{
FILE *old_stdout = stdout;
stdout = file_to_use_instead;
fclose(old_stdout);
}
then the FILE
whose address was stored into stdout
will be closed when the program terminates, but absent such a specification it is possible that closing stdout
would result in the storage that had been assigned to that FILE
being reused to hold something else, and the program trying to interpret that other object as a FILE
when the program terminates.
CodePudding user response:
The stdin
and stdout
(and stderr
) objects declared by stdio.h
are specified to have type FILE *
and to initially refer to the program's standard input, standard output, and standard error streams, respectively. Roughly speaking, you can do anything with them that you can do with any other stream, including close them. After closure, they are no longer valid streams for I/O, including for those I/O functions that target them implicitly (printf
, scanf
, ...).
Therefore, if you attempt to use one of them for I/O after having closed it, you can expect that your I/O operation will fail. The specific manifestation of that depends in part on the specific function with which you attempt the I/O operation.
Note also, by the way, that the C naming of type FILE
reflects the Unix model of the world that all I/O endpoints are modeled as "files". Where you mean a persistent, named chunk of data accessible via a filesystem on a local storage device, you can use the term "regular file". Even then, it is important to distinguish between a C stream, represented by a C object of type FILE
, and the underlying data on the storage device.