[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: gnulib portability issues
From: |
Eric Blake |
Subject: |
Re: gnulib portability issues |
Date: |
Tue, 12 Jun 2012 06:12:39 -0600 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20120430 Thunderbird/12.0.1 |
On 06/12/2012 01:04 AM, Ben Pfaff wrote:
> Eric Blake <address@hidden> writes:
>
>> Wrong. Pretty much every libc out there lets you ungetc() more than one
>> byte.
>
> Does that include glibc? Then there is a bug in the manual,
> which says:
>
> The GNU C library only supports one character of
> pushbackâin other words, it does not work to call ungetc
> twice without doing input in between.
>
> in the description of ungetc().
That's the glibc documentation and I agree it is inaccurate; the Linux
man-pages project is better:
ungetc() pushes c back to stream, cast to unsigned char, where
it is
available for subsequent read operations. Pushed-back
characters will
be returned in reverse order; only one pushback is guaranteed.
And this simple program proves that most libc know how to push back more
than one byte, whether or not they differ from the original contents,
and especially in the common case where the byte still fits in the
buffer. It's the corner case where the bytes being pushed back differ
from the backing store, and where they don't fit in the normal buffer
(perhaps because you have used setvbuf or friends), and therefore libc
has to malloc() some pushback storage, and if the malloc fails then so
does the ungetc().
$ cat foo.c
#include <stdio.h>
int main(void)
{
char buf[10];
if (fseek(stdin, 0, SEEK_CUR))
return 1;
if (fread(buf, 1, sizeof(buf), stdin) != 10)
return 2;
if (ungetc(buf[9], stdin) != buf[9])
return 3;
if (ungetc(buf[8], stdin) != buf[8])
return 4;
if (getchar() != buf[8])
return 5;
if (getchar() != buf[9])
return 6;
if (ungetc(buf[9] + 1, stdin) != buf[9] + 1)
return 7;
if (ungetc(buf[8] + 1, stdin) != buf[8] + 1)
return 8;
if (getchar() != buf[8] + 1)
return 9;
if (getchar() != buf[9] + 1)
return 10;
return 0;
}
$ ./foo < foo.c; echo $?
0
--
Eric Blake address@hidden +1-919-301-3266
Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature
- gnulib portability issues, Rich Felker, 2012/06/09
- Re: gnulib portability issues, Paul Eggert, 2012/06/10
- Re: gnulib portability issues, Rich Felker, 2012/06/10
- Re: gnulib portability issues, Paul Eggert, 2012/06/10
- Re: gnulib portability issues, Rich Felker, 2012/06/10
- Re: gnulib portability issues, Paul Eggert, 2012/06/10
- Re: gnulib portability issues, Eric Blake, 2012/06/11
- Re: gnulib portability issues, Rich Felker, 2012/06/11
- Re: gnulib portability issues, Ben Pfaff, 2012/06/12
- Re: gnulib portability issues,
Eric Blake <=
- Re: gnulib portability issues, Rich Felker, 2012/06/12
- Re: gnulib portability issues, Eric Blake, 2012/06/12
- Re: gnulib portability issues, Rich Felker, 2012/06/10
- Re: gnulib portability issues, Paul Eggert, 2012/06/10
- Re: gnulib portability issues, Rich Felker, 2012/06/10
- Re: gnulib portability issues, Paul Eggert, 2012/06/11
- Re: gnulib portability issues, Bruno Haible, 2012/06/17
- Re: gnulib portability issues, Eric Blake, 2012/06/11
- Re: gnulib portability issues, Rich Felker, 2012/06/11
- Re: gnulib portability issues, Eric Blake, 2012/06/11