glibc i zwisy poldka

Jakub Bogusz qboosh w pld-linux.org
Pon, 11 Kwi 2005, 21:06:24 CEST


On Fri, Apr 08, 2005 at 05:08:01PM +0200, Arkadiusz Miskiewicz wrote:
> On Friday 08 of April 2005 16:56, Jakub Bogusz wrote:
> 
> > wg komentarza do zmian w fmemopen powinno być raczej:
> >
> >       if (rc >= 0) {
> >         *offset =  rc;
> >         rc = 0;
> >       }
> >
> > (w kodzie poldka)
> Nie pomaga. Zresztą bugów jest więcej:
> http://sources.redhat.com/ml/libc-alpha/2005-04/msg00035.html
> 
> fseek(stream, 5, SEEK_SET); zwraca 0 ale ftell mówi 0 czyli fseek średnio się 
> powiodło lub ftell zwraca bzdury.

Program testowy jest zły - seek cookie działa trochę inaczej niż seek (info
libc, szukać cookie - tzn. ma zwracać 0 lub -1, natomiast nowy offset ma
wpisywać pod zmienną podaną jako drugi parametr (i to nie jest to samo,
co fpos_t).
Poprawiony w załączniku (z usuniętym jeszcze niepotrzebnym zlib.h).
(w poldku też jest źle - łatę wrzuciłem do SOURCES, ale nie wystarcza)

Co nie zmienia bzdurnego zachowania ftell() w 2.3.5.

$ cat /tmp/bla
abcdefgh
$ ./fcookie-tst /tmp/bla
1: ftell 0
2: fseek ret: 0 ftell 0
3: fseek ret: 0 ftell 5
4: char: f fread ret: 1 ftell: 6
$ LD_PRELOAD=~qboosh/PLD/BUILD/glibc-2.3.5/builddir/libc.so.6 ./fcookie-tst /tmp/bla
1: ftell 0
2: fseek ret: 0 ftell 0
3: fseek ret: 0 ftell 0
4: char: f fread ret: 1 ftell: -1

System to Ac, z gcc 3.3.5.

Z drugiej strony w 2.3.4 faktycznie był błąd w fmemopen(), poprawiony
przez:

2005-01-05  Ulrich Drepper  <drepper w redhat.com>

        [BZ #730]
        * libio/iofopncook.c (_IO_cookie_seekoff): Define.  Mark offset
        * as
        invalid to disable optimizations in fileops which won't work here.
        (_IO_cookie_jumps): Use it.
        (_IO_old_cookie_jumps): Likewise.
        * libio/fmemopen.c (fmemopen_seek): Result must be returned in
        * *P,
        not the return value.
        * stdio-common/Makefile (tests): Add tst-fmemopen2.
        * stdio-common/tst-fmemopen2.c: New file.

która to zmiana wprowadziła regresję gdzie indziej (oprócz tego, że
z powodu tego błędu błędny kod w poldku wcześniej przypadkiem działał).


-- 
Jakub Bogusz    http://cyber.cs.net.pl/~qboosh/
-------------- następna część ---------
# define _GNU_SOURCE 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <libio.h>

static size_t myread(void* myhandle, char* buffer, size_t size)
{
  return fread(buffer, 1, size, (FILE*)myhandle);
}
static size_t mywrite(void* myhandle, char* buffer, size_t size)
{
  return fwrite(buffer, 1, size, (FILE*)myhandle);
}
static int myseek(void* myhandle, _IO_off64_t* position, int whence)
{
  int p = *position, rc;
  rc = fseek((FILE*)myhandle, p, whence);
  if(rc >= 0) {
    *position = rc;
    rc = 0;
  }
  return rc;
}
static int myclose(void* myhandle)
{
  return fclose((FILE*)myhandle);
}

cookie_io_functions_t myfunctions =
{
  (cookie_read_function_t*)myread,
  (cookie_write_function_t*)mywrite,
  (cookie_seek_function_t*)myseek,
  (cookie_close_function_t*)myclose
};

int main(int argc, char *argv[])
{
    char *path = argv[1];
    FILE *zstream;
    FILE *stream;
    int c, d;

    if ((zstream = fopen(path, "r")) != NULL) {
        stream = fopencookie(zstream, "r", myfunctions);
	if (!stream) {
		printf("fopencookie failed\n");
		return 1;
	}
        printf("1: ftell %ld\n", ftell(stream));
	d = fseek(stream, 0, SEEK_CUR);
	printf("2: fseek ret: %d ftell %ld\n", d, ftell(stream));
	d = fseek(stream, 5, SEEK_SET);
	printf("3: fseek ret: %d ftell %ld\n", d, ftell(stream));
        d = fread(&c, 1, 1, stream);
        printf("4: char: %c fread ret: %d ftell: %ld\n", (unsigned char)c, d, ftell(stream));
	fclose(zstream);
    }
    return 1;
}



Więcej informacji o liście dyskusyjnej pld-devel-pl