From 9a7658070aeca2c0a6c68e5025a80f9e4b847ad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20Hamb=C3=BCchen?= Date: Mon, 24 Aug 2020 06:23:51 +0200 Subject: Use fstat() to determine file size. This allows us to get the file size even when the input file is passed via stdin. This fixes `--content-size` not working in situations like $ lz4 -v --content-size < /tmp/test > /tmp/test.lz4 Warning : cannot determine input content size With this change, it works. Also helps with #904. --- programs/lz4io.c | 4 ++-- programs/util.h | 27 ++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/programs/lz4io.c b/programs/lz4io.c index 7926b20..0f3507e 100644 --- a/programs/lz4io.c +++ b/programs/lz4io.c @@ -680,7 +680,7 @@ LZ4IO_compressFilename_extRess(LZ4IO_prefs_t* const io_prefs, cRess_t ress, prefs.frameInfo.contentChecksumFlag = (LZ4F_contentChecksum_t)io_prefs->streamChecksum; prefs.favorDecSpeed = io_prefs->favorDecSpeed; if (io_prefs->contentSizeFlag) { - U64 const fileSize = UTIL_getFileSize(srcFileName); + U64 const fileSize = UTIL_getOpenFileSize(srcFile); prefs.frameInfo.contentSize = fileSize; /* == 0 if input == stdin */ if (fileSize==0) DISPLAYLEVEL(3, "Warning : cannot determine input content size \n"); @@ -1472,7 +1472,7 @@ LZ4IO_getCompressedFileInfo(LZ4IO_cFileInfo_t* cfinfo, const char* input_filenam LZ4IO_infoResult result = LZ4IO_format_not_known; /* default result (error) */ unsigned char buffer[LZ4F_HEADER_SIZE_MAX]; FILE* const finput = LZ4IO_openSrcFile(input_filename); - cfinfo->fileSize = UTIL_getFileSize(input_filename); + cfinfo->fileSize = (finput == NULL) ? 0 : UTIL_getOpenFileSize(finput); while (!feof(finput)) { LZ4IO_frameInfo_t frameInfo = LZ4IO_INIT_FRAMEINFO; diff --git a/programs/util.h b/programs/util.h index 8e361ca..4b2c09a 100644 --- a/programs/util.h +++ b/programs/util.h @@ -33,7 +33,7 @@ extern "C" { #include /* size_t, ptrdiff_t */ #include /* malloc */ #include /* strlen, strncpy */ -#include /* fprintf */ +#include /* fprintf, fileno */ #include #include /* stat, utime */ #include /* stat */ @@ -357,6 +357,31 @@ UTIL_STATIC U32 UTIL_isDirectory(const char* infilename) } +UTIL_STATIC U64 UTIL_getOpenFileSize(FILE* file) +{ + int r; + int fd = fileno(file); + if (fd < 0) { + perror("fileno"); + exit(1); + } +#if defined(_MSC_VER) + struct __stat64 statbuf; + r = _fstat64(fd, &statbuf); + if (r || !(statbuf.st_mode & S_IFREG)) return 0; /* No good... */ +#elif defined(__MINGW32__) && defined (__MSVCRT__) + struct _stati64 statbuf; + r = _fstati64(fd, &statbuf); + if (r || !(statbuf.st_mode & S_IFREG)) return 0; /* No good... */ +#else + struct stat statbuf; + r = fstat(fd, &statbuf); + if (r || !S_ISREG(statbuf.st_mode)) return 0; /* No good... */ +#endif + return (U64)statbuf.st_size; +} + + UTIL_STATIC U64 UTIL_getFileSize(const char* infilename) { int r; -- cgit v0.12