fseek/fgetc puzzle

Darren Tucker dtucker at dtucker.net
Mon Feb 20 21:44:41 AEDT 2023


On Mon, 20 Feb 2023 at 21:03, John-Mark Gurney <jmg at funkthat.com> wrote:
[...]
> Can you check the return value of fseek to see if it's non-zero?  It
> should be zero if successful, but likely non-zero on the failing
> systems.

The fseek returns zero.  The real code[0] checks this and other return
values, but I omitted the check in the test case for brevity (and to
make it easier to truss/strace).

> I decided to check the C standard for fseek's behavior, and it looks
> like SEEK_END is not specified on text streams, only binary streams
> (at least in C99 and C2X).
>
> For text streams, this is what it says is supported (C99 7.19.9.2):
> For a text stream, either offset shall be zero, or offset shall be a
> value returned by an earlier successful call to the ftell function on
> a stream associated with the same file and whence shall be SEEK_SET.

In at least the Solaris man page that language seems to only refer to
use with wide characters:

"""
       If the stream is to be used with wide character input/output functions,
       offset must either be 0 or a value  returned  by  an  earlier  call  to
       ftell(3C) on the same stream and whence must be SEEK_SET.
"""

> Does it work if you open the file in binary mode?  a+b or r+b?

Same behaviour as before with both.

$ cat test.c
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
        FILE *f = fopen("testfile", "w");
        printf("fputc A=%d\n", fputc('A', f));
        fclose(f);

        f = fopen("testfile", "a+b");
        printf("fseek=%d\n", fseek(f, -1L, SEEK_END));
        printf("c=%d\n", fgetc(f));
        printf("fputc B = %d\n", fputc('B', f));
}
$ gcc test.c && ./a.out && od -x -c testfile
fputc A=65
fseek=0
c=65
fputc B = 66
0000000    4141    0042
           A   A   B
0000003

[0] https://github.com/openssh/openssh-portable/commit/3c379c9a849a635cc7f05cbe49fe473ccf469ef9

-- 
Darren Tucker (dtucker at dtucker.net)
GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860  37F4 9357 ECEF 11EA A6FA (new)
    Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.


More information about the openssh-unix-dev mailing list