Fix to allow the flac command to parse piped WAV input with
authornu774 <honeycomb77@gmail.com>
Thu, 27 Dec 2012 12:44:38 +0000 (21:44 +0900)
committerErik de Castro Lopo <erikd@mega-nerd.com>
Fri, 28 Dec 2012 00:31:35 +0000 (11:31 +1100)
WAVEFORMATEXTENSIBLE format.

MinGW's fseeko() doesn't return error for the attempt to seek on non
seekable file (same behavior as MSVC).
The simplest solution would be to change #ifdef _MSC_VER to #ifdef
_WIN32 here.
Instead, this patch tests file with fstat(), and use fseeko() only when
it is a regular file.
This is confirmed to work properly both on MSVC and MinGW, can seek if
stdin is a redirected regular file, and doesn't require #ifdef.

Signed-off-by: Erik de Castro Lopo <erikd@mega-nerd.com>
src/flac/encode.c

index b3f3670..eeea08a 100644 (file)
@@ -26,6 +26,7 @@
 #include <stdio.h> /* for FILE etc. */
 #include <stdlib.h> /* for malloc */
 #include <string.h> /* for strcmp(), strerror() */
+#include <sys/stat.h>
 #include "FLAC/all.h"
 #include "share/alloc.h"
 #include "share/grabbag.h"
@@ -2799,29 +2800,18 @@ FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, const char *fn)
 FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset)
 {
        static unsigned char dump[8192];
+       struct stat stb;
 
-#ifdef _MSC_VER
-       if(f == stdin) {
-               /* MS' stdio impl can't even seek forward on stdin, have to use pure non-fseek() version: */
-               while(offset > 0) {
-                       const long need = (long)min(offset, sizeof(dump));
-                       if((long)fread(dump, 1, need, f) < need)
-                               return false;
-                       offset -= need;
-               }
-       }
-       else
-#endif
+       if(fstat(fileno(f), &stb) == 0 && (stb.st_mode & S_IFMT) == S_IFREG)
        {
-               while(offset > 0) {
-                       long need = (long)min(offset, LONG_MAX);
-                       if(fseeko(f, need, SEEK_CUR) < 0) {
-                               need = (long)min(offset, sizeof(dump));
-                               if((long)fread(dump, 1, need, f) < need)
-                                       return false;
-                       }
-                       offset -= need;
-               }
+               if(fseeko(f, offset, SEEK_CUR) == 0)
+                       return true;
+       }
+       while(offset > 0) {
+               const long need = (long)min(offset, sizeof(dump));
+               if((long)fread(dump, 1, need, f) < need)
+                       return false;
+               offset -= need;
        }
        return true;
 }