ref: 87a8264b2ae5a088cd1b4a37bf1aa761267205b8
parent: 87c1572b1d7a007d54d47113b995325293b13d54
author: robs <robs>
date: Thu Dec 21 12:56:24 EST 2006
Output file clobbering protection; clean-ups
--- a/ChangeLog
+++ b/ChangeLog
@@ -74,6 +74,8 @@
by 0dB [Bug# 1395781]. (robs)
o Removed (for output file only) the potentially
problematic -v option. Use the vol effect instead. (robs)
+ o Added prompt to overwrite pre-existing output file (unless overridden
+ with --force). (robs)
sox-12.18.2
-----------
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -149,8 +149,7 @@
_PKG_TEXT
])],
- [AC_MSG_RESULT([no])
- $4])
+ [$4])
elif test $pkg_failed = untried; then
ifelse([$4], , [AC_MSG_FAILURE(dnl
[The pkg-config script could not be found or is too old. Make sure it
--- a/sox.1
+++ b/sox.1
@@ -11,7 +11,7 @@
..
.TH SoX 1 "November 14, 2006" "sox" "Sound eXchange"
.SH NAME
-sox \- Sound eXchange : universal sound sample translator
+SoX \- Sound eXchange : universal sound sample translator and processor
.SH SYNOPSIS
.P
\fBsox\fR \fIinfile1\fR [ \fIinfile2\fR ... ] \fIoutfile\fR
@@ -34,63 +34,52 @@
.br
[ \fIeffect\fR [ \fIeffect options\fR ] ... ]
.SH DESCRIPTION
-The
.I SoX
-audio file transformer can read and write most popular audio formats and
-optionally apply effects to them; it includes a simple audio synthesiser,
-and on unix-like systems, can also play and record sound files.
+reads and writes most popular audio formats and can optionally apply
+effects to them; it includes a basic audio synthesiser, and on unix-like
+systems, can play and record sound files.
.P
-Multiple input files can be combined to form the output file using one
-of three methods: `concatenate', `mix', or `merge'. There is currently
-the restriction that multiple input files must have the same number of
-channels and the same sample rate (though not necessarily the same file
-format).
+.I SoX
+can also combine multiple input files (with the same sample rate and
+number of channels) to form one output file using one of three methods:
+`concatenate' (the default), `mix', or `merge'. \fBsoxmix\fR is an
+alias for \fBsox\fR for which the the default combining method is `mix'.
.P
-The default combining method for \fBsox\fR is `concatenate';
-\fBsoxmix\fR is an alias for \fBsox\fR for which the the default
-combining method is `mix'.
-.P
-Exit status is 0 for no error, 1 if there is a problem with the command-line arguments, and 2 if an error occurs during file processing.
-.P
\fBFile Format Types\fR
.br
There are two types of audio file format that
.I SoX
-can work with. The first is "self-describing". Such formats
-include a header that completely describe the characteristics of
-the audio data that follows.
-The header may also allow the inclusion of textual "comments" that can
-be used to describe the audio in some way, e.g. for music, the title,
-the author, etc.
-.P
-The second type is headerless data, often called raw data.
-For this type, a
-user must pass enough information to
+can work with. The first is "self-describing". Such formats include a
+header that completely describes the characteristics of the audio data
+that follows.
+The second type is "headerless" data, often called raw data. For a file
+of this type, the audio data characteristics are sometimes described by
+the filename extension, sometimes by giving options on the
.I SoX
-on the command line so that it knows what type of data it contains,
-though in some cases, the audio filename extension may imply some
-of this information.
+command line, and sometimes by a combination of the two.
.P
-Audio data can usually be totally described by four characteristics:
+The following four characteristics are usually sufficent to describe
+audio data so that it can be processed with \fISoX\fR:
.TP 10
rate
The sample rate is in samples per second. For example, CDs use 44,100 samples per second.
.TP 10
data size
-The precision the data is stored in. Most popular are 8-bit bytes or 16-bit
-words.
+The number of bits (or bytes) used to store each sample. Most popular are
+8-bit (i.e. one byte) and 16-bit (i.e. two bytes, or one "word").
.TP 10
data encoding
-What encoding the data type uses. Examples are u-law, ADPCM, or signed linear data.
+The way in which each audio sample is stored (or "encoded").
+Some encodings involve an element of "compression".
+Commonly-used encoding types include: floating-point, u-law, ADPCM, signed
+linear, FLAC, etc.
.TP 10
channels
The number of audio channels contained in the file. 1 ("mono") and 2
("stereo") are widely used.
.P
-Refer to the
-.B soxexam(1)
-manual page for a long description with examples on how to use SoX with
-various file formats.
+The term "bit-rate" is sometimes used as an overall measure of an audio
+format and usually includes elements of all of the above.
.P
\fBFormat Conversion\fR
.br
@@ -100,12 +89,12 @@
(i.e. converting back again would yield an exact copy of the original
audio signal)
where it
-can be, i.e. when not using "lossy" compression (e.g. A-law, MP3, etc.)
+can be, i.e. when not using "lossy" compression (A-law, MP3, etc.)
and the number of bits used in the destination format is not less than
in the source format.
E.g. converting from an 8-bit PCM format to a 16-bit PCM format is
-lossless but converting from a 24-bit PCM format to a 16-bit PCM format isn't.
+lossless but converting from a 8-bit PCM format to (8-bit) A-law isn't.
When performing a lossy conversion,
.I SoX
uses rounding to retain as much accuracy as possible in the
@@ -115,7 +104,7 @@
.br
Clipping is distortion that occurs when an audio signal
level exceeds the range of the chosen representation.
-Clipping is nearly always undesirable and so should usually be corrected by
+It is nearly always undesirable and so should usually be corrected by
adjusting the audio volume prior to the point at which clipping occurs.
In \fISoX\fR, clipping could occur, as you might expect, when using the
@@ -124,7 +113,7 @@
other effects, when converting one format to another, and even when
simply playing the audio.
-Playing an audio file often involves reampling, and processing by
+Playing an audio file often involves resampling, and processing by
analogue components that can introduce a small DC offset and/or
amplification, all of which can produce distortion if the audio signal
level was intially too close to the clipping point.
@@ -134,8 +123,14 @@
range available, as this will avoid the majority of clipping problems.
\fISoX\fR's
.I stat
-effect can assist here by displaying the signal level in an audio file.
+effect can assist in determining the signal level in an audio file; the
+.B vol
+effect can be used to preventing clipping e.g.
+ sox tinny.au better.au vol -6 dB bass +6
+
+guarantees that the bass boost will not clip.
+
If clipping occurs at any point during processing, then
.I SoX
will display a warning message to that effect.
@@ -171,6 +166,11 @@
.P
.br
mixes together two sound files.
+.P
+Refer to the
+.B soxexam(1)
+manual page for a long description with examples on how to use SoX with
+various file formats and options.
.PP
\fBSpecial Filenames\fR
.TP 10
@@ -197,13 +197,20 @@
but is left here for historical reasons.
.PP
\fBGlobal Options\fR
+.br
+These options can be specified on the command line at any point
+before the first effect name.
.TP 10
+\fB\fB\-\-force\fR
+Force \fISoX\fR to overwrite an existing file with the same name as that
+given for the output file without first prompting to do so.
+.TP 10
\fB\-h\fR, \fB\-\-help\fR
-Print version number and usage information.
+Show version number and usage information.
.TP 10
\fB--help-effect=name\fR
-Display usage information on the specified effect. The name
-\fBall\fR can be used to display usage on all effects.
+Show usage information on the specified effect. The name
+\fBall\fR can be used to show usage on all effects.
.TP 10
\fB\-m\fR, \fB\-\-mix\fR
Set the input file combining method to `mix'.
@@ -244,7 +251,7 @@
processed in terms of audio running time instead of samples.
.TP 10
\fB--version\fR
-Print version number and exit.
+Show version number and exit.
.IP "\fB\-V[level]\fP"
Set verbosity.
.I SoX
@@ -318,21 +325,27 @@
will be inverted.
See the \fBstat\fR effect for information on how to find
-the maximum volume of an audio file to help with setting
+the maximum volume of an audio file; this can be used to help select
suitable values for this option.
.P
-The \fB-V\fR option will show what input file volume adjustments
-have been selected (either manually or automatically).
+The \fB-V\fR option can be used to show the input file volume adjustments
+that have been selected (either manually or automatically).
.PP
\fBInput And Output File Format Options\fR
.br
-These options apply to the input or output file that they immediately precede.
+These options apply to the input or output file whose name they
+immediately precede on the command line.
.PP
Self describing input files can contain all the format information in the header and so don't generally need format options. Headerless input files lack this information and so format options must be used to inform SoX of the file's data type, sample rate, and number of channels.
.PP
-By default, SoX attempts to write audio data using the same data type, sample rate, and channel count as the input data. If the user wants the output file to be of a different format then format options can be used to specify the differences.
+By default, SoX attempts to write audio data using the same data type,
+sample rate, and channel count as the input data. If this is not what
+is wanted, then format options can be used to specify the differences.
.PP
-If an output file format doesn't support the same data type, sample rate, or channel count as the input file format, then SoX will automatically select the closest values it does support so that the user does not have to specify these format change options manually.
+If an output file format does not support the same data type, sample
+rate, or channel count as the input file format, then unless overriden
+on the command line, SoX will automatically select the closest values
+that the format does support.
.TP 10
\fB-c \fIchannels\fR
The number of sound channels in the data file.
@@ -354,8 +367,9 @@
If no rate change effect is specified then a default one will be chosen.
.TP 10
\fB-t \fIfiletype\fR
-gives the file type of the sound sample file. Useful when file extension
-is not standard or can not be determined by looking at the header of the file.
+Gives the file type of the sound sample file. This is useful when the
+file extension is non-standard or when the type can not be determined by
+looking at the header of the file.
The
.I -t
@@ -365,7 +379,7 @@
will exit with an appropriate error message if such a header is not
actually present.
-See the section \fRFILE TYPES\fR for a list of supported file types.
+See \fBFILE TYPES\fR below for a list of supported file types.
.TP 10
\fB-x\fR
The sample data comes from a machine with the opposite word order
@@ -381,8 +395,8 @@
U-law (actually shorthand for mu-law) and A-law are the U.S. and
international standards for logarithmic telephone sound compression.
-When uncompressed u-law has roughly the precision of 14-bit PCM audio
-and A-law has roughly the precision of 13-bit PCM audio.
+When uncompressed u-law has roughly the precision of 13-bit PCM audio
+and A-law has roughly the precision of 14-bit PCM audio.
A-law and u-law data is sometimes encoded using a reversed bit-ordering
(i.e. MSB becomes LSB). Internally, SoX understands how to work with
@@ -403,9 +417,12 @@
and slightly lower fidelity than Microsoft's flavor of ADPCM.
IMA ADPCM is also called DVI ADPCM.
-GSM is a standard used for telephone sound compression in
-European countries and it's gaining popularity because of its
-quality. It usually is CPU intensive to work with GSM audio data.
+GSM is currently used for the vast majority of the world's digital
+wireless telephone calls. It utilises several audio
+formats with different bit-rates and associated speech quality.
+.I SoX
+has support for GSM's original 13kbps "Full Rate" audio format.
+It is usually CPU intensive to work with GSM audio data.
.TP 10
\fB-1/-2/-3/-4/-8\fR
The sample data size is 1, 2, 3, 4, or 8 bytes; i.e 8, 16, 24, 32, or 64 bits.
@@ -416,9 +433,13 @@
.PP
\fBOutput File Format Options\fR
.br
-These options apply to and may precede only the output file.
+These options apply to only the output file and may only precede the output
+filename on the command line.
.TP 10
\fB--comment \fItext\fR
+ (The header may also allow the inclusion of textual
+"comments" that can be used to describe the audio in some way, e.g. for
+music, the title, the author, etc.)
Specify the comment text to store in the output file header (where applicable).
.TP 10
\fB--comment-file \fIfilename\fR
@@ -426,10 +447,11 @@
file header (where applicable).
.TP 10
\fB-C \fIcompression-factor\fR
-The compression factor for variably compressing output file formats.
-If this option is not given, then a default compression factor will apply.
-The compression factor is interpreted differently for different compressing file formats.
-See the description of the file formats that use this parameter for more information.
+The compression factor for variably compressing output file formats. If
+this option is not given, then a default compression factor will apply.
+The compression factor is interpreted differently for different
+compressing file formats. See the description of the file formats that
+use this option for more information.
.SH FILE TYPES
.B Determining The File Type
.br
@@ -550,7 +572,7 @@
meaning that audio is compressed in FLAC without any loss in
quality.
-.B SoX
+.I SoX
can decode native FLAC files (.flac) but not Ogg FLAC files (.ogg).
[But see
.B .ogg
@@ -557,7 +579,7 @@
below for information relating to support for Ogg
Vorbis files.]
-.B SoX
+.I SoX
has rudimentary support for writing FLAC files: it can encode to
native FLAC using compression levels 0 to 8. 8 is the default
compression level and gives the best (but slowest) compression;
@@ -567,12 +589,12 @@
option (see above) with a whole number from 0 to 8.
Note that Replay Gain information is not used by
-.B SoX
+.I SoX
if present in FLAC input files and is not generated by
-.B SoX
+.I SoX
for FLAC
output files, however
-.B SoX
+.I SoX
will copy input file "comments" (which can be used to hold Replay
Gain information) to output files that
support comments, so FLAC output files may contain Replay Gain
@@ -579,12 +601,12 @@
information if some was present in the input file. In this case the
Replay Gain information in the output file is likely to be incorrect and so should
be recalculated using a tool that supports this (not
-.B SoX
+.I SoX
).
.br
FLAC support in
-.B SoX
+.I SoX
is optional and requires optional FLAC libraries. To
see if there is support for FLAC run \fBsox -h\fR and look for
it under the list of supported file formats as "flac".
@@ -622,9 +644,11 @@
.TP 10
.B .mp3
MP3 Compressed Audio. MP3 (MPEG Layer 3) is part of the
-MPEG standards for audio and video compression. It is a lossy
+MPEG standards for audio and video compression. It is a lossy
compression format that achieves good compression rates with little
-quality loss. Also see Ogg Vorbis for a similar format.
+quality loss. See also
+.B Ogg Vorbis
+for a similar format.
MP3 support in
.B SoX
@@ -672,7 +696,9 @@
Ogg Vorbis is a open, patent-free CODEC designed for compressing music
and streaming audio. It is a lossy compression format (similar to MP3,
VQF & AAC) that achieves good compression rates with a minimum amount of
-quality loss. Also see MP3 for a similar format.
+quality loss. See also
+.B MP3
+ for a similar format.
.B SoX
can decode all types of Ogg Vorbis files, and can encode at different
@@ -935,21 +961,23 @@
These effects support the \fI-o\fR option (see above).
.TP 10
bandreject \fIfrequency bandwidth\fR
-See \fI bandpass\fR.
+Apply a band-reject filter.
+
+See the description of the \fBbandpass\fR effect for details.
.TP 10
bass|treble \fIgain\fR [\fIfrequency\fR] [\fIslope\fR]
-Boost or cut the bass (lower) or treble (upper) frequencies of
-the audio signal using a two-pole shelving filter with (by
-default) a response similar to that of a standard hi-fi's
-(Baxandall) tone controls.
+Boost or cut the bass (lower) or treble (upper) frequencies of the audio
+signal using a two-pole shelving filter with a response similar to that
+of a standard hi-fi's (Baxandall) tone controls. This is also
+known as shelving equalisation or EQ.
\fIgain\fR gives the dB gain at 0Hz (for \fIbass\fR), or whichever is
-the lower of ~22kHz and the Nyquist frequency (for \fItreble\fR). Its
+the lower of ~22kHz and the Nyquist frequency (for \fItreble\fR). Its
useful range is about -20.0 (for a large cut) to +20.0 (for a large
-boost). N.B. When using a positive \fIgain\fR, in order to prevent
-clipping, it may be necessary to precede this effect with a suitable
-attenuation using the \fI-v\fR option or the \fIvol\fR effect. SoX
-will display a warning message should clipping occur.
+boost).
+Beware of
+.B Clipping
+when using a positive \fIgain\fR.
If desired, the filter can be fine-tuned using the following
optional parameters (in either order):
@@ -964,9 +992,9 @@
about 0.3 (for a gentle slope) to 1 (for a steep slope). The
default value is 0.5.
-The \fIbass\fR and \fItreble\fR effects support the \fI-o\fR
-option (see above).
+These effects support the \fI-o\fR option (see above).
+See \fBequalizer\fR for a peaking equalisation effect.
.TP
chorus \fIgain-in gain-out delay decay speed depth
.TP 10
@@ -1015,11 +1043,6 @@
allows the compander to effectively operate in a "predictive" rather than a
reactive mode.
.TP 10
-copy
-Copy the input file to the output file.
-This is the default effect if both files have the same
-sampling rate.
-.TP 10
dcshift \fIshift\fR [ \fIlimitergain\fR ]
DC Shift the audio data, with basic linear amplitude formula.
This is most useful if your audio data tends to not be centered around
@@ -1041,6 +1064,7 @@
.TP 10
dither [\fIdepth\fR]
+Apply dithering to the audio signal.
Dithering deliberately adds white noise to the signal
in order to mask audible quantization effects that
can occur if the output sample size is less than 24 bits.
@@ -1074,11 +1098,25 @@
Gain-out is the volume of the output.
.TP 10
equalizer \fIcentral\-frequency\fR \fIQ\fR \fIgain\fR
-Apply an equalizer effect which allows you to modify the amplitude (\fIgain\fR) of a signal at and around (\fIQ\-factor\fR) a central frequency (\fIcentral\-frequency\fR), leaving all other frequencies untouched (unlike regular bandpass/bandreject filters).
+Apply a two-pole peaking equalisation (EQ) filter.
+This allows modification (\fIgain\fR) of the signal level at and
+around (\fIQ\-factor\fR) a central frequency (\fIcentral\-frequency\fR),
+leaving all other frequencies untouched (unlike
+bandpass/bandreject filters).
-\fIcentral\-frequency\fR gives the central frequency in Hz, \fIQ\fR is the Q\-factor (see http://en.wikipedia.org/wiki/Q_factor), and \fIgain\fR is the gain or attenuation in dB.
+\fIcentral\-frequency\fR is the filter's central frequency in Hz, \fIQ\fR
+its Q\-factor (see http://en.wikipedia.org/wiki/Q_factor), and
+\fIgain\fR is the gain or attenuation in dB.
+Beware of
+.B Clipping
+when using a positive \fIgain\fR.
+In order to produce complex equalisation curves, this effect
+can be given several times, each with a different central frequency.
+
This effect supports the \fI-o\fR option (see above).
+
+See \fBbass\fR and \fBtreble\fR for shelving equalisation effects.
.TP 10
fade [ \fItype\fR ] \fIfade-in-length\fR [ \fIstop-time\fR [ \fIfade-out-length\fR ] ]
Add a fade effect to the beginning, end, or both of the audio data.
@@ -1166,13 +1204,17 @@
These effects support the \fI-o\fR option (see above).
.TP 10
lowp \fIfrequency\fR
-See the description of the \fIhighp\fR effect for details.
+Apply a low-pass filter.
+
+See the description of the \fBhighp\fR effect for details.
.TP 10
lowpass \fIfrequency\fB
-See the description of the \fIhighpass\fR effect for details.
+Apply a low-pass filter.
+
+See the description of the \fBhighpass\fR effect for details.
.TP 10
mask [\fIdepth\fR]
-This effect is just an alias of the "dither" effect but is left
+This effect is just an alias of the \fBdither\fR effect but is left
here for historical reasons.
.TP
mcompand "\fIattack1,decay1\fR[,\fIattack2,decay2\fR...]
@@ -1645,8 +1687,9 @@
.TP 10
treble \fIgain\fR [\fIfrequency\fR] [\fIslope\fR]
-See the description of the \fIbass\fR effect for details.
+Apply a treble tone control effect.
+See the description of the \fBbass\fR effect for details.
.TP 10
trim \fIstart\fR [ \fIlength\fR ]
Trim can trim off unwanted audio data from the beginning and end of the
@@ -1707,6 +1750,9 @@
Not specifying this parameter will cause no limiter to be used. In verbose
mode, this effect will display the percentage of audio data that needed to be
limited.
+.SH DIAGNOSTICS
+Exit status is 0 for no error, 1 if there is a problem with the
+command-line arguments, or 2 if an error occurs during file processing.
.SH BUGS
Please report any bugs found in this version of SoX to the mailing list
(sox-users@lists.sourceforge.net).
--- a/src/sox.c
+++ b/src/sox.c
@@ -61,6 +61,8 @@
#define S_IFREG _S_IFREG
#define fstat _fstat
#define strdup _strdup
+#define isatty _isatty
+#include <io.h>
#endif
/*
@@ -81,6 +83,7 @@
static st_size_t mixing_clips = 0;
static int writing = 1; /* are we writing to a file? assume yes. */
static bool repeatable_random = false; /* Whether to invoke srand. */
+static bool force_overwrite = false;
static st_globalinfo_t globalinfo = {false, 1};
static char uservolume = 0;
@@ -104,8 +107,9 @@
char *filetype;
st_signalinfo_t info;
double volume;
- st_size_t volume_clips;
char *comment;
+
+ st_size_t volume_clips; /* not actually an option */
} * file_options_t;
/* local forward declarations */
@@ -179,7 +183,22 @@
}
}
-
+static bool overwrite_permitted(char const * filename)
+{
+ char c;
+
+ if (force_overwrite) {
+ st_report("Overwriting '%s'", filename);
+ return true;
+ }
+ st_warn("Output file '%s' already exists", filename);
+ if (!isatty(fileno(stdin)))
+ return false;
+ do fprintf(stderr, "%s sox: overwrite '%s' (y/n)? ", myname, filename);
+ while (scanf(" %c%*[^\n]", &c) != 1 || !strchr("yYnN", c));
+ return c == 'y' || c == 'Y';
+}
+
/* Cleanup atexit() function, hence always called. */
static void cleanup(void)
{
@@ -217,7 +236,6 @@
int main(int argc, char **argv)
{
- file_options_t fo;
size_t i;
myname = argv[0];
@@ -237,8 +255,11 @@
* found.
*/
while (optind < argc && !is_effect_name(argv[optind])) {
+ file_options_t fo;
+ struct file_options fo_none;
+
if (file_count >= MAX_FILES) {
- st_fail("too many filenames. max of %d input files and 1 output file", MAX_INPUT_FILES);
+ st_fail("Too many filenames; maximum is %d input files and 1 output file", MAX_INPUT_FILES);
exit(1);
}
@@ -249,7 +270,7 @@
fo->info.compression = HUGE_VAL;
fo->volume = HUGE_VAL;
fo->volume_clips = 0;
- file_opts[file_count++] = fo;
+ fo_none = *fo;
if (doopts(fo, argc, argv) == true) { /* is null file? */
if (fo->filetype != NULL && strcmp(fo->filetype, "null") != 0)
@@ -257,10 +278,15 @@
fo->filetype = "null";
fo->filename = strdup(fo->filetype);
} else {
- if (optind >= argc)
- usage("missing filename"); /* No return */
+ if (optind >= argc) {
+ if (memcmp(fo, &fo_none, sizeof(fo_none)) != 0)
+ usage("missing filename"); /* No return */
+ free(fo);
+ continue;
+ }
fo->filename = strdup(argv[optind++]);
}
+ file_opts[file_count++] = fo;
}
/* Make sure we got at least the required # of input filenames */
@@ -319,9 +345,6 @@
srand(t);
}
- signal(SIGINT, sigint);
- signal(SIGTERM, sigint);
-
process();
if (mixing_clips > 0)
@@ -386,6 +409,7 @@
{"help-effect", required_argument, NULL, 0},
{"comment", required_argument, NULL, 0},
{"comment-file", required_argument, NULL, 0},
+ {"force", no_argument, NULL, 0},
{"help", no_argument, NULL, 'h'},
{"mix", no_argument, NULL, 'm'},
@@ -423,6 +447,10 @@
case 3:
fo->comment = read_comment_file(optarg);
break;
+
+ case 4:
+ force_overwrite = true;
+ break;
}
break;
@@ -625,7 +653,8 @@
}
file_desc[file_count - 1] =
- st_open_write_instr(options->filename,
+ st_open_write_instr(overwrite_permitted,
+ options->filename,
&options->info,
options->filetype,
comment,
@@ -715,10 +744,11 @@
supposed to be ST_EOF, so we can't test that in order to know
whether to drain. */
if (flowstatus == 0) {
-
/* Run input data through effects and get more until olen == 0
- * (or ST_EOF).
+ * (or ST_EOF) or user-abort.
*/
+ signal(SIGINT, sigint);
+ signal(SIGTERM, sigint);
do {
if (combine_method == SOX_CONCAT) {
ilen[0] = st_read(file_desc[current_input], efftab[0].obuf,
@@ -1543,6 +1573,7 @@
"\n"
"Global options (gopts) (can be specified at any point before the first effect):\n"
"\n"
+ "--force overwrite output file without first prompting\n"
"-h, --help display version number and usage information\n"
"--help-effect=name\n"
" display usage of specified effect. use 'all' to display all\n"
--- a/src/st.h
+++ b/src/st.h
@@ -379,12 +379,15 @@
extern ft_t st_open_read(const char *path, const st_signalinfo_t *info,
const char *filetype);
-extern ft_t st_open_write(const char *path, const st_signalinfo_t *info,
- const char *filetype, const char *comment);
-extern ft_t st_open_write_instr(const char *path, const st_signalinfo_t *info,
- const char *filetype, const char *comment,
- const st_instrinfo_t *instr,
- const st_loopinfo_t *loops);
+ft_t st_open_write_instr(
+ bool (*overwrite_permitted)(char const * filename),
+ const char *path,
+ const st_signalinfo_t *info,
+ const char *filetype,
+ const char *comment,
+ const st_instrinfo_t *instr,
+ const st_loopinfo_t *loops);
+#define st_open_write(a,b,c,d,e) st_open_write_instr(a,b,c,d,e,NULL,NULL)
extern st_size_t st_read(ft_t ft, st_sample_t *buf, st_size_t len);
extern st_size_t st_write(ft_t ft, const st_sample_t *buf, st_size_t len);
extern int st_close(ft_t ft);
--- a/src/stio.c
+++ b/src/stio.c
@@ -164,10 +164,14 @@
#define LASTCHAR '/'
#endif
-ft_t st_open_write_instr(const char *path, const st_signalinfo_t *info,
- const char *filetype, const char *comment,
- const st_instrinfo_t *instr,
- const st_loopinfo_t *loops)
+ft_t st_open_write_instr(
+ bool (*overwrite_permitted)(char const * filename),
+ const char *path,
+ const st_signalinfo_t *info,
+ const char *filetype,
+ const char *comment,
+ const st_instrinfo_t *instr,
+ const st_loopinfo_t *loops)
{
ft_t ft = (ft_t)xcalloc(sizeof(struct st_soundstream), 1);
int i;
@@ -208,7 +212,7 @@
if (!ft->filetype || st_gettype(ft, no_filetype_given) != ST_SUCCESS)
{
- st_warn("Unknown output file format for '%s': %s",
+ st_fail("Unknown output file format for '%s': %s",
ft->filename,
ft->st_errstr);
goto output_error;
@@ -231,11 +235,17 @@
SET_BINARY_MODE(stdout);
ft->fp = stdout;
}
- else if ((ft->fp = fopen(ft->filename, "wb")) == NULL)
- {
- st_warn("Can't open output file '%s': %s", ft->filename,
+ else {
+ struct stat st;
+ if (!stat(ft->filename, &st) && !overwrite_permitted(ft->filename)) {
+ st_fail("Permission to overwrite '%s' denied", ft->filename);
+ goto output_error;
+ }
+ if ((ft->fp = fopen(ft->filename, "wb")) == NULL) {
+ st_fail("Can't open output file '%s': %s", ft->filename,
strerror(errno));
goto output_error;
+ }
}
/* stdout tends to be line-buffered. Override this */
@@ -242,7 +252,7 @@
/* to be Full Buffering. */
if (setvbuf (ft->fp, NULL, _IOFBF, sizeof(char)*ST_BUFSIZ))
{
- st_warn("Can't set write buffer");
+ st_fail("Can't set write buffer");
goto output_error;
}
@@ -263,13 +273,13 @@
/* Read and write starters can change their formats. */
if ((*ft->h->startwrite)(ft) != ST_SUCCESS)
{
- st_warn("Failed writing %s: %s", ft->filename, ft->st_errstr);
+ st_fail("Failed writing %s: %s", ft->filename, ft->st_errstr);
goto output_error;
}
if (st_checkformat(ft) )
{
- st_warn("bad output format for file %s: %s", ft->filename,
+ st_fail("bad output format for file %s: %s", ft->filename,
ft->st_errstr);
goto output_error;
}
@@ -282,12 +292,6 @@
free(ft->filetype);
free(ft);
return NULL;
-}
-
-ft_t st_open_write(const char *path, const st_signalinfo_t *info,
- const char *filetype, const char *comment)
-{
- return st_open_write_instr(path, info, filetype, comment, NULL, NULL);
}
st_size_t st_read(ft_t ft, st_sample_t *buf, st_size_t len)