From 0a4586338a67f8a001543da81fbc085837ad3178 Mon Sep 17 00:00:00 2001 From: Josh Coalson Date: Sun, 17 Feb 2002 22:22:49 +0000 Subject: [PATCH] add code for forcing the file mode for stdin/stdout to binary when needed --- src/flac/decode.c | 12 ++++++------ src/flac/encode.c | 20 +++++++++---------- src/flac/file.c | 40 ++++++++++++++++++++++++++++++++++++-- src/flac/file.h | 5 +++++ src/flac/main.c | 2 +- src/libFLAC/file_decoder.c | 28 +++++++++++++++++++++++++- 6 files changed, 87 insertions(+), 20 deletions(-) diff --git a/src/flac/decode.c b/src/flac/decode.c index e2e25e93..5217e448 100644 --- a/src/flac/decode.c +++ b/src/flac/decode.c @@ -119,7 +119,7 @@ int flac__decode_wav(const char *infilename, const char *outfilename, FLAC__bool if(!stream_info.test_only) { if(0 == strcmp(outfilename, "-")) { - stream_info.fout = stdout; + stream_info.fout = file__get_binary_stdout(); } else { if(0 == (stream_info.fout = fopen(outfilename, "wb"))) { @@ -132,11 +132,11 @@ int flac__decode_wav(const char *infilename, const char *outfilename, FLAC__bool #ifdef FLAC__HAS_OGG if(stream_info.is_ogg) { if (0 == strcmp(infilename, "-")) { - stream_info.fin = stdin; + stream_info.fin = file__get_binary_stdin(); } else { if (0 == (stream_info.fin = fopen(infilename, "rb"))) { fprintf(stderr, "%s: ERROR: can't open input file %s\n", stream_info.inbasefilename, infilename); - if(stream_info.fout != stdout) + if(0 != stream_info.fout && stream_info.fout != stdout) fclose(stream_info.fout); return 1; } @@ -305,7 +305,7 @@ int flac__decode_raw(const char *infilename, const char *outfilename, FLAC__bool if(!stream_info.test_only) { if(0 == strcmp(outfilename, "-")) { - stream_info.fout = stdout; + stream_info.fout = file__get_binary_stdout(); } else { if(0 == (stream_info.fout = fopen(outfilename, "wb"))) { @@ -318,11 +318,11 @@ int flac__decode_raw(const char *infilename, const char *outfilename, FLAC__bool #ifdef FLAC__HAS_OGG if(stream_info.is_ogg) { if (0 == strcmp(infilename, "-")) { - stream_info.fin = stdin; + stream_info.fin = file__get_binary_stdin(); } else { if (0 == (stream_info.fin = fopen(infilename, "rb"))) { fprintf(stderr, "%s: ERROR: can't open input file %s\n", stream_info.inbasefilename, infilename); - if(stream_info.fout != stdout) + if(0 != stream_info.fout && stream_info.fout != stdout) fclose(stream_info.fout); return 1; } diff --git a/src/flac/encode.c b/src/flac/encode.c index 30da076c..0b4ef5f1 100644 --- a/src/flac/encode.c +++ b/src/flac/encode.c @@ -156,12 +156,13 @@ int flac__encode_wav(FILE *infile, long infilesize, const char *infilename, cons (void)lookahead_length; if(0 == strcmp(outfilename, "-")) { - encoder_wrapper.fout = stdout; + encoder_wrapper.fout = file__get_binary_stdout(); } else { if(0 == (encoder_wrapper.fout = fopen(outfilename, "wb"))) { fprintf(stderr, "%s: ERROR: can't open output file %s\n", encoder_wrapper.inbasefilename, outfilename); - fclose(infile); + if(infile != stdin) + fclose(infile); return 1; } } @@ -262,7 +263,7 @@ int flac__encode_wav(FILE *infile, long infilesize, const char *infilename, cons fprintf(stderr, "%s: WARNING: skipping extra 'data' sub-chunk\n", encoder_wrapper.inbasefilename); } else if(!got_fmt_chunk) { - fprintf(stderr, "%s: ERROR: got data sub-chunk before fmt sub-chunk\n", encoder_wrapper.inbasefilename); + fprintf(stderr, "%s: ERROR: got 'data' sub-chunk before 'fmt' sub-chunk\n", encoder_wrapper.inbasefilename); goto wav_abort_; } else { @@ -399,7 +400,7 @@ int flac__encode_wav(FILE *infile, long infilesize, const char *infilename, cons goto wav_abort_; } else if(bytes_read != (*options.align_reservoir_samples) * bytes_per_wide_sample) { - fprintf(stderr, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_wrapper.inbasefilename, (unsigned)encoder_wrapper.total_samples_to_encode, (unsigned)encoder_wrapper.samples_written); + fprintf(stderr, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_wrapper.inbasefilename, (unsigned)bytes_read, (unsigned)encoder_wrapper.total_samples_to_encode, (unsigned)encoder_wrapper.samples_written); data_bytes = 0; } else { @@ -513,12 +514,13 @@ int flac__encode_raw(FILE *infile, long infilesize, const char *infilename, cons #endif if(0 == strcmp(outfilename, "-")) { - encoder_wrapper.fout = stdout; + encoder_wrapper.fout = file__get_binary_stdout(); } else { if(0 == (encoder_wrapper.fout = fopen(outfilename, "wb"))) { fprintf(stderr, "ERROR: can't open output file %s\n", outfilename); - fclose(infile); + if(infile != stdin) + fclose(infile); return 1; } } @@ -1062,7 +1064,7 @@ void metadata_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMet { encoder_wrapper_struct *encoder_wrapper = (encoder_wrapper_struct *)client_data; FLAC__byte b; - FILE *f; + FILE *f = encoder_wrapper->fout; const FLAC__uint64 samples = metadata->data.stream_info.total_samples; const unsigned min_framesize = metadata->data.stream_info.min_framesize; const unsigned max_framesize = metadata->data.stream_info.max_framesize; @@ -1088,13 +1090,11 @@ void metadata_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMet (void)encoder; /* silence compiler warning about unused parameter */ - if(encoder_wrapper->fout != stdout) { + if(f != stdout) { fclose(encoder_wrapper->fout); if(0 == (f = fopen(encoder_wrapper->outfilename, "r+b"))) return; } - else - f = stdout; /* all this is based on intimate knowledge of the stream header * layout, but a change to the header format that would break this diff --git a/src/flac/file.c b/src/flac/file.c index 8c11da3f..77df50b6 100644 --- a/src/flac/file.c +++ b/src/flac/file.c @@ -18,13 +18,17 @@ #if defined _MSC_VER || defined __MINGW32__ #include /* for utime() */ -#include /* for chmod() */ +#include /* for chmod(), _setmode() */ +#include /* for _O_BINARY */ #else #include /* some flavors of BSD (like OS X) require this to get time_t */ #include /* for utime() */ #include /* for chown() */ #endif -#include /* for stat() */ +#ifdef __CYGWIN__ +#include /* for _setmode(), O_BINARY */ +#endif +#include /* for stat(), maybe chmod() */ #include /* for strrchr() */ #include "file.h" @@ -67,3 +71,35 @@ const char *flac__file_get_basename(const char *srcpath) } return ++p; } + +FILE *file__get_binary_stdin() +{ + /* if something breaks here it is probably due to the presence or + * absence of an underscore before the identifiers 'setmode', + * 'fileno', and/or 'O_BINARY'; check your system header files. + */ +#if defined _MSC_VER || defined __MINGW32__ + _setmode(_fileno(stdin), _O_BINARY); +#elif defined __CYGWIN__ + /* almost certainly not needed for any modern Cygwin, but let's be safe... */ + setmode(_fileno(stdin), _O_BINARY); +#endif + + return stdin; +} + +FILE *file__get_binary_stdout() +{ + /* if something breaks here it is probably due to the presence or + * absence of an underscore before the identifiers 'setmode', + * 'fileno', and/or 'O_BINARY'; check your system header files. + */ +#if defined _MSC_VER || defined __MINGW32__ + _setmode(_fileno(stdout), _O_BINARY); +#elif defined __CYGWIN__ + /* almost certainly not needed for any modern Cygwin, but let's be safe... */ + setmode(_fileno(stdout), _O_BINARY); +#endif + + return stdout; +} diff --git a/src/flac/file.h b/src/flac/file.h index 6c55fc42..b902bd6c 100644 --- a/src/flac/file.h +++ b/src/flac/file.h @@ -20,9 +20,14 @@ #define flac__file_h #include /* for off_t */ +#include /* for FILE */ void flac__file_copy_metadata(const char *srcpath, const char *destpath); off_t flac__file_get_filesize(const char *srcpath); const char *flac__file_get_basename(const char *srcpath); +/* these will forcibly set stdin/stdout to binary mode (for OSes that require it) */ +FILE *file__get_binary_stdin(); +FILE *file__get_binary_stdout(); + #endif diff --git a/src/flac/main.c b/src/flac/main.c index fa515411..fcaa4262 100644 --- a/src/flac/main.c +++ b/src/flac/main.c @@ -660,7 +660,7 @@ int encode_file(const char *infilename, const char *forced_outfilename, FLAC__bo if(0 == strcmp(infilename, "-")) { infilesize = -1; - encode_infile = stdin; + encode_infile = file__get_binary_stdin(); } else { infilesize = flac__file_get_filesize(infilename); diff --git a/src/libFLAC/file_decoder.c b/src/libFLAC/file_decoder.c index 1039cdfe..3de04636 100644 --- a/src/libFLAC/file_decoder.c +++ b/src/libFLAC/file_decoder.c @@ -21,6 +21,12 @@ #include /* for malloc() */ #include /* for strcmp() */ #include /* for stat() */ +#if defined _MSC_VER || defined __MINGW32__ +#include /* for _setmode() */ +#include /* for _O_BINARY */ +#elif defined __CYGWIN__ +#include /* for _setmode(), O_BINARY */ +#endif #include "FLAC/assert.h" #include "protected/file_decoder.h" #include "protected/seekable_stream_decoder.h" @@ -32,6 +38,7 @@ * ***********************************************************************/ +static FILE *get_binary_stdin_(); static FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data); static FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data); static FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); @@ -153,7 +160,7 @@ FLAC__FileDecoderState FLAC__file_decoder_init(FLAC__FileDecoder *decoder) decoder->private_->seekable_stream_decoder = 0; if(0 == decoder->private_->filename) - decoder->private_->file = stdin; + decoder->private_->file = get_binary_stdin_(); else decoder->private_->file = fopen(decoder->private_->filename, "rb"); @@ -385,6 +392,25 @@ FLAC__bool FLAC__file_decoder_seek_absolute(FLAC__FileDecoder *decoder, FLAC__ui * ***********************************************************************/ +/* + * This will forcibly set stdin to binary mode (for OSes that require it) + */ +FILE *get_binary_stdin_() +{ + /* if something breaks here it is probably due to the presence or + * absence of an underscore before the identifiers 'setmode', + * 'fileno', and/or 'O_BINARY'; check your system header files. + */ +#if defined _MSC_VER || defined __MINGW32__ + _setmode(_fileno(stdin), _O_BINARY); +#elif defined __CYGWIN__ + /* almost certainly not needed for any modern Cygwin, but let's be safe... */ + setmode(_fileno(stdin), _O_BINARY); +#endif + + return stdin; +} + FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data) { FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;