I’ve written a program called Mathtext. This program gives plain text “style” by shifting certain character ranges into Unicode ranges such as ‘mathematical letterlike symbols” to produce plain-text italics, bold, serif, etc.
It works as a line-by-line interpreter, like a shell, outputting the translated line after a line is entered. This means that files can be cat/piped in to translate an entire file, as well as the fact that you can ‘exit’ the ‘shell’ by pressing ^D, which is detected by stdin hitting EOF.
Everything works. However, when I press ^D and exit, it segfaults. I still can’t quite grasp what is causing this.
Compiling with -g -O0 helps a little; I now know that the problem arises from a strlen call in transpose when ^D is pressed. However, transpose should never be called during ^D, as eof is true!
Program received signal SIGSEGV, Segmentation fault.
__strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:31
31 ../sysdeps/x86_64/multiarch/../strlen.S: No such file or directory.
in ../sysdeps/x86_64/multiarch/../strlen.S
(gdb) where
#0 __strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:31
#1 0x0000000000400b0e in transpose (s=0x0, capsDelta=120263, smallDelta=120257, numDelta=0) at mathtext.c:58
#2 0x0000000000400e2b in main (argc=2, argv=0x7fffffffe4b8) at mathtext.c:92
Most uses of
feof()are a bug – and this program demonstrates it perfectly in this main loop:At end-of-file,
fgets()will returnNULL, and then the next invocation offeof()will return true. So the correct approach is to test the return value of your input function – and since you’re doing that test anyway, there’s no need to callfeof()(unless you want to distinguish a file error from end-of-file).