]> git.alsa-project.org Git - alsa-utils.git/commitdiff
aplay: fix lurking capture file overwrite bug
authorDavid Fries <David@Fries.net>
Thu, 14 Apr 2016 04:32:46 +0000 (23:32 -0500)
committerTakashi Iwai <tiwai@suse.de>
Thu, 14 Apr 2016 12:35:42 +0000 (14:35 +0200)
If -d was given to arecord while commit
8aa13eec80eac312e4b99423909387660fb99b8f (now reverted) was in effect,
the last read would be shorter than the chunk size, but pcm_read would
read and return the chunk size, the samples were discarded, and
capture() continued in a loop because count never reached 0.  arecord
opens a new file each loop iteration, if arecord is dynamically naming
files, --use-strftime option or beyond the wave 2GB limit, this will
generate a series of header only wave files.  If the file is unique
the originally recorded data is lost and it will continue overwriting
the same file with a header only wave file.

While the current pcm_read can't fail (it can exit), it is better to
just fix this lurking bug in case it is "fixed" again.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
aplay/aplay.c

index 7acaa83f0873f417fcecf3d70b9095fcf88cbfc2..2da7ddac1c81d24d20988d2719e4e66833277177 100644 (file)
@@ -3067,11 +3067,14 @@ static void capture(char *orig_name)
                        size_t c = (rest <= (off64_t)chunk_bytes) ?
                                (size_t)rest : chunk_bytes;
                        size_t f = c * 8 / bits_per_frame;
-                       if (pcm_read(audiobuf, f) != f)
+                       if (pcm_read(audiobuf, f) != f) {
+                               in_aborting = 1;
                                break;
+                       }
                        if (write(fd, audiobuf, c) != c) {
                                perror(name);
-                               prg_exit(EXIT_FAILURE);
+                               in_aborting = 1;
+                               break;
                        }
                        count -= c;
                        rest -= c;
@@ -3091,7 +3094,7 @@ static void capture(char *orig_name)
                }
 
                if (in_aborting)
-                       break;
+                       prg_exit(EXIT_FAILURE);
 
                /* repeat the loop when format is raw without timelimit or
                 * requested counts of data are recorded