Messages in this thread | | | Date | Fri, 14 Jul 2000 13:25:06 -0400 (EDT) | From | "Richard B. Johnson" <> | Subject | Closing the FILE object. |
| |
This is in reference to the reported seg-faults when attempting to fclose() an invalid file pointer.
The following shows that my current 'C' runtime library does not adhere to any known standard when referencing the FILE object during fclose(). This is gcc 2.7.2.3 (libc 5.3.12)
According to existing Linux documentation, this should return EBADF. It should NOT seg-fault.
#include <stdio.h> #include <malloc.h>
int main () { FILE *fp; fp = (FILE *)malloc(sizeof(FILE));/* Make sure the pointer is valid */ fprintf(stderr, "%p\n", fp); /* Display valid address */ fclose(fp); puts("It worked??"); /* Will not occur */ return 0; }
Script started on Fri Jul 14 12:50:27 2000 $$$ man fclose FCLOSE(3) Linux Programmer's Manual FCLOSE(3)
NAME fclose - close a stream
SYNOPSIS #include <stdio.h>
int fclose( FILE *stream);
DESCRIPTION The fclose function dissociates the named stream from its underlying file or set of functions. If the stream was being used for output, any buffered data is written first, using fflush(3).
RETURN VALUES Upon successful completion 0 is returned. Otherwise, EOF is returned and the global variable errno is set to indi- cate the error. In either case no further access to the stream is possible.
ERRORS line 1 EBADF The argument stream is not an open stream. line 4 The fclose function may also fail and set errno for any of the errors specified for the routines close(2) or fflush(3).
SEE ALSO close(2), fflush(3), fopen(3), setbuf(3)
STANDARDS The fclose function conforms to ANSI C3.159-1989 (``ANSI C'').
BSD MANPAGE 29 November 1993 1
line 19/66 (END)# exit exit
Script done on Fri Jul 14 12:50:47 2000
I reported a similar problem several years ago when I way trying to substitute during runtime, a FILE pointer obtained from a fopen() and the default FILE pointer(s) of stdin, stdout, stderr. In other words, if the program didn't have a terminal, stdout and stderr would go to a file.
Because the FILE *object didn't work as a real pointer, I could not do: FILE *fp;
fp = fopen("filename", "w"); fflush(stdout); fflush(stderr); stdout = fp; stderr = fp;
The next write to stdout would segfault. This behavior was never seen on any other Unix system, including Ultrix and Sun(s). In fact, the interplay of the FILE object was a feature of Unix 'C' programming.
In the example above, I could have saved the original FILE *, and restored it later in the program. With Linux, you can't even compile such a program because the assignments will result in 'invalid lvalue' errors. This is because Linux libc's stdout is not a FILE * at all!
This breaks compatability rules because, for instance fprintf() takes, as it's first parameter, a pointer of type FILE.
So we have the case of fprintf(stderr, ...) compiling and working because stderr is a FILE pointer, but I can't make a legal assignment to it like any other FILE pointers.
Go figure.
Cheers, Dick Johnson
Penguin : Linux version 2.2.15 on an i686 machine (797.90 BogoMips).
"Memory is like gasoline. You use it up when you are running. Of course you get it all back when you reboot..."; Actual explanation obtained from the Micro$oft help desk.
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |