[alsa-devel] aplay can't run in background since adding pause support
Takashi Iwai
tiwai at suse.de
Tue May 24 07:55:15 CEST 2011
At Mon, 23 May 2011 13:55:44 -0700,
Stephen Warren wrote:
>
> Jaroslav,
>
> In recent versions of aplay, if I try to either run them in the
> background, or run them in the foreground, then ^Z and bg them, they
> hang indefinitely:
>
> aplay foo.wav &
> # doesn't play anything
>
> aplay foo.wav
> ...
> ^Z
> bg
> [1]+ Stopped aplay foo.wav
> bg
> [1]+ Stopped aplay foo.wav
>
> At least, this is true under ChromeOS on ARM with kernel 2.6.38 and
> ALSA 1.0.24.2, or an Ubuntu Natty rootstock on ARM with the same ChromeOS
> kernel.
>
> This was introduced by alsa-utils commit:
> 3bd65336222a4d00cefc4db5e74a7a96c07ab567
> aplay/arecord: Added hardware pause support (press SPACE or Enter)
>
> What happens is that the call to tcsetattr causes the process to receive
> signal TTOU and be stopped. Running under strace yields an infinite loop
> with ioctl(TCSETS) returning -ERESTARTSYS, and being retried.
>
> I believe this is related to http://lkml.org/lkml/2008/6/2/157.
>
> I'm not exactly sure how to solve this though. Another post in that
> thread implied that adding a signal handler for TTOU and then adjusting
> the tcsetattr settings might help, but I'm not convinced about that,
> since I believe the -ERESTARTSYS handling loop is inside the call to
> tcsetattr, and hence tcsetattr's parameters can't be changed.
>
> Does anyone have any ideas? Thanks.
IMO, it's safer to add an option for interactive mode like below.
As aplay has been used since long time ago, we shouldn't introduce
any regression to this basic program.
thanks,
Takashi
---
diff --git a/aplay/aplay.1 b/aplay/aplay.1
index b6caf0b..8cd1d56 100644
--- a/aplay/aplay.1
+++ b/aplay/aplay.1
@@ -137,6 +137,10 @@ by typing aplay.
Record. This is the default if the program is invoked
by typing arecord.
.TP
+\fI\-i, \-\-interactive\fP
+Allow interactive operation via stdin.
+Currently only pause/resume via space key is implemented.
+.TP
\fI\-\-disable\-resample\fP
Disable automatic rate resample.
.TP
diff --git a/aplay/aplay.c b/aplay/aplay.c
index c09f23c..04959b8 100644
--- a/aplay/aplay.c
+++ b/aplay/aplay.c
@@ -103,6 +103,7 @@ static int avail_min = -1;
static int start_delay = 0;
static int stop_delay = 0;
static int monotonic = 0;
+static int interactive = 0;
static int can_pause = 0;
static int verbose = 0;
static int vumeter = VUMETER_NONE;
@@ -200,6 +201,7 @@ _("Usage: %s [OPTION]... [FILE]...\n"
"-v, --verbose show PCM structure and setup (accumulative)\n"
"-V, --vumeter=TYPE enable VU meter (TYPE: mono or stereo)\n"
"-I, --separate-channels one file for each channel\n"
+"-i, --interactive allow interactive operation from stdin\n"
" --disable-resample disable automatic rate resample\n"
" --disable-channels disable automatic channel conversions\n"
" --disable-format disable automatic format conversions\n"
@@ -404,7 +406,7 @@ enum {
int main(int argc, char *argv[])
{
int option_index;
- static const char short_options[] = "hnlLD:qt:c:f:r:d:MNF:A:R:T:B:vV:IPC";
+ static const char short_options[] = "hnlLD:qt:c:f:r:d:MNF:A:R:T:B:vV:IPCi";
static const struct option long_options[] = {
{"help", 0, 0, 'h'},
{"version", 0, 0, OPT_VERSION},
@@ -442,6 +444,7 @@ int main(int argc, char *argv[])
{"max-file-time", 1, 0, OPT_MAX_FILE_TIME},
{"process-id-file", 1, 0, OPT_PROCESS_ID_FILE},
{"use-strftime", 0, 0, OPT_USE_STRFTIME},
+ {"interactive", 0, 0, 'i'},
{0, 0, 0, 0}
};
char *pcm_name = "default";
@@ -608,6 +611,9 @@ int main(int argc, char *argv[])
if (file_type == FORMAT_DEFAULT)
file_type = FORMAT_WAVE;
break;
+ case 'i':
+ interactive = 1;
+ break;
case OPT_DISABLE_RESAMPLE:
open_mode |= SND_PCM_NO_AUTO_RESAMPLE;
break;
@@ -1206,6 +1212,8 @@ static void init_stdin(void)
struct termios term;
long flags;
+ if (!interactive)
+ return;
tcgetattr(fileno(stdin), &term);
term_c_lflag = term.c_lflag;
if (fd == fileno(stdin))
@@ -1221,6 +1229,8 @@ static void done_stdin(void)
{
struct termios term;
+ if (!interactive)
+ return;
if (fd == fileno(stdin) || term_c_lflag == -1)
return;
tcgetattr(fileno(stdin), &term);
@@ -1258,6 +1268,8 @@ static void check_stdin(void)
{
unsigned char b;
+ if (!interactive)
+ return;
if (fd != fileno(stdin)) {
while (read(fileno(stdin), &b, 1) == 1) {
if (b == ' ' || b == '\r') {
More information about the Alsa-devel
mailing list