fseek/fgetc puzzle

Darren Tucker dtucker at dtucker.net
Mon Feb 20 23:19:58 AEDT 2023


On Mon, 20 Feb 2023 at 22:39, Nathan Wagner <nw at hydaspes.if.org> wrote:
> On Mon, Feb 20, 2023 at 10:21:31PM +1100, Darren Tucker wrote:
[...]
> > The "od" call in the middle of the above example proves there's only
> > one byte after the first fclose.
>
> Ah, so it does.

I added that to answer the question, it wasn't in the original.

> What happens if you do everything except the last call at the end?
> printf("fputc B = %d\n", fputc('B', f));

Omitting the final fputc leaves the file as it was after the first fclose ("A").

> What happen if you don't read the last byte?  I realize
> you will need to for the original problem?
>
> What I'm wondering is if somehow reading the byte puts it in
> the output buffer.
>
> What happens if you create an initial two byte file, say "AB", and try
> to write a 'C'?  If you read the B, I guess we expect 'ABBC' at this
> point.

Yep that's what we get:

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

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

> If you read the 'A', do you get 'ABAC' or something else?

Yep. change the fseek to -2 and you get "ABAC".

> I wish I had a box I could reproduce the problem on (see below).

If you're willing to install OpenIndiana (an OpenSolaris fork) it
reproduces on that:

$ uname -a
SunOS openindiana 5.11 illumos-a5a9a6bb70 i86pc i386 i86pc

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