ref: b8a72eb31135e817d63325d463896e6cb7f70bc3
parent: cb3ed7449799a52613bd433da94b3fca5cc43115
author: robs <robs>
date: Sat Mar 8 17:32:28 EST 2008
Fix ungraceful handling of out of disc space and other writeerrors
--- a/ChangeLog
+++ b/ChangeLog
@@ -71,6 +71,8 @@
16-bit, etc.) to input handler. (robs)
o Fix auto-detect of hcom files. (robs)
o Added auto-detect for caf, txw & sf files. (robs)
+ o Fix ungraceful handling of out of disc space and other write
+ errors (bug was introduced in 14.0.0). (robs)
Internal improvements:
--- a/src/effects.c
+++ b/src/effects.c
@@ -321,6 +321,8 @@
}
} else if (have_imin && flow_effect(chain, e) == SOX_EOF) {
flow_status = SOX_EOF;
+ if (e == chain->length - 1)
+ break;
source_e = e;
draining = sox_true;
}
--- a/src/example1.c
+++ b/src/example1.c
@@ -40,8 +40,9 @@
static int output_flow(sox_effect_t *effp UNUSED, sox_sample_t const * ibuf,
sox_sample_t * obuf UNUSED, sox_size_t * isamp, sox_size_t * osamp)
{
- size_t len = sox_write(out, ibuf, *osamp);
+ size_t len = sox_write(out, ibuf, *isamp);
+ *osamp = 0;
if (len != *isamp) {
fprintf(stderr, "%s: %s\n", out->filename, out->sox_errstr);
return SOX_EOF;
--- a/src/misc.c
+++ b/src/misc.c
@@ -146,8 +146,7 @@
return (SOX_SAMPLE_MAX >> shift) << shift;
}
-const char sox_readerr[] = "Premature EOF while reading sample file.";
-const char sox_writerr[] = "Error writing sample file. You are probably out of disk space.";
+const char sox_readerr[] = "Premature EOF while reading sample file";
/* Lookup table to reverse the bit order of a byte. ie MSB become LSB */
uint8_t const cswap[256] = {
@@ -215,7 +214,11 @@
size_t sox_writebuf(sox_format_t * ft, void const *buf, sox_size_t len)
{
size_t ret = fwrite(buf, 1, len, ft->fp);
- return (ferror(ft->fp) || (feof(ft->fp) && ret == 0)) ? 0 : ret;
+ if (ret != len) {
+ sox_fail_errno(ft, errno, "error writing output file");
+ clearerr(ft->fp); /* Allows us to seek back to write header */
+ }
+ return ret;
}
sox_size_t sox_filelength(sox_format_t * ft)
@@ -291,10 +294,7 @@
int sox_writes(sox_format_t * ft, char const * c)
{
if (sox_writebuf(ft, c, strlen(c)) != strlen(c))
- {
- sox_fail_errno(ft,errno,sox_writerr);
return(SOX_EOF);
- }
return(SOX_SUCCESS);
}
--- a/src/raw.c
+++ b/src/raw.c
@@ -94,8 +94,7 @@
ctype *data = xmalloc(sizeof(ctype) * len); \
for (n = 0; n < len; n++) \
data[n] = cast(buf[n], ft->clips); \
- if ((nwritten = sox_write_ ## type ## _buf(ft, (uctype *)data, len)) != len) \
- sox_fail_errno(ft, errno, sox_writerr); \
+ nwritten = sox_write_ ## type ## _buf(ft, (uctype *)data, len); \
free(data); \
return nwritten; \
}
--- a/src/sox.c
+++ b/src/sox.c
@@ -271,7 +271,7 @@
"Invalid argument",
"Unsupported file format",
};
- sox_fail("%s: %s (%s)", ft->filename, ft->sox_errstr,
+ sox_fail("%s: %s: %s", ft->filename, ft->sox_errstr,
ft->sox_errno < SOX_EHDR?
strerror(ft->sox_errno) : sox_strerror[ft->sox_errno - SOX_EHDR]);
}
@@ -430,11 +430,12 @@
return &handler;
}
-static int output_flow(sox_effect_t *effp UNUSED, sox_sample_t const * ibuf,
- sox_sample_t * obuf UNUSED, sox_size_t * isamp, sox_size_t * osamp)
+static int output_flow(sox_effect_t *effp, sox_sample_t const * ibuf,
+ sox_sample_t * obuf, sox_size_t * isamp, sox_size_t * osamp)
{
size_t len;
+ (void)effp, (void)obuf;
if (show_progress) for (len = 0; len < *isamp; len += effp->in_signal.channels) {
omax[0] = max(omax[0], ibuf[len]);
omin[0] = min(omin[0], ibuf[len]);
@@ -447,16 +448,13 @@
omin[1] = omin[0];
}
}
- for (*osamp = *isamp; *osamp; ibuf += len, *osamp -= len) {
- len = sox_write(ofile->ft, ibuf, *osamp);
- if (len == 0) {
- sox_warn("Error writing: %s", ofile->ft->sox_errstr);
- return SOX_EOF;
- }
- if (user_abort) /* Don't get stuck in this loop. */
- return SOX_EOF;
+ *osamp = 0;
+ len = sox_write(ofile->ft, ibuf, *isamp);
+ output_samples += len / ofile->ft->signal.channels;
+ if (len != *isamp) {
+ display_error(ofile->ft);
+ return SOX_EOF;
}
- output_samples += *isamp / ofile->ft->signal.channels;
return SOX_SUCCESS;
}
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -296,7 +296,6 @@
extern sox_effects_globals_t sox_effects_globals;
extern const char sox_readerr[];
-extern const char sox_writerr[];
extern uint8_t const cswap[256];
--- a/src/soxio.c
+++ b/src/soxio.c
@@ -637,8 +637,9 @@
sox_size_t sox_write(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
{
- ft->olength += len;
- return ft->handler.write? (*ft->handler.write)(ft, buf, len) : 0;
+ sox_size_t ret = ft->handler.write? (*ft->handler.write)(ft, buf, len) : 0;
+ ft->olength += ret;
+ return ret;
}
#define TWIDDLE_BYTE(ub, type) \
@@ -711,8 +712,7 @@
sox_size_t n, nwritten; \
for (n = 0; n < len; n++) \
twiddle(buf[n], type); \
- if ((nwritten = sox_writebuf(ft, buf, len * size)) != len * size) \
- sox_fail_errno(ft, errno, sox_writerr); \
+ nwritten = sox_writebuf(ft, buf, len * size); \
return nwritten / size; \
}
@@ -735,8 +735,7 @@
twiddle(datum, type); \
sox_pack ## size(data + n * size, datum); \
} \
- if ((nwritten = sox_writebuf(ft, data, len * size)) != len * size) \
- sox_fail_errno(ft, errno, sox_writerr); \
+ nwritten = sox_writebuf(ft, data, len * size); \
free(data); \
return nwritten / size; \
}
--- a/src/voc.c
+++ b/src/voc.c
@@ -485,7 +485,7 @@
int16_t sw;
sox_size_t done = 0;
- if (v->samples == 0) {
+ if (len && v->samples == 0) {
/* No silence packing yet. */
v->silent = 0;
blockstart(ft);