0

I'm working on an assignment where part of it is to read from stdin using the system function read(), and then print the last 10 lines and so far I've got this:

int tailSTD()
{
    char *lines = malloc(1);
    char buffer[10];
    int cmdCount = 0, buffCount, rState;
    while((rState = read(STDOUT_FILENO, buffer, 10)) > 0)
    {
        if(rState < 0)
        {
            if(errno == EINTR) rState = 0;
            else
            {
                perror("read()");
                return 0;
            }
        }
        else if (rState == 0) break;

        lines = realloc(lines, strlen(lines) + strlen(buffer));
        for(buffCount = 0; buffCount < strlen(buffer); buffCount++)
        {
            lines[cmdCount] = buffer[buffCount];
            cmdCount++; 
        }
    }
    printf("do we get this far?");
    printSTDLines(lines);
    return 0;
}

The problem is that I get a segmentation fault somewhere along the loop and I\m not sure where, this worked with fgets(), and I simply modified it just because it just HAS to be done with read(). It's probably very messy, for which I apologize, but it just has to be done in this manner. I know the problem is here, because it never gets to the last printf before printSTDLines. Here's printSTDLines if you need it:

void printSTDLines(char *lines)
{
    int lineCount = strlen(lines), newLineCount = 0;
    while(newLineCount < 10)
    {
        if(lines[lineCount] == '\n')
        {
            newLineCount++;
        }
        lineCount--;
    }
    int readSize = strlen(lines) - lineCount;
    for(lineCount = readSize; lineCount < sizeof(lines); lineCount++)
    {
        write(STDOUT_FILENO, &lines[lineCount], 1);
    }
}

1 Answers1

1

You are using strlen(lines) but you never nul terminate it. The strlen() function expects to find a '\0' byte to tell where the end of the "string" is, you don't add that byte to any of your arrays and that invokes undefined behavior, one possible consequence of that is a segmentation fault.

Also, this

for(lineCount = readSize; lineCount < sizeof(lines); lineCount++)

seems wrong, the sizeof operator doesn't work for an dynamically allocated array, in this case lines is a pointer and that means sizeof is giving you the size of a pointer and by no means the length of the array which is apparently what you want.

To use the length of the array inside printSTDLine() you need to pass it as a parameter.

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
  • Yeah, I always confuse `sizeof` and `strlen` on the first go of coding, and it always takes me ages to figure out that that's the problem, but where in the loop should i `nul` terminate the string? – IneptusMechanicus Jan 18 '16 at 22:13
  • It doesn't matter where. When you pass it to `strlen()` it MUST have a `'\0'` somewhere. In practice it should be after the last character. – Iharob Al Asimi Jan 18 '16 at 22:15