Re: Closing the FILE object.

From: Igmar Palsenberg (maillist@chello.nl)
Date: Sun Jul 16 2000 - 20:53:09 EST


On Fri, 14 Jul 2000, Richard B. Johnson wrote:

>
> 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.

Read again, get some coffee, and read it again :-))(

'EBADF The argument steam is not an open stream'

The code below provides a valid pointer, NOT a valid stream.
 
> #include <stdio.h>
> #include <malloc.h>
>
> int main ()
> {
> FILE *fp;
> fp = (FILE *)malloc(sizeof(FILE));/* Make sure the pointer is valid */
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

      Totally bogus. Makes a valid pointer, not a valid filestream what
fclose() requires.

> fprintf(stderr, "%p\n", fp); /* Display valid address */
> fclose(fp);
> puts("It worked??"); /* Will not occur */
> return 0;
> }
>
> 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.

This indeed didn't work on old libc's. It compiles fine here (2.1.3)

> Go figure.
>
> Cheers,
> Dick Johnson

        Regards,

                
                Igmar

-
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/



This archive was generated by hypermail 2b29 : Sun Jul 23 2000 - 21:00:08 EST