Subject: bin/9134: audioplay should quit immediately on ^C
To: None <gnats-bugs@gnats.netbsd.org>
From: Ben Wong <hackerb9@u.washington.edu>
List: netbsd-bugs
Date: 01/08/2000 05:49:56
>Number: 9134
>Category: bin
>Synopsis: audioplay waits for buffer to drain even on a SIGINT
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Thu Jan 6 09:09:00 2000
>Last-Modified:
>Originator: Ben Wong
>Organization:
>Release: NetBSD-1.4.1
>Environment:
System: NetBSD ursula.wongs.net 1.4.1 NetBSD 1.4.1 (AMNESIAC) #7: Thu Oct 14 22:00:19 EDT 1999 hackerb9@ursula.wongs.net:/usr/src/sys/arch/i386/compile/AMNESIAC i386
>Description:
When using audioplay to play a sound, if the user hits ^C the sound
keeps playing for about five seconds while the buffer drains. This is
annoying but easily fixed.
>How-To-Repeat:
Assuming a largish sound file called "large.au" try this:
# Hit ^C shortly after starting to play the sound.
# Audioplay will not quit for another five seconds.
> audioplay large.au
^C
>Fix:
This can be fixed by watching for relevant signals and calling a
cleanup function to flush the audio buffer. Here is a patch which does
that.
% diff -u play.c.orig play.c
--- play.c.orig Tue Apr 13 03:13:41 1999
+++ play.c Thu Jan 6 12:00:18 2000
@@ -40,6 +40,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <signal.h>
#include <paths.h>
@@ -48,6 +49,7 @@
int main __P((int, char *[]));
void usage __P((void));
ssize_t audioctl_write_fromhdr __P((void *, size_t, int));
+void cleanup(int);
audio_info_t info;
int volume;
@@ -62,6 +64,9 @@
char const *play_errstring = NULL;
+int audiofd; /* Usually open to "/dev/audio" */
+
+
int
main(argc, argv)
int argc;
@@ -70,13 +75,18 @@
size_t len, bufsize;
ssize_t hdrlen;
off_t filesize;
- int ch, audiofd, ctlfd;
+ int ch, ctlfd;
int iflag = 0;
int qflag = 0;
int verbose = 0;
char *device = 0;
char *ctldev = 0;
+ /* Cleanup quickly if the user wants us to die. */
+ signal(SIGHUP, cleanup);
+ signal(SIGINT, cleanup);
+ signal(SIGTERM, cleanup);
+
while ((ch = getopt(argc, argv, "b:C:c:d:e:fhip:P:qs:Vv:")) != -1) {
switch (ch) {
case 'b':
@@ -368,3 +378,15 @@
"-v volume\n");
exit(0);
}
+
+
+/* Signal handler for HUP, INT, and TERM that flushes the audio buffer
+ immediately instead of waiting five seconds for it to drain. */
+void cleanup(int x)
+{
+ ioctl(audiofd, AUDIO_FLUSH, NULL); /* Purge all data from audio buffer. */
+ close(audiofd); /* Close the device */
+ exit(0);
+}
+
+
>Audit-Trail:
>Unformatted: