thlgood
thlgood

Reputation: 1295

Segmentation fault in pipe

Given the following program:

#include <stdio.h>

int main()
{
    char buf[1024];
    scanf("%s", buf);
    printf("----> %s", buf);
    return 0;
}

which is executed as follows:

grep ....| a.out

or

echo ....| a.out

I get a Segmentation fault error. Can anyone explain why?

Upvotes: 1

Views: 2293

Answers (3)

David Pfeffer
David Pfeffer

Reputation: 39833

Whatever you are echoing or grepping must contain more than 1023 characters. (1024 - 1 for the null terminator.)

Instead of using scanf, use fgets and specify a size. Alternatively, use scanf but specify the field length. You can do scanf("%1023s", buf);. If there's more bytes available, you can always do it again to read in the rest.

Given your test input, you should not receive a segfault. I just tried it locally and it worked fine. If you are on Linux, since you wrote a.out instead of ./a.out, depending on how your path is configured you may be running the wrong program (some sort of a.out in your bin folder?)

Upvotes: 7

2r2w
2r2w

Reputation: 1509

from scanf man:
s Matches a sequence of non-white-space characters; the next pointer must be a pointer to character array that is long enough to hold the input sequence and the terminating null character ('\0'), which is added automatically. The input string stops at white space or at the maximum field width, whichever occurs first.

specifying maximum field width will prevent stack overrun

    scanf("%1023s", buf);

and to ensure stack no overrun on printf use memset:

    memset(buf,0,1024);

so, programm will be:

#include <stdio.h>
#include <string.h>
int main()
{
    char buf[1024];
    memset(buf,0,1024);
    scanf("%1023s", buf);
    printf("----> %s", buf);
    return 0;
}

Upvotes: 0

paxdiablo
paxdiablo

Reputation: 881633

Don't ever use scanf with unbounded strings. fgets provides a much safer alternative, especially if you provide an intelligent wrapper function like the one in this answer.

I'm assuming that's just sample code here but, just in case it isn't, you can achieve the same effect with:

WhateverYourCommandIs | sed 's/^/----> '

without having to write your own tool to do the job. In fact, with sed, awk and the likes, you probably never need to write text processing tools yourself.

Upvotes: 2

Related Questions