Project

General

Profile

Bug #12392

ftello64 doesn't handle ungetc() correctly when unbuffered

Added by Robert Mustacchi 8 months ago. Updated 8 months ago.

Status:
Closed
Priority:
Normal
Category:
lib - userland libraries
Start date:
Due date:
% Done:

100%

Estimated time:
Difficulty:
Medium
Tags:
Gerrit CR:

Description

While looking at issues with 7092, I discovered that there was a weird difference in behavior between ftell and ftello64(). Notably, ftell() has an additional case in the non-buffered case that looks at the buffer and subtracts it from what's there. This makes sense because when you call ungetc(), even when you have a non-buffered stream, a buffer is still used. However, ftello64() is a mostly complete copy of ftell(), but lack this.

Writing a test program for this is a little tricky. A stream can be in a reading or writing mode. In this case we need to be in writing mode for this to matter. The following program (which could be reduced further) demonstrates this.

#include <stdio.h>

int
main(void)
{
        int c;

        FILE *f = fopen("./foobar", "r+");
        setvbuf(f, NULL, _IONBF, 0);
        c = fgetc(f);
        fflush(f);
        fputc('e', f);
        printf("got c %d\n", c);
        printf("%d\n", ftell(f));
        printf("%d\n", ftello64(f));
        printf("%d\n", ungetc(c, f));
        printf("%d\n", ftell(f));
        printf("%d\n", ftello64(f));
        return (0);
}
rm@turin:/ws/rm$ gcc tmp.c 
rm@turin:/ws/rm$ echo 'hello' > foobar
rm@turin:/ws/rm$ ./a.out 
got c 104
2
2
104
1
2

Note how ftell() and ftello64() disagree. This should be the same. As part of this, I'm going to look at consolidating the implementation into a single one so we have less versions of this sitting around and it's easier to modify the behavior required for 7092.


Related issues

Related to illumos gate - Feature #7092: Want support for stdio memory streamsClosedRobert Mustacchi

Actions
Related to illumos gate - Bug #12768: 12392 regressed ftello64 behaviorClosedRobert Mustacchi

Actions
#1

Updated by Robert Mustacchi 8 months ago

  • Subject changed from ftello64 doesn't handle ungetc() correctly to ftello64 doesn't handle ungetc() correctly when unbuffered
#2

Updated by Robert Mustacchi 8 months ago

To test this, i wrote a dedicated test program that was a slightly cleaner version of the sample program. For the test results that show that this work, see 7092.

#3

Updated by Robert Mustacchi 8 months ago

  • Related to Feature #7092: Want support for stdio memory streams added
#4

Updated by Electric Monk 8 months ago

  • Status changed from New to Closed
  • % Done changed from 0 to 100

git commit cd62a92d4a964bfe61d35ba2301b69e65e22a509

commit  cd62a92d4a964bfe61d35ba2301b69e65e22a509
Author: Robert Mustacchi <rm@fingolfin.org>
Date:   2020-03-26T07:42:53.000Z

    7092 Want support for stdio memory streams
    12360 fwrite can loop forever on zero byte write
    12392 ftello64 doesn't handle ungetc() correctly when unbuffered
    Reviewed by: John Levon <john.levon@joyent.com>
    Reviewed by: Yuri Pankov <ypankov@fastmail.com>
    Approved by: Dan McDonald <danmcd@joyent.com>

#5

Updated by Robert Mustacchi 6 months ago

  • Related to Bug #12768: 12392 regressed ftello64 behavior added

Also available in: Atom PDF