Why read behavior is different? - Unix

This is a discussion on Why read behavior is different? - Unix ; Hi, I tried running this piece of code on FreeBSD 4.11, and then again on FreeBSD 6.2. #include #include #include #include #include #include int main(int argc, char** argv) { int bufsize = atoi(argv[2]); int f; int r; char* buffer = ...

+ Reply to Thread
Results 1 to 2 of 2

Thread: Why read behavior is different?

  1. Why read behavior is different?

    Hi,

    I tried running this piece of code on FreeBSD 4.11, and then again on
    FreeBSD 6.2.

    #include
    #include
    #include
    #include
    #include
    #include

    int main(int argc, char** argv)
    {
    int bufsize = atoi(argv[2]);
    int f;
    int r;
    char* buffer = new char[bufsize];
    if ( argc < 3 )
    {
    printf("wrong\n");
    exit(1);
    }

    f = open (argv[1], O_RDONLY);
    if (!f)
    {
    printf("cant open\n");
    exit(1);
    }

    r = 0;
    while ( (r = read (f, buffer, bufsize)) > 0)
    {
    fprintf(stdout, "%s", buffer);
    }

    if (r < 0)
    {
    printf("ERRROR\n");
    }

    close(f);
    return 0;
    }

    On FreeBSD 4.11
    -bash-2.05b$ ktrace ./zlib4 ./4.gz 10240
    -bash-2.05b$ kdump > 11
    -bash-2.05b$ grep bytes 11 | grep read
    84183 zlib4 GIO fd 3 read 128 bytes
    84183 zlib4 GIO fd 3 read 88 bytes
    84183 zlib4 GIO fd 3 read 4096 bytes
    84183 zlib4 GIO fd 3 read 4096 bytes
    84183 zlib4 GIO fd 3 read 4096 bytes
    84183 zlib4 GIO fd 3 read 4096 bytes
    84183 zlib4 GIO fd 3 read 10240 bytes
    84183 zlib4 GIO fd 3 read 10240 bytes
    84183 zlib4 GIO fd 3 read 10240 bytes
    84183 zlib4 GIO fd 3 read 10240 bytes
    84183 zlib4 GIO fd 3 read 10240 bytes
    84183 zlib4 GIO fd 3 read 10240 bytes
    84183 zlib4 GIO fd 3 read 10240 bytes
    84183 zlib4 GIO fd 3 read 10240 bytes
    84183 zlib4 GIO fd 3 read 10240 bytes
    84183 zlib4 GIO fd 3 read 10240 bytes
    84183 zlib4 GIO fd 3 read 10240 bytes
    84183 zlib4 GIO fd 3 read 10240 bytes
    84183 zlib4 GIO fd 3 read 10240 bytes
    ...

    On FreeBSD 6.2
    -bash-3.2$ ktrace ./zlib4 ./4.gz 10240
    -bash-3.2$ kdump > 44
    -bash-3.2$ grep bytes 44 | grep read
    72916 zlib4 GIO fd 3 read 128 bytes
    72916 zlib4 GIO fd 3 read 76 bytes
    72916 zlib4 GIO fd 3 read 4096 bytes
    72916 zlib4 GIO fd 3 read 4096 bytes
    72916 zlib4 GIO fd 3 read 4096 bytes
    72916 zlib4 GIO fd 3 read 4096 bytes
    72916 zlib4 GIO fd 3 read 4096 bytes
    72916 zlib4 GIO fd 3 read 4096 bytes
    72916 zlib4 GIO fd 3 read 4096 bytes
    72916 zlib4 GIO fd 3 read 4096 bytes
    72916 zlib4 GIO fd 3 read 4096 bytes
    72916 zlib4 GIO fd 3 read 4096 bytes
    72916 zlib4 GIO fd 3 read 4096 bytes
    72916 zlib4 GIO fd 3 read 4096 bytes
    72916 zlib4 GIO fd 3 read 4096 bytes
    72916 zlib4 GIO fd 3 read 4096 bytes
    72916 zlib4 GIO fd 3 read 4096 bytes

    I see using ktrace that the read system call in 6.2 just reads 4K per
    call, while 10K on FreeBSD 4.11. Could someone tell me why it's the
    case?

    Thanks ..


  2. Re: Why read behavior is different?

    Kelvin Moss writes:
    >Hi,
    >
    >I tried running this piece of code on FreeBSD 4.11, and then again on
    >FreeBSD 6.2.
    >
    >#include
    >#include
    >#include
    > #include
    > #include
    > #include
    >
    >int main(int argc, char** argv)
    >{
    > int bufsize = atoi(argv[2]);
    > int f;
    > int r;
    > char* buffer = new char[bufsize];
    > if ( argc < 3 )
    > {
    > printf("wrong\n");
    > exit(1);
    > }
    >
    > f = open (argv[1], O_RDONLY);
    > if (!f)
    > {
    > printf("cant open\n");
    > exit(1);
    > }
    >
    > r = 0;
    > while ( (r = read (f, buffer, bufsize)) > 0)


    You should really check for 'r == bufsize' to determine
    if the read was successful. r < bufsize is a short read
    (which shouldn't happen from a disk file unless you're up
    against the end-of-file). r == 0 is returned if the fd
    is positioned at the end-of-file mark, and r == -1 is
    returned if an error occurred.

    I suspect that you'll find that except for the last read,
    'r' is always == bufsize and that the 'read' system call is
    implemented in BSD's libc by calling a generic I/O system call (GIO). It looks
    like BSD's libc will break the 'read' into one or more GIO
    calls for some reason, and different versions of BSD have different
    implementations of the 'read' system call in libc. 4k happens to
    correspond to the system page size.

    You should probably pull the BSD libc source and check what its doing
    for the read system call.

    scott

+ Reply to Thread