Stdio filter crashed when

I wrote a program for anagram string using strfry. It works fine with stdin stdin, but fails 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's wrong here? Used by GNU libc / GCC. Go through valgrind and find no memory leaks.

+3


source to share


3 answers


fgets

returns NULL

when end of file has been reached. You should be using this return value, not calls ferror

or feof

to control your loop. You should also be careful not to pass pointers NULL

to string functions. They can handle it gracefully, but they usually don't.

So your loop should look like this:



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

      

I threw it out memset

because the result is fgets

null terminated and will not overflow the buffer, so you can pass the full length of the 4096 byte.

0


source


Rewrite this line

if (argc>1) fryend=fopen(argv[1],"r") ? fryend : stdin;

      

without a conditional operator.



Maybe something like

if (argc > 1) {
    FILE *tmp = fopen(argv[1], "r");
    if (tmp) fryend = tmp;
}

      

+1


source


When redirecting stdin

a.out <test.txt

      

fgets()

can return NULL

.

From manfgets()

:

RETURN VALUE

[...] fgets () return [s] [...] NULL on error or on file termination when no characters have been read.

In turn NULL

goes to strfry()

,

strfry(fgets(buf, 4095, fryend));

      

which is not a good idea.

0


source







All Articles