Hi Tilo,

On Tue, 11 Aug 2015 17:11:13 +0200
Tilo Stritzky <lf...@gmx.de> wrote:

> Am I doing something silly here?  Or is there a bug?
> I see the same result on i386 and amd64. Same for /dev/sound.
> This works on a 5.5 release, but not on later releases or current.

I've been able to reproduce this with a simple C program on amd64
-current. I've tracked it down to the recent audio(4) subsystem rewrite,
which removed support for the FIOASYNC ioctl(2) (used internally by
fcntl(2)). However, this implies it should work on 5.6 and 5.7. I don't
have any such systems with audio devices available to test; are you
sure you're seeing the same behaviour on those releases?

Below is a diff that fixes the problem for me. I'm not sure if the
EINVAL on set is needed, as other drivers which don't support FIOASYNC
(drm(4), hotplug(4), random(4) and systrace(4)) appear to just ignore
that ioctl completely. I'm sure someone more experienced than I will
know the answer to that.

> Incidentally, are there perl bindings for the native sound interface
> sio_open(3)?

I wrote some low-level Perl bindings a few weeks ago:

  https://github.com/stevenjm/perl-Audio-Sndio

They're not on CPAN yet because they're not finished, mainly because
I'm not yet sure if writing a higher-level interface in pure Perl or
extending the XS code is a better approach. The low-level bindings are
usable as is, and probably a better option than talking to /dev/audio
directly.

Index: audio.c
===================================================================
RCS file: /cvs/src/sys/dev/audio.c,v
retrieving revision 1.138
diff -u -p -r1.138 audio.c
--- audio.c     29 Jul 2015 21:13:32 -0000      1.138
+++ audio.c     13 Aug 2015 10:35:08 -0000
@@ -1542,6 +1542,11 @@ audio_ioctl(struct audio_softc *sc, unsi
        case FIONBIO:
                /* All handled in the upper FS layer. */
                break;
+       case FIOASYNC:
+               /* No async mode, so set is an error, unset is a noop. */
+               if (*(int *)addr)
+                       error = EINVAL;
+               break;
        case AUDIO_PERROR:
                mtx_enter(&audio_lock);
                *(int *)addr = sc->play.xrun / (sc->pchan * sc->bps);

Reply via email to