shithub: sox

Download patch

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);