mirror of https://gitee.com/openkylin/qemu.git
oss/alsa: Do not invoke UB described in 7.15.1.1
Additional argument (whether to try poll mode) is only passed with VOICE_ENABLE command. Thanks to Markus Armbruster for noticing the potential breakage.
This commit is contained in:
parent
c227f0995e
commit
301901b56c
|
@ -861,22 +861,25 @@ static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int pause)
|
||||||
|
|
||||||
static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
|
static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
|
||||||
int poll_mode;
|
|
||||||
ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
|
ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
|
||||||
|
|
||||||
va_start (ap, cmd);
|
|
||||||
poll_mode = va_arg (ap, int);
|
|
||||||
va_end (ap);
|
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case VOICE_ENABLE:
|
case VOICE_ENABLE:
|
||||||
ldebug ("enabling voice\n");
|
{
|
||||||
if (poll_mode && alsa_poll_out (hw)) {
|
va_list ap;
|
||||||
poll_mode = 0;
|
int poll_mode;
|
||||||
|
|
||||||
|
va_start (ap, cmd);
|
||||||
|
poll_mode = va_arg (ap, int);
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
|
ldebug ("enabling voice\n");
|
||||||
|
if (poll_mode && alsa_poll_out (hw)) {
|
||||||
|
poll_mode = 0;
|
||||||
|
}
|
||||||
|
hw->poll_mode = poll_mode;
|
||||||
|
return alsa_voice_ctl (alsa->handle, "playback", 0);
|
||||||
}
|
}
|
||||||
hw->poll_mode = poll_mode;
|
|
||||||
return alsa_voice_ctl (alsa->handle, "playback", 0);
|
|
||||||
|
|
||||||
case VOICE_DISABLE:
|
case VOICE_DISABLE:
|
||||||
ldebug ("disabling voice\n");
|
ldebug ("disabling voice\n");
|
||||||
|
|
|
@ -583,34 +583,37 @@ static int oss_init_out (HWVoiceOut *hw, struct audsettings *as)
|
||||||
static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...)
|
static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...)
|
||||||
{
|
{
|
||||||
int trig;
|
int trig;
|
||||||
va_list ap;
|
|
||||||
int poll_mode;
|
|
||||||
OSSVoiceOut *oss = (OSSVoiceOut *) hw;
|
OSSVoiceOut *oss = (OSSVoiceOut *) hw;
|
||||||
|
|
||||||
va_start (ap, cmd);
|
|
||||||
poll_mode = va_arg (ap, int);
|
|
||||||
va_end (ap);
|
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case VOICE_ENABLE:
|
case VOICE_ENABLE:
|
||||||
ldebug ("enabling voice\n");
|
{
|
||||||
if (poll_mode && oss_poll_out (hw)) {
|
va_list ap;
|
||||||
poll_mode = 0;
|
int poll_mode;
|
||||||
}
|
|
||||||
hw->poll_mode = poll_mode;
|
|
||||||
|
|
||||||
if (!oss->mmapped) {
|
va_start (ap, cmd);
|
||||||
return 0;
|
poll_mode = va_arg (ap, int);
|
||||||
}
|
va_end (ap);
|
||||||
|
|
||||||
audio_pcm_info_clear_buf (&hw->info, oss->pcm_buf, hw->samples);
|
ldebug ("enabling voice\n");
|
||||||
trig = PCM_ENABLE_OUTPUT;
|
if (poll_mode && oss_poll_out (hw)) {
|
||||||
if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
|
poll_mode = 0;
|
||||||
oss_logerr (
|
}
|
||||||
errno,
|
hw->poll_mode = poll_mode;
|
||||||
"SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
|
|
||||||
);
|
if (!oss->mmapped) {
|
||||||
return -1;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio_pcm_info_clear_buf (&hw->info, oss->pcm_buf, hw->samples);
|
||||||
|
trig = PCM_ENABLE_OUTPUT;
|
||||||
|
if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
|
||||||
|
oss_logerr (
|
||||||
|
errno,
|
||||||
|
"SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
|
||||||
|
);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue