read a file line by line with POSIX IO primitives

I'm a newbie and I'm trying to implement my own readline() with POSIX IO primitives.

I've wrote the code:

int readline(int fd, char **line, size_t size)
{
    char *ch = malloc(sizeof(char));
    char buf[BUFSIZ];
    int index = 0;
    int nr;

    if (NULL == line)
        return -1;

    do
    {
        nr = read(fd, ch, 1);

        if (nr == -1)
        {
            perror("read()");
            return -1;
        } else
            if (0 == nr)
                break;

        buf[index++] = (*ch);


    } while ((*ch != '\n') && (index < BUFSIZ));

    if ((index) && (buf[index-1] == '\r'))
    {
        index--;
    }

    buf[index++] = '\n';

    buf[index] = 0; /* null-terminate */

    printf("index = %d\n", index);

    strncpy(*line, buf, size);

    if ((buf[0] == '\n') || (buf[0] == '\0') || (buf[0] == '\r'))
        return 0;
    return index;
}

int main(void)
{
    int fd;
    ssize_t nbytes;

    char *line = malloc(BUFSIZ*sizeof(char));

    fd = open("/etc/passwd", O_RDONLY);

    while((nbytes = readline(fd, &line, sizeof(line))) > 0)
    {
        write(1, line, nbytes);
    }

    close(fd);

    return 0;
}

But it reads only 8 characters of each line. I spent much time to fix the code, but didn't get anywhere. I also read many topics on this website, most of them use the same algorithm, but it is only my code that does not work!

Upvotes: 0

Views: 958

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409166

The problem is your use of the sizeof operator to get the size of the allocate memory. The sizeof operator will not give you the size of what a pointer points to, it will give you the size of the actual pointer.

In your case, it's 8 bytes which equals 64 bits, which is the standard pointer size on 64-bit systems.

You need to keep track of the sizes you allocate yourself, and in this case pass BUFSIZ as the argument instead.

Upvotes: 2

Related Questions