X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f X-Recipient: djgpp-workers AT delorie DOT com Message-ID: <51E9D758.8000209@gmx.de> Date: Sat, 20 Jul 2013 02:18:32 +0200 From: Juan Manuel Guerrero User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:16.0) Gecko/20121025 Thunderbird/16.0.2 MIME-Version: 1.0 To: djgpp-workers AT delorie DOT com Subject: Re: Set _IOERR if the file stream has been opened in wrong mode. References: <51E5D0C6 DOT 1060404 AT gmx DOT de> <83y5951a79 DOT fsf AT gnu DOT org> <51E702E0 DOT 3010809 AT gmx DOT de> <83fvvc1t0x DOT fsf AT gnu DOT org> <8738rcsdik DOT fsf AT uwakimon DOT sk DOT tsukuba DOT ac DOT jp> <201307180459 DOT r6I4xWxV010383 AT envy DOT delorie DOT com> In-Reply-To: <201307180459.r6I4xWxV010383@envy.delorie.com> Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit X-Provags-ID: V03:K0:NV5p+pDwDRlJhwI569Z322uvx/ESh646iPECEnJ83mXHJJUKuuU TCPr6RPAx385cyDKTKkGl9zKdrHKC5gydjhb42bXWUG0hhtZGVeHgsUxbmCgpOyWm3MF78p 2YDP4iiDEDTM/nj52DxlMkX41F23/DbNhDstbLXfvH9Cvpeuzc+6eWI67qjJHb7a3prk4mx C74Nde+ok2iAIU/7NbEJw== Reply-To: djgpp-workers AT delorie DOT com Am 18.07.2013 06:59, schrieb DJ Delorie: >> man pages. IIRC, DJGPP libc is derived from BSD to avoid (L)GPL >> implications of merely using the compilation suite, so BSD man pages >> should be considered carefully, if not as authoritative. > V1 was bsd-derived. V2 was written from scratch using the ANSI and > POSIX specs as references. > > I looked in the code and didn't see anything where we specifically set > the error flag, other than read() failing. So, it looks like this is > a DOS thing - that file just isn't readable. > > But I couldn't find anything in the posix/ansi specs that said what > conditions cause errors, just that if errors happen ferror() says so. Only for the record: File is empty. Reading from file (stream) using either fread or fgets | fopen("foobar", "w") | ferror | feof -------+----------------------+--------+------ cygwin | reading from file | TRUE | FALSE -------+----------------------+--------+------ linux | reading from file | TRUE | FALSE -------+----------------------+--------+------ mingw | reading from file | TRUE | FALSE -------+----------------------+--------+------ pcbsd | reading from file | TRUE | FALSE -------+----------------------+--------+------ djgpp | reading from file | FALSE | FALSE | fopen("foobar", "r") | ferror | feof -------+----------------------+--------+------ cygwin | reading from file | FALSE | TRUE -------+----------------------+--------+------ linux | reading from file | FALSE | TRUE -------+----------------------+--------+------ mingw | reading from file | FALSE | TRUE -------+----------------------+--------+------ pcbsd | reading from file | FALSE | TRUE -------+----------------------+--------+------ djgpp | reading from file | FALSE | TRUE File is empty. Writing to file (stream) using either fwrite or fputs | fopen("foobar", "r") | ferror | feof -------+----------------------+--------+------ cygwin | writing to file | TRUE | FALSE -------+----------------------+--------+------ linux | writing to file | TRUE | FALSE -------+----------------------+--------+------ mingw | writing to file | TRUE | FALSE -------+----------------------+--------+------ pcbsd | writing to file | TRUE | FALSE -------+----------------------+--------+------ djgpp | writing to file | FALSE | FALSE IMHO, with this evidence it can taken for granted that for the C programing community that uses one of the above enumerated systems, this behavior no longer is a bug but a feature no matter if mandated or not by a standard and it is a matter of fact that some coders already exploit this feature in their code. (No offending intention here). I do not have access to other posix or bsd-like systems. These are all checks I can do. As can be seen djgpp sets _IOEOF were appropriate and this can be checked using feof() but it does not set _IOERR under the conditions described in previous mails. Below there is a new small patch that fixes the issue as suggested, this time in _filbuf for fread an fgets and in _flsbuf for fwrite and fputs. Concerning the patch, suggestions, objections, comments and improvements are always welcome. If I get no positive response or any response at all, I will not insiste in this issue anymore and assume that it is prefered to keep the current behavior of the library. Regards, Juan M. Guerrero diff -aprNU3 djgpp.orig/src/docs/kb/wc204.txi djgpp/src/docs/kb/wc204.txi --- djgpp.orig/src/docs/kb/wc204.txi 2013-03-23 11:54:58 +0000 +++ djgpp/src/docs/kb/wc204.txi 2013-07-20 00:11:48 +0000 @@ -1289,3 +1289,11 @@ members of @code{struct rlimit}. The @acronym{C99} macros @code{isfinite}, @code{isinf}, @code{isnan}, @code{isnormal}, @code{isgreater}, @code{isgreaterequal}, @code{isless}, @code{islessequal}, @code{islessgreater} and @code{isunordered} were added to comply with the @acronym{C99} standard. + +@findex fread AT r{, and setting @code{_flag} to @code{_IOERR} if stream has been opened with wrong mode} +@findex fwrite AT r{, and setting @code{_flag} to @code{_IOERR} if stream has been opened with wrong mode} +@findex fgets AT r{, and setting @code{_flag} to @code{_IOERR} if stream has been opened with wrong mode} +@findex fputs AT r{, and setting @code{_flag} to @code{_IOERR} if stream has been opened with wrong mode} +@code{fread}, @code{fwrite}, @code{fgets} and @code{fputs} now check that the file stream has +been opened in correct mode. If it is the wrong mode the file stream @code{_flag} flag will +be set to @code{_IOERR} before aborting the operation. diff -aprNU3 djgpp.orig/src/libc/ansi/stdio/filbuf.c djgpp/src/libc/ansi/stdio/filbuf.c --- djgpp.orig/src/libc/ansi/stdio/filbuf.c 2013-07-16 18:00:12 +0000 +++ djgpp/src/libc/ansi/stdio/filbuf.c 2013-07-20 00:01:26 +0000 @@ -37,7 +37,11 @@ _filbuf(FILE *f) f->_flag |= _IOREAD; if (!(f->_flag & _IOREAD)) + { + f->_flag |= _IOERR; return EOF; + } + if (f->_flag & (_IOSTRG | _IOEOF)) return EOF; f->_flag &= ~_IOUNGETC; diff -aprNU3 djgpp.orig/src/libc/ansi/stdio/flsbuf.c djgpp/src/libc/ansi/stdio/flsbuf.c --- djgpp.orig/src/libc/ansi/stdio/flsbuf.c 2013-07-16 18:00:14 +0000 +++ djgpp/src/libc/ansi/stdio/flsbuf.c 2013-07-20 00:01:18 +0000 @@ -31,7 +31,10 @@ _flsbuf(int c, FILE *f) } if (!(f->_flag & _IOWRT)) + { + f->_flag |= _IOERR; return EOF; + } /* No-op for full string buffers */ if (f->_flag & _IOSTRG)