I have a utility that is supposed to optimize files by transforming them into an alternate file-format. If it cannot make the files smaller, I would like the original file returned.
The design is to use stdin
in and stdout
for input and output. This is for a case where the processed size is larger than the original file size. All other branches are tested as working.
char readbuffer[65536];
ssize_t readinbytes;
while ((readinbytes = fread(readbuffer, sizeof(char), insize, stdin)) > 0) {
if (fwrite(readbuffer, sizeof(char), readnbytes, stdout) != readnbytes) {
fatal("can't write to stdout, please smash and burn the computer\n");
}
}
Problem This is resulting in a file with size 0
Right this question has a strange answer. Essentially I had to read stdin
into a buffer (inbuf
), then output the contents of that buffer. The overarching reason I was getting no output was multi-faceted.
Firstly I'd failed to spot a branch which already determined if the input buffer was smaller than the output buffer
if((readinbytes < outbuffersize) || force) {
// inside this is where the code was...
It looks like (because stdout was being used to write to) there was a section that contained a log statement that was not output in the matching else
block. The code inherited was terribly formatted so it was never picked up on.
As outputting error messages is not fulfilling the purpose of the utility (always output a valid output file if a valid input file is provided)
solution (stdin
is read into inbuf
at the start of the program)
set_filemode_binary(stdout);
if (fwrite(inbuf, 1, readinbytes, stdout) != insize) {
fprintf(stderr, "error writing to stdout\n");
free(inbuf);
exit(3);
}
errata (reading in stdin
)
unsigned char * inbuf = NULL;
size_t readinbytes;
long insize = 0;
// elsewhere...
// die if no stdin
insize = getFileSize(stdin);
if (insize < 0) {
fprintf(stderr, "no input to stdin\n");
exit(2);
}
// read stdin to buffer
inbuf = createBuffer(insize); // wrapper around malloc handling OOM
if ((readinbytes = fread(inbuf, sizeof(char), insize, stdin)) < 0) {
fprintf(stderr, "error reading from stdin\n");
free(inbuf);
exit(3);
}
Also don't forget to free(inbuf)
.
if(inbuf){ free(inbuf); }
I Hope this helps someone.