Search code examples
cstringstdio

The stdio filter crashed when piped


I have written a program to anagram string using strfry. It works greatly with default standard input, but crashes when used with stdio redirection(functions, but segfaults at the end):

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sys/mman.h"

int main(int argc,char *argv[]) {
    FILE *fryend=stdin;
    if (argc==1) goto mainloop;
    if (argc>1) fryend=fopen(argv[1],"r") ? fryend : stdin;

    mainloop:;
    char *buf=malloc(4096);
    while (!ferror(fryend)) {
        memset(buf,0,4096);
        strfry(fgets(buf,4095,fryend));
        fputs(buf,stdout);
    }
    free(buf);
    if (fryend!=stdin) fclose(fryend);
    return 0;
}

What is wrong here? Used GNU libc/GCC. Run through valgrind and no memory leak detected.


Solution

  • fgets returns NULL when the end of the file has been reached. You should use this return value rather than calls to ferror or feof to control your loop. You should also be careful not to pass NULL pointers to string functions. They might handle this gracefully, but usually don't.

    So your loop should look like:

    while (fgets(buf, 4096, fryend)) {
        strfry(buf);
        fputs(buf, stdout);
    }
    

    I've thrown out the memset, because the result of fgets is null-terminated and will not overflow the buffer, so you can pass the full 4096 byte length.