Home > Net >  What would happen with c code if you try to close stdin or stdout instead of a file?
What would happen with c code if you try to close stdin or stdout instead of a file?

Time:09-23

I am a bit confused about this question:

What would happen with c code if you would try to close stdin or stdout 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 the stream 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 the setbuf or setvbuf 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.

  •  Tags:  
  • c
  • Related