1
0
mirror of synced 2026-04-05 21:33:24 +00:00

Fix issues with C stdio stream and Unix FD getting out of sync when rewind() is used.

This commit is contained in:
Eric Smith
2022-04-28 21:37:24 -06:00
parent 5b451610a9
commit 061a017018

View File

@@ -28,6 +28,10 @@
#include <stdlib.h>
#include <strings.h> /* strcasecmp() is a BSDism */
// Sadly libtiff doesn't accept C streams as input sources, so we have to
// use Unix file descriptors.
#include <unistd.h>
#include <tiffio.h>
/*
* On the x86, libtiff defaults to big-endian bit order for no good reason.
@@ -80,10 +84,43 @@ static bool open_tiff_input_file (FILE *f, char *name)
((buf [0] == 0x4d) && (buf [1] == 0x4d))))
return (0);
tiff_in = TIFFFdOpen (fileno (f), name, "r");
// At this point we expect never to use f (C stream) again,
// and rewind() isn't guaranteed to have had any effect on
// the C stream, so we explicity lseek() the Unix FD to the start
// of the file.
// However, if TIFFFdOpen() fails, it's possible that another
// input handler will try using the C stream again, so we'll
// have to restore the file offset to where it left it.
int fd = fileno(f);
off_t original_offset = lseek(fd, 0, SEEK_CUR);
if (original_offset < 0)
{
// SHOULD NEVER HAPPEN
fprintf(stderr, "can't get file descriptor position from lseek().");
exit (2);
}
off_t new_offset = lseek(fd, 0, SEEK_SET);
if (new_offset != 0)
{
// SHOULD NEVER HAPPEN
fprintf(stderr, "can't lseek() to start of file.");
exit (2);
}
tiff_in = TIFFFdOpen (fd, name, "r");
if (! tiff_in)
{
fprintf (stderr, "can't open input file '%s'\n", name);
off_t restore_offset = lseek(fd, original_offset, SEEK_SET);
if (restore_offset != original_offset)
{
// SHOULD NEVER HAPPEN
fprintf(stderr, "can't lseek() back to original file offset.");
exit (2);
}
return (0);
}
return (1);