fseek/fgetc puzzle

Mitchell Dorrell mwd at psc.edu
Tue Feb 21 07:25:20 AEDT 2023


I get a variety of hits searching for "Be sure to call fseek before
you write", especially here: https://c-faq.com/stdio/fupdate.html ,
which might be drawn from the book referenced on the c-faq.com index
page, "C Programming FAQs: Frequently Asked Questions"
(Addison-Wesley, 1995, ISBN 0-201-84519-9).

The link mentions "ISO Sec. 7.9.5.3" presumably refers to the ISO/IEC
9899:1990 version of the C standard, which is the section, "The fopen
function". I think this section is the most pertinent:

When a file is opened with update mode (‘+’ as the second or third
character in the above list of mode argument values), both input and
output may be performed on the associated stream. However, output may
not be directly followed by input without an intervening call to the
flush function or to a file positioning function (fseek. fsetpos. or
rewind), and input may not be directly followed by output without an
intervening call to a file positioning function. unless the input
operation encounters end-of-file. Opening (or creating) a text file
with update mode may instead open (or create) a binary stream in some
implementations.

(The above excerpt may contain typos courtesy of OCR. I fixed the ones
I noticed.)


On Mon, Feb 20, 2023 at 2:53 PM Steffen Nurpmeso <steffen at sdaoden.eu> wrote:
>
> Gert Doering wrote in
>  <Y/PHnwAkzq29I9G4 at greenie.muc.de>:
>  |Hi,
>  |
>  |On Mon, Feb 20, 2023 at 08:00:24PM +0100, Steffen Nurpmeso wrote:
>  |>     Jörg Schilling however convinced me that the standard requires
>  |>     this behaviour, and it is also in the C FAQ.  Nonetheless...
>  |
>  |Do you have references for this?
>
> Hm, mail in between me and Jörg from 2017-05-02.
>
>   | |Davor kann ich nur warnen. Das stdio in Solaris geht auf die
>   | |Originalimplementierung aus der Zeit um 1976 zurück. Es ist also 40 \
>   | |Jahre alter
>   | |und auch ständig verifizierter Code.
>   |
>   |Oh, mein C++ ist auch ziemlich gut.
>   |
>   | |>|Außerdem: Nach einem read() muß man fflush() aufrufen bevor man schreiben \
>   | |>|\
>   | |>|darf
>   | |>|und umgekehrt auch.
>   | |>
>   | |> Wo steht das?  Wirklich?  Ich habe stdio nie benutzt, bis ich nail
>   | |
>   | |Das steht leider nicht im POSIX standard (das halte ich für einen Bug) \
>   | |aber es
>   | |ist im C-Standard.....
>   |
>   |Du hast mich überzeugt, in der C FAQ steht es auch.
>
> Maybe i was a bit over-forgiving as the C FAQ how i have it
> locally says
>
>   12.30:  I'm trying to update a file in place, by using fopen mode "r+",
>           reading a certain string, and writing back a modified string,
>           but it's not working.
>
>   A:      Be sure to call fseek before you write, both to seek back to the
>           beginning of the string you're trying to overwrite, and because
>           an fseek or fflush is always required between reading and
>           writing in the read/write "+" modes.  Also, remember that you
>
>   From: scs at eskimo.com (Steve Summit)
>   Newsgroups: comp.lang.c,comp.lang.c.moderated,comp.answers,news.answers
>   Subject: comp.lang.c Answers to Frequently Asked Questions (FAQ List)
>   Date: 3 Jul 2004 23:27:33 GMT
>   Organization: better late than never
>   Message-ID: <2004Jul03.1927.scs.0003 at eskimo.com>
>
>   ...
>   | |> Die Test-Suite scheint mir wirklich löchrig zu sein.
>   | |> Sag, ist das ein Fehler, oder nicht?  Und wenn ja, was mach ich
>   | |> damit?  Bräuchte das gar eine Klarstellung im Standard?
>   | |
>   | |Wie gesagt: im C-Standard steht, daß zwischen dem Ändern der I/O Richtung
>   | |fflush() zu rufen ist.
>   ...
>   | |In der Funktion, die Du erwähnst ist es aber falsch, denn da wird eben \
>   | |nicht
>   | |immer zwischen einem read und einem write fflush() gerufen.
>   | |Zwischen einem write und einem read muß es natürlich auch geschehen.Jörg
>
> I personally stand to my opinion quoted from my commit message
> "which i consider a bug in Solaris stdio", but i was talking to
> Jörg, and doing it the way he said fixed the problem.  (I have no
> idea of stdio and would only fflush after writing, say.)
> Anyhow it was no later but 2021-11-11 that i once again had to fix
> something in Jörg's spirit
>
>   commit 7b8ac94bf7cc6a97cc2c6d799cab07218e693377
>   Author:     Steffen Nurpmeso <steffen at sdaoden.eu>
>   AuthorDate: 2021-11-11 21:27:04 +0100
>   ...
>       n_folder_mbox_prepare_append(): fix it on SunOS (Jörg Schilling, RIP!)
>   ...
>   -   if((needsep && putc('\n', fout) == EOF) || fflush(fout) == EOF)
>   +   if((needsep && (fseek(fout, 0L, SEEK_END) || putc('\n', fout) == EOF)) ||
>   +         fflush(fout) == EOF)
>   ...
>
> --steffen
> |
> |Der Kragenbaer,                The moon bear,
> |der holt sich munter           he cheerfully and one by one
> |einen nach dem anderen runter  wa.ks himself off
> |(By Robert Gernhardt)
> _______________________________________________
> openssh-unix-dev mailing list
> openssh-unix-dev at mindrot.org
> https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


More information about the openssh-unix-dev mailing list