fread breaks file descriptors opened in "w" mode.

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?ISO-8859-15?Q?L=E9na=EFc?= Huard

    fread breaks file descriptors opened in "w" mode.

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    Hello all,

    For some reasons, somewhere in a program, I'd like, if possible, to quickly
    parse a whole file before rewinding it and letting the full analysis start.
    My problem is that the FILE* I want do parse has been fopen'ed far away
    from where I am and I don't know in which MODE my FILE* has been opened.
    And additionally, my FILE* may not be a regular file, but a continuous
    stream (pipe), in which case it is not rewindable.

    So my program basically behaves like this:

    void PreParsing( FILE *my_file )
    {
    /*
    * Test if my FILE * is seekable
    */
    if( fseek( my_file, 0, SEEK_SET ) == 0 ) {

    /*
    * If so, go on for the pre-parsing.
    */
    //...
    fread( buf, BUF_SIZE, 1, my_file );
    //...

    /*
    * Rewind the file.
    */
    if( fseek( my_file, 0, SEEK_SET ) != 0 ) {
    // unexpected error since my FILE * was expected to be seekable.
    }
    }
    }

    * On both Linux 2.6.xx and Solaris 5.10,

    when the my_file is a regular file that has been fopen'ed with "w" as mode,
    - the first fseek returns 0 meaning success: my_file is seekable
    - the fread returns 0 meaning that there was nothing to read: expected
    since a file opened in "w" is truncated, hence is empty, and anyhow, cannot
    be read!
    - the second fseek returns 0 meaning success: my_file could be rewound.

    when the my_file is a pipe that has been fopen'ed with "w" as mode,
    - the first fseek returns -1 and errno is set to 29 (Illegal seek).
    That's exactly what I expected since a pipe cannot be sought.

    Ok. So, on Linux 2.6.xx and Solaris 5.10, my code behaves like I expected
    for both regular files and pipes.

    * On AIX 5.2,

    when the my_file is a pipe that has been fopen'ed with "w" as mode,
    - the first fseek returns -1 and errno is set to 29 (Illegal seek).
    I'm still OK with that.

    but...
    when the my_file is a regular file that has been fopen'ed with "w" as mode,
    - the first fseek returns 0 meaning success: my_file is seekable
    - the fread returns 0 meaning that there was nothing to read: expected
    since a file opened in "w" is truncated, hence is empty, and anyhow, cannot
    be read!
    - the second fseek returns -1 and sets errno to 9 (Bad file number)
    I'm a little bit surprised by this error.

    In fact, after having had a deeper look on that, it appears to me that a
    fread attempt on a FILE * opened in "w" mode breaks it since any subsequent
    operation (fseek, fwrite and even fclose !) fails with the error 9 (Bad
    file number).
    So, on AIX , my function fails to restore the FILE * state at its end.


    So, I have a few questions:

    - a fread on a FILE * opened in "w" will for sure return 0 item, but is it
    really expected that it makes the given FILE * totally unusable even for
    fclose !?! This behavior has been observed only on AIX. Linux and Solaris
    works.
    - given a FILE *, is there a better way to guess in which mode it has been
    opened than attempting to read or write it and look at errors ?
    - given a FILE *, is there a better way to guess if it can be sought than
    attempting a fseek on it ?


    PS: I Xposted my problem on both comp.lang.c and comp.unix.aix because I
    have no idea whether this is an AIX specific problem or if the C norm
    specifies explicitly that fread have unpredictable effects on a write-only
    file descriptor. Anyhow, my goal is to find a portable solution that uses
    as less platform specific stuff as possible.

    Thanks for your advices.
    Lénaïc ...still puzzled by AIX behavior...
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v2.0.9 (GNU/Linux)

    iEYEARECAAYFAkk jPpUACgkQjYEjJA TS6Bi55ACgj+Rbz OhyjDj63G+ciKo0 Iy1B
    FuoAn3WsnRc69XX Di2KV0Wt4aOFo0B pf
    =In7u
    -----END PGP SIGNATURE-----
  • vippstar@gmail.com

    #2
    Re: fread breaks file descriptors opened in "w&quot ; mode.

    On Nov 19, 12:15 am, Lénaïc Huard <lenaic.hu...@l aposte.netwrote :
    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1
    Please don't include that crap in your messages...
    Hello all,
    >
    For some reasons, somewhere in a program, I'd like, if possible, to quickly
    parse a whole file before rewinding it and letting the full analysis start.
    My problem is that the FILE* I want do parse has been fopen'ed far away
    from where I am and I don't know in which MODE my FILE* has been opened.
    Well that's a bad thing, if you want truly meaningful results you
    should enforce just one mode, binary or text.
    And additionally, my FILE* may not be a regular file, but a continuous
    stream (pipe), in which case it is not rewindable.
    Load it in memory once, and don't bother with the actual file
    rewinding.
    So my program basically behaves like this:
    >
    void PreParsing( FILE *my_file )
    {
    /*
    * Test if my FILE * is seekable
    */
    if( fseek( my_file, 0, SEEK_SET ) == 0 ) {
    That isn't testing anything really, except for that very fseek call.
    >
    /*
    * If so, go on for the pre-parsing.
    */
    //...
    fread( buf, BUF_SIZE, 1, my_file );
    I think you probably want fread(buf, 1, BUF_SIZE, my_file);
    You should also observe the return value.

    <snip observations of implementations >
    * On AIX 5.2,
    when the my_file is a regular file that has been fopen'ed with "w" as mode,
    - the first fseek returns 0 meaning success: my_file is seekable
    - the fread returns 0 meaning that there was nothing to read: expected
    since a file opened in "w" is truncated, hence is empty, and anyhow, cannot
    be read!
    - the second fseek returns -1 and sets errno to 9 (Bad file number)
    I'm a little bit surprised by this error.
    Why? That's allowed by the standard.
    In fact, after having had a deeper look on that, it appears to me that a
    fread attempt on a FILE * opened in "w" mode breaks it since any subsequent
    operation (fseek, fwrite and even fclose !) fails with the error 9 (Bad
    file number).
    So, on AIX , my function fails to restore the FILE * state at its end.
    Well, that's also allowed by the standard (it does however sound like
    your implementation has a bug)
    So, I have a few questions:
    >
    - a fread on a FILE * opened in "w" will for sure return 0 item, but is it
    really expected that it makes the given FILE * totally unusable even for
    fclose !?! This behavior has been observed only on AIX. Linux and Solaris
    works.
    The standard allows any function of the standard library to set errno
    for any reason. (there are exceptions)
    - given a FILE *, is there a better way to guess in which mode it has been
    opened than attempting to read or write it and look at errors ?
    There's no way to do that in standard C.
    - given a FILE *, is there a better way to guess if it can be sought than
    attempting a fseek on it ?
    No way in standard C.
    PS: I Xposted my problem on both comp.lang.c and comp.unix.aix because I
    have no idea whether this is an AIX specific problem or if the C norm
    specifies explicitly that fread have unpredictable effects on a write-only
    file descriptor. Anyhow, my goal is to find a portable solution that uses
    as less platform specific stuff as possible.
    Well, the standard is okay with this behavior. The implementation
    probably has a bug. It's topical in both groups I believe.

    Comment

    • Mark McIntyre

      #3
      Re: fread breaks file descriptors opened in &quot;w&quot ; mode.

      Lénaïc Huard wrote:
      -----BEGIN PGP SIGNED MESSAGE-----
      Hash: SHA1
      >
      Hello all,
      >
      For some reasons, somewhere in a program, I'd like, if possible, to quickly
      parse a whole file before rewinding it and letting the full analysis start.
      My problem is that the FILE* I want do parse has been fopen'ed far away
      from where I am and I don't know in which MODE my FILE* has been opened.
      You have a design flaw.
      And additionally, my FILE* may not be a regular file, but a continuous
      stream (pipe), in which case it is not rewindable.
      You have a second design flaw....

      <snip>
      >
      So, I have a few questions:
      >
      - a fread on a FILE * opened in "w" will for sure return 0 item, but is it
      really expected that it makes the given FILE * totally unusable even for
      fclose
      AFAIK reading from a write-only stream is undefined behaviour. Once you
      do something undefined, who knows what will happen.

      If you rip pages out of a library book, can you safely return it to the
      library?

      - given a FILE *, is there a better way to guess in which mode it has been
      opened than attempting to read or write it and look at errors ?
      Unfortunately the answer is "fix the design flaws in the programme"....
      PS: I Xposted my problem on both comp.lang.c and comp.unix.aix
      There may be AIX-specific answers to your problem but I can't comment on
      that

      Comment

      • Richard Tobin

        #4
        Re: fread breaks file descriptors opened in &quot;w&quot ; mode.

        In article <49233ea1$0$847 9$426a74cc@news .free.fr>,
        Lénaïc Huard <lenaic.huard@l aposte.netwrote :
        >For some reasons, somewhere in a program, I'd like, if possible, to quickly
        >parse a whole file before rewinding it and letting the full analysis start.
        >My problem is that the FILE* I want do parse has been fopen'ed far away
        >from where I am and I don't know in which MODE my FILE* has been opened.
        >And additionally, my FILE* may not be a regular file, but a continuous
        >stream (pipe), in which case it is not rewindable.
        I'm at a loss as to why you want to handle the case where the file
        has been opened for writing. If you want to read from a file, open
        it for reading.

        The other aspect - seekability - is entirely reasonable, but I don't
        think you can handle it in standard C. If you are (as you appear to
        be) using Posix systems, you can stat the underlying file descriptor
        and seek only if it is a regular file.

        I seem to recall using at least one system where fseek() succeeded
        even on pipes provided the seek was within the existing stdio buffer,
        so just because one fseek() succeeds, it doesn't mean others will.

        -- Richard
        --
        Please remember to mention me / in tapes you leave behind.

        Comment

        • vippstar@gmail.com

          #5
          Re: fread breaks file descriptors opened in &quot;w&quot ; mode.

          On Nov 19, 12:43 am, Mark McIntyre <markmcint...@T ROUSERSspamcop. net>
          wrote:
          <snip>
          AFAIK reading from a write-only stream is undefined behaviour.
          I've recently asked this (or remember asking it), but I believe I
          received no answers.
          I've also searched the standard for the answer, with no luck. Anyone?

          Comment

          • =?ISO-8859-15?Q?L=E9na=EFc?= Huard

            #6
            Re: fread breaks file descriptors opened in &quot;w&quot ; mode.

            vippstar@gmail. com a écrit :
            >My problem is that the FILE* I want do parse has been
            >fopen'ed far away from where I am and I don't know in which MODE my FILE*
            >has been opened.
            >
            Well that's a bad thing, if you want truly meaningful results you
            should enforce just one mode, binary or text.
            Sorry, I wasn't clear enough. My problem is not between binary or text. I
            deal only with binary files. The problem is between read or write.

            I want to write a kind of « decorator » around a FILE *. And the constructor
            of that decorator should parse the file is possible (i.e. if it is a
            regular file opened for reading). But unfortunately, I don't know whether
            those conditions are met when the constructor is invoked.
            >And additionally, my FILE* may not be a regular file, but a continuous
            >stream (pipe), in which case it is not rewindable.
            >
            Load it in memory once, and don't bother with the actual file
            rewinding.
            But sometimes, this piece of code is used in programs working on continuous
            streams. The data must me processed as they come. We can't wait for the
            last item before starting to process the first one. And when used in this
            context, the total amount of data that will have been read at the end of
            the program is too big to fit into memory.
            I would like to be able to detect such contexts and to skip the initial
            parsing in those cases.
            And of course, as I believe in Santa Claus, I try to do this without
            modifying the prototypes of a lot of functions to add a read vs. write
            information.
            >So my program basically behaves like this:
            >>
            >void PreParsing( FILE *my_file )
            >{
            > /*
            > * Test if my FILE * is seekable
            > */
            > if( fseek( my_file, 0, SEEK_SET ) == 0 ) {
            >
            That isn't testing anything really, except for that very fseek call.
            Indeed, but this was already a workaround. My initial wish was to know
            whether I have a chance that the second fseek works or if there is no
            chance. In my case, this is nearly equivalent to know whether FILE * is a
            regular file or a pipe.
            But... I realize that may be such question ought to be put in
            comp.unix.progr ammer instead...
            >>
            > /*
            > * If so, go on for the pre-parsing.
            > */
            > //...
            > fread( buf, BUF_SIZE, 1, my_file );
            >
            I think you probably want fread(buf, 1, BUF_SIZE, my_file);
            You should also observe the return value.
            Indeed. Sorry, the real program is better and checks the return. Promise!
            >* On AIX 5.2,
            >when the my_file is a regular file that has been fopen'ed with "w" as
            >mode,
            > - the first fseek returns 0 meaning success: my_file is seekable
            > - the fread returns 0 meaning that there was nothing to read: expected
            >since a file opened in "w" is truncated, hence is empty, and anyhow,
            >cannot be read!
            > - the second fseek returns -1 and sets errno to 9 (Bad file number)
            >I'm a little bit surprised by this error.
            >
            Why? That's allowed by the standard.
            I have no problem with the fact that fseek returns an error. But the kind of
            error make me feel that the fread didn't simply return 0 item, it also
            closed the file descriptor. Further in the program, fclose also issues an
            EBADF (Bad file number) error.

            My concern is not « fseek shouldn't fail ». It's more : « Should fread
            executed on an un-readable stream just return an error or is its behavior
            completely undefined (including closing the file descriptor, corrupting
            memory, crashing or potentially anything else.) »
            >In fact, after having had a deeper look on that, it appears to me that a
            >fread attempt on a FILE * opened in "w" mode breaks it since any
            >subsequent operation (fseek, fwrite and even fclose !) fails with the
            >error 9 (Bad file number).
            >So, on AIX , my function fails to restore the FILE * state at its end.
            >
            Well, that's also allowed by the standard (it does however sound like
            your implementation has a bug)
            >
            The standard allows any function of the standard library to set errno
            for any reason. (there are exceptions)
            I understand your point: the standard library functions can, according to
            the standard, legally fail at any call and return an appropriate error.
            But I would expect that any illegal operation (like reading an un-readable
            stream) would return an error, set the errno, and leave the stream
            un-modified. And instead of this, I have the feeling that my file
            descriptor is closed.

            Comment

            • =?ISO-8859-15?Q?L=E9na=EFc?= Huard

              #7
              Re: fread breaks file descriptors opened in &quot;w&quot ; mode.

              Richard Tobin a écrit :
              The other aspect - seekability - is entirely reasonable, but I don't
              think you can handle it in standard C. If you are (as you appear to
              be) using Posix systems, you can stat the underlying file descriptor
              and seek only if it is a regular file.
              Sounds to be exactly what I was looking for... I'm still wondering why I
              didn't think about stat before.
              Thanks!
              I seem to recall using at least one system where fseek() succeeded
              even on pipes provided the seek was within the existing stdio buffer,
              so just because one fseek() succeeds, it doesn't mean others will.
              Sounds to be an excellent reason for not testing the seekability with fseek!

              Comment

              • jameskuyper

                #8
                Re: fread breaks file descriptors opened in &quot;w&quot ; mode.

                Lénaïc Huard wrote:
                vippstar@gmail. com a �crit :
                >
                My problem is that the FILE* I want do parse has been
                fopen'ed far away from where I am and I don't know in which MODE my FILE*
                has been opened.
                Well that's a bad thing, if you want truly meaningful results you
                should enforce just one mode, binary or text.
                >
                Sorry, I wasn't clear enough. My problem is not between binary or text. I
                deal only with binary files. The problem is between read or write.
                If you don't know whether a given file has been opened for reading or
                writing, you need to re-design your code so that you do know.
                I want to write a kind of � decorator � around a FILE *. And the constructor
                of that decorator should parse the file is possible (i.e. if it is a
                regular file opened for reading). But unfortunately, I don't know whether
                those conditions are met when the constructor is invoked.
                C doesn't have constructors. Are you actually working in C++? in that
                case your question should be re-directed to comp.lang.c++.

                ....
                And of course, as I believe in Santa Claus, I try to do this without
                modifying the prototypes of a lot of functions to add a read vs. write
                information.
                Well, I don't see what Santa has to do with that, but if there's some
                legitimate reason why the most obvious fix is s unacceptable, you'll
                need to find some other way of passing the information around. One
                option is to create a structure with at least two members: a FILE *
                and something that keeps track of what mode the file was opened in.

                Comment

                • bennett.tony@con-way.com

                  #9
                  Re: fread breaks file descriptors opened in &quot;w&quot ; mode.

                  On Nov 18, 2:15 pm, Lénaïc Huard <lenaic.hu...@l aposte.netwrote :
                  -----BEGIN PGP SIGNED MESSAGE-----
                  Hash: SHA1
                  >
                  Hello all,
                  >
                  For some reasons, somewhere in a program, I'd like, if possible, to quickly
                  parse a whole file before rewinding it and letting the full analysis start.
                  My problem is that the FILE* I want do parse has been fopen'ed far away
                  from where I am and I don't know in which MODE my FILE* has been opened.
                  And additionally, my FILE* may not be a regular file, but a continuous
                  stream (pipe), in which case it is not rewindable.
                  >
                  So my program basically behaves like this:
                  >
                  void PreParsing( FILE *my_file )
                  {
                    /*
                     * Test if my FILE * is seekable
                     */
                    if( fseek( my_file, 0, SEEK_SET ) == 0 ) {
                  >
                      /*
                       * If so, go on for the pre-parsing.
                       */
                      //...
                      fread( buf, BUF_SIZE, 1, my_file );
                      //...
                  >
                      /*
                       * Rewind the file.
                       */
                      if( fseek( my_file, 0, SEEK_SET ) != 0 ) {
                        // unexpected error since my FILE * was expected to be seekable.
                      }
                    }
                  >
                  }
                  >
                  * On both Linux 2.6.xx and Solaris 5.10,
                  >
                  when the my_file is a regular file that has been fopen'ed with "w" as mode,
                   - the first fseek returns 0 meaning success: my_file is seekable
                   - the fread returns 0 meaning that there was nothing to read: expected
                  since a file opened in "w" is truncated, hence is empty, and anyhow, cannot
                  be read!
                   - the second fseek returns 0 meaning success: my_file could be rewound..
                  >
                  when the my_file is a pipe that has been fopen'ed with "w" as mode,
                   - the first fseek returns -1 and errno is set to 29 (Illegal seek).
                  That's exactly what I expected since a pipe cannot be sought.
                  >
                  Ok. So, on Linux 2.6.xx and Solaris 5.10, my code behaves like I expected
                  for both regular files and pipes.
                  >
                  * On AIX 5.2,
                  >
                  when the my_file is a pipe that has been fopen'ed with "w" as mode,
                   - the first fseek returns -1 and errno is set to 29 (Illegal seek).
                  I'm still OK with that.
                  >
                  but...
                  when the my_file is a regular file that has been fopen'ed with "w" as mode,
                   - the first fseek returns 0 meaning success: my_file is seekable
                   - the fread returns 0 meaning that there was nothing to read: expected
                  since a file opened in "w" is truncated, hence is empty, and anyhow, cannot
                  be read!
                   - the second fseek returns -1 and sets errno to 9 (Bad file number)
                  I'm a little bit surprised by this error.
                  >
                  In fact, after having had a deeper look on that, it appears to me that a
                  fread attempt on a FILE * opened in "w" mode breaks it since any subsequent
                  operation (fseek, fwrite and even fclose !) fails with the error 9 (Bad
                  file number).
                  So, on AIX , my function fails to restore the FILE * state at its end.
                  >
                  So, I have a few questions:
                  >
                   - a fread on a FILE * opened in "w" will for sure return 0 item, but is it
                  really expected that it makes the given FILE * totally unusable even for
                  fclose !?! This behavior has been observed only on AIX. Linux and Solaris
                  works.
                   - given a FILE *, is there a better way to guess in which mode it has been
                  opened than attempting to read or write it and look at errors ?
                   - given a FILE *, is there a better way to guess if it can be sought than
                  attempting a fseek on it ?
                  >
                  PS: I Xposted my problem on both comp.lang.c and comp.unix.aix because I
                  have no idea whether this is an AIX specific problem or if the C norm
                  specifies explicitly that fread have unpredictable effects on a write-only
                  file descriptor. Anyhow, my goal is to find a portable solution that uses
                  as less platform specific stuff as possible.
                  >
                  Thanks for your advices.
                  Lénaïc ...still puzzled by AIX behavior...
                  -----BEGIN PGP SIGNATURE-----
                  Version: GnuPG v2.0.9 (GNU/Linux)
                  >
                  iEYEARECAAYFAkk jPpUACgkQjYEjJA TS6Bi55ACgj+Rbz OhyjDj63G+ciKo0 Iy1B
                  FuoAn3WsnRc69XX Di2KV0Wt4aOFo0B pf
                  =In7u
                  -----END PGP SIGNATURE-----
                  Partial solution - you can discover if it is a PIPE or a Special
                  Device
                  by doing a "stat" on it and checking the
                  mode:

                  Passed in as a parm: FILE *fp;

                  struct stat my_stat;
                  mode_t the_type;

                  fstat ( fileno(fp), &my_stat);

                  /* apply mask to get just file_type */
                  the_type = (my_stat.st_mod e & _S_IFMT )

                  if ( the_type == _S_IFIFO ) {
                  printf("Its a pipe\n");
                  }else{
                  if ( the_type == _S_IFBLK ) {
                  printf("It is a Block Special device\n");
                  }else{
                  if ( the_type == _S_IFCHR ) {
                  printf("It is a Character Special device\n");
                  ....... etc....

                  -tony

                  Comment

                  • Martien Verbruggen

                    #10
                    Re: fread breaks file descriptors opened in &quot;w&quot ; mode.

                    On Tue, 18 Nov 2008 17:14:21 -0800 (PST),
                    bennett.tony@co n-way.com <bennett.tony@c on-way.comwrote:
                    On Nov 18, 2:15 pm, Lénaïc Huard <lenaic.hu...@l aposte.netwrote :
                    >For some reasons, somewhere in a program, I'd like, if possible, to quickly
                    >parse a whole file before rewinding it and letting the full analysis start.
                    >My problem is that the FILE* I want do parse has been fopen'ed far away
                    >from where I am and I don't know in which MODE my FILE* has been opened.
                    >And additionally, my FILE* may not be a regular file, but a continuous
                    >stream (pipe), in which case it is not rewindable.
                    Partial solution - you can discover if it is a PIPE or a Special
                    Device
                    by doing a "stat" on it and checking the
                    mode:
                    [snip code using fstat() and its associated macros]

                    Of course, this is not standard C, but POSIX. If you are indeed using a
                    POSIX or POSIX-like system, and you want to use that API, you
                    should probably be discussing this in comp.unix.progr ammer, as the
                    people there tend to know a lot more about POSIX, on average, than the
                    people here.

                    Martien
                    --
                    |
                    Martien Verbruggen | This matter is best disposed of from a great
                    | height, over water.
                    |

                    Comment

                    • CBFalconer

                      #11
                      Re: fread breaks file descriptors opened in &quot;w&quot ; mode.

                      Lénaïc Huard wrote:
                      Richard Tobin a écrit :
                      >
                      >The other aspect - seekability - is entirely reasonable, but I
                      >don't think you can handle it in standard C. If you are (as you
                      >appear to be) using Posix systems, you can stat the underlying
                      >file descriptor and seek only if it is a regular file.
                      >
                      Sounds to be exactly what I was looking for. I'm still
                      wondering why I didn't think about stat before. Thanks!
                      >
                      >I seem to recall using at least one system where fseek()
                      >succeeded even on pipes provided the seek was within the
                      >existing stdio buffer, so just because one fseek() succeeds,
                      >it doesn't mean others will.
                      >
                      Sounds to be an excellent reason for not testing the seekability
                      with fseek!
                      And it is entirely off-topic on c.l.c, so all such answers are
                      necessarily suspect. If you ask on comp.unix.progr ammer, however,
                      you will probably be on-target and get valid answers and criticisms
                      of those answers.

                      As an aside, if a file is opened in "w" mode, you can't do many
                      things to it. Read the C standard.

                      --
                      [mail]: Chuck F (cbfalconer at maineline dot net)
                      [page]: <http://cbfalconer.home .att.net>
                      Try the download section.

                      Comment

                      • lawrence.jones@siemens.com

                        #12
                        Re: fread breaks file descriptors opened in &quot;w&quot ; mode.

                        vippstar@gmail. com wrote:
                        On Nov 19, 12:43 am, Mark McIntyre <markmcint...@T ROUSERSspamcop. net>
                        wrote:
                        <snip>
                        AFAIK reading from a write-only stream is undefined behaviour.
                        >
                        I've recently asked this (or remember asking it), but I believe I
                        received no answers.
                        I've also searched the standard for the answer, with no luck. Anyone?
                        It's undefined behavior by virture of the fact that all I/O takes place
                        as if by calls to fgetc() and fputc(), and their behavior is only
                        defined for input and output streams, respectively.
                        --
                        Larry Jones

                        Talk about someone easy to exploit! -- Calvin

                        Comment

                        • vippstar@gmail.com

                          #13
                          Re: fread breaks file descriptors opened in &quot;w&quot ; mode.

                          On Nov 19, 8:50 pm, lawrence.jo...@ siemens.com wrote:
                          vipps...@gmail. com wrote:
                          On Nov 19, 12:43 am, Mark McIntyre <markmcint...@T ROUSERSspamcop. net>
                          wrote:
                          <snip>
                          AFAIK reading from a write-only stream is undefined behaviour.
                          >
                          I've recently asked this (or remember asking it), but I believe I
                          received no answers.
                          I've also searched the standard for the answer, with no luck. Anyone?
                          >
                          It's undefined behavior by virture of the fact that all I/O takes place
                          as if by calls to fgetc() and fputc(), and their behavior is only
                          defined for input and output streams, respectively.
                          Ah, I suspected something like that. Thanks!

                          Comment

                          • Gary R. Hook

                            #14
                            Re: fread breaks file descriptors opened in &quot;w&quot ; mode.

                            Lénaïc Huard wrote:
                            So, I have a few questions:
                            >
                            - a fread on a FILE * opened in "w" will for sure return 0 item, but is it
                            really expected that it makes the given FILE * totally unusable even for
                            fclose !?! This behavior has been observed only on AIX. Linux and Solaris
                            works.
                            - given a FILE *, is there a better way to guess in which mode it has been
                            opened than attempting to read or write it and look at errors ?
                            Once you've eliminated the pipe possibility, dup() the descriptor and
                            fdopen() the duplicate in r-w mode. Close the old one.

                            You shouldn't be attempting to read from a stream opened for writing.
                            That makes no sense and getting undefined, inconsistent results seems
                            reasonable.

                            Comment

                            • Keith Thompson

                              #15
                              Re: fread breaks file descriptors opened in &quot;w&quot ; mode.

                              "Gary R. Hook" <ghook@no.spamm ers.netwrites:
                              Lénaïc Huard wrote:
                              >
                              >So, I have a few questions:
                              > - a fread on a FILE * opened in "w" will for sure return 0 item,
                              >but is it
                              >really expected that it makes the given FILE * totally unusable even for
                              >fclose !?! This behavior has been observed only on AIX. Linux and Solaris
                              >works.
                              > - given a FILE *, is there a better way to guess in which mode it has been
                              >opened than attempting to read or write it and look at errors ?
                              There's no portable way to do it.
                              Once you've eliminated the pipe possibility, dup() the descriptor and
                              fdopen() the duplicate in r-w mode. Close the old one.
                              dup() and fdopen() are defined by POSIX. Using them is ok as long as
                              you don't mind limiting your code's portability to POSIX
                              implementations .
                              You shouldn't be attempting to read from a stream opened for
                              writing. That makes no sense and getting undefined, inconsistent
                              results seems reasonable.
                              Right, reading from a file opened in "w" mode invokes undefined
                              behavior.

                              --
                              Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                              Nokia
                              "We must do something. This is something. Therefore, we must do this."
                              -- Antony Jay and Jonathan Lynn, "Yes Minister"

                              Comment

                              Working...