2

im trying to pipe into read but it keeps segfaulting after the second input. what am i doing wrong? Thanks in advance.

 $ ./read < <(python -c 'print "BBA\nBBADD\n",')
 Please enter your first name: 
 buf=
 BBA
 BBA
 Please enter your last name: 
 buf=
 Segmentation fault (core dumped)

I attached the code of read as a reference, the important part is the read()

//read.c
#include <stdio.h>
#include <string.h>

void prompt_name(char *name, char *msg){
    char buf[4096];

    puts(msg);

    read(0, buf, sizeof buf);
puts("buf=");
puts(buf);
    *strchr(buf, '\n') = 0;

puts(buf);
    strncpy(name, buf, 20);
puts(name);
}

void prompt_full_name(char *fullname) {
    char last[20];
    char first[20];

    prompt_name(first, "Please enter your first name: ");
    prompt_name(last, "Please enter your last name: ");

    strcpy(fullname, first);
    strcat(fullname, " ");
    strcat(fullname, last);
}


int main(int argc, char **argv){
    char fullname[42];

    prompt_full_name(fullname);
    printf("Welcome, %s\n", fullname);

    return 0;
}

`

kokocrunch
  • 41
  • 4
  • 3
    You need to check return cods on most of the library calls. `read()` attempts to read up to 4096 bytes, thus consuming your entire input on the first call - it does not simply read the first line. Thus, your second call to `read()` gets nothing, and you have a bunch of assumptions that you're not checking, leading you to copy and and manipulate "strings" that aren't what you think they are. – twalberg Nov 08 '12 at 15:29
  • 1
    Don't use `strncpy`, [it might not null-terminate the string](http://stackoverflow.com/questions/1453876/why-does-strncpy-not-null-terminate). – Adam Rosenfield Nov 08 '12 at 16:28

1 Answers1

4

read doesn't know anything about strings, so it just happily reads sizeof(buf) characters without ever NUL-terminating buf. Calling puts(buf) then causes undefined behavior.

You shouldn't be using such low-level functions for simple string I/O; prefer getline instead. If you do want to use read, then read smaller chunks, check the return value on every call and use it; it tells you how much was read.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836