I was curious how Python would handle this evil and non portable mess:
$ cat io.py
from string import printable
f = open('foo', 'w')
for i in range(0, 5):
f = open('foo', 'r')
for l in f.readlines():
print ''.join(c if c in printable else '.' for c in l),
$ python io.py
Instead of doing it right, look for others who do it worse?
I just noticed that io:lines() does not cope with \0 in the lines, and thus just returns truncated lines (lua-5.2.3, but legacy 5.1 likewise).
May I suggest replacing the call to fgets in src/liolib.c so that we can read lines with \0 data?