Found the call, made the change, it just segfaults. strace says:
> open("/dev/dsp", O_WRONLY) = 5
> getuid() = 501
> setreuid(4294967295, 501) = 0
> ioctl(5, SNDCTL_DSP_RESET, 0) = 0
> ioctl(5, SNDCTL_DSP_GETCAPS, 0xbffff2d8) = 0
> ioctl(5, SNDCTL_DSP_GETOSPACE, 0xbffff2dc) = 0
> ioctl(5, SNDCTL_DSP_SPEED, 0x809ba58) = 0
> mmap(0, 65536, PROT_WRITE, MAP_SHARED, 5, 0) = -1 EACCES (Permission denied)
My first reaction was: Huh? However, looking at mm/mmap.c reveals that
we refuse to mmap() anything that isn't open for reading (due to
limitations of the x86 architecture, it would seem):
> if (!(file->f_mode & 1))
> return -EACCES;
Given that the latest sound drivers use the open() flags to determine
whether to use 8/16-bit duplex, this seems to pretty much screw the
possibility of 16-bit write-only sound using mmap().
To my mind, the possibilities seem to be:
1. Don't use the open flags to select duplex operation, but to use an
ioctl() instead.
2. Change mmap() to allow mapping files which were open()ed O_WRONLY,
provided that the process has read permission on the inode. Presumably
this will break if the program is relying on a segfault if the process
tries to read the mmap()d region (is this a realistic possibility?).
3. Leave things as they are, and forego the possibility of using
mmap() for 16-bit sound output.
Do POSIX/FIPS/XPG-*/Unix98/... have anything to say about the
behaviour of `open(O_WRONLY); mmap(PROT_WRITE)'? If not, then 1 has
the advantage of backwards compatibility.
For now, I have two versions of sb.o (vanilla, and with the no-duplex
patch). If this issue can't be resolved cleanly, then the behaviour of
open()ing /dev/dsp O_RDWR probably needs to be controlled by a module
parameter, IMHO.
-- Glynn Clements <glynn@sensei.co.uk>- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/