[alsa-devel] If /dev/snd/controlCx EACCES vs. ENODEV mixup
Jaroslav Kysela
perex at perex.cz
Sun Nov 25 22:40:07 CET 2007
On Sun, 25 Nov 2007, Lennart Poettering wrote:
> Hi!
>
> If /dev/snd/controlC0 is not accessible due to a permission problem
> (EACCES), then alsa-libs will lie and return ENODEV. This is quite a
> bit confusing:
>
> <snip>
> $ sudo chmod 000 /dev/snd/controlC0
> $ aplay -D hw:0
> ALSA lib pcm_hw.c:1207:(_snd_pcm_hw_open) Invalid value for card
> aplay: main:546: audio open error: No such device
> </snip>
>
> (and strace shows that the actual problem is EACESS, as one would
> assume.
Could you try attached patch?
Jaroslav
-----
Jaroslav Kysela <perex at perex.cz>
Linux Kernel Sound Maintainer
ALSA Project
-------------- next part --------------
diff -r 672c5387645d src/control/cards.c
--- a/src/control/cards.c Fri Nov 23 15:46:48 2007 +0100
+++ b/src/control/cards.c Sun Nov 25 22:36:57 2007 +0100
@@ -39,12 +39,7 @@
#define SND_FILE_LOAD ALOAD_DEVICE_DIRECTORY "aloadC%i"
#endif
-/**
- * \brief Try to load the driver for a card.
- * \param card Card number.
- * \return 1 if driver is present, zero if driver is not present
- */
-int snd_card_load(int card)
+static int snd_card_load1(int card)
{
int open_dev;
char control[sizeof(SND_FILE_CONTROL) + 10];
@@ -61,9 +56,20 @@ int snd_card_load(int card)
#endif
if (open_dev >= 0) {
close (open_dev);
- return 1;
- }
- return 0;
+ return 0;
+ } else {
+ return -errno;
+ }
+}
+
+/**
+ * \brief Try to load the driver for a card.
+ * \param card Card number.
+ * \return 1 if driver is present, zero if driver is not present
+ */
+int snd_card_load(int card)
+{
+ return !!(snd_card_load1(card) == 0);
}
/**
@@ -104,7 +110,7 @@ int snd_card_next(int *rcard)
*/
int snd_card_get_index(const char *string)
{
- int card;
+ int card, err;
snd_ctl_t *handle;
snd_ctl_card_info_t info;
@@ -116,13 +122,16 @@ int snd_card_get_index(const char *strin
return -EINVAL;
if (card < 0 || card > 31)
return -EINVAL;
- if (snd_card_load(card))
+ err = snd_card_load1(card);
+ if (err >= 0)
return card;
- return -ENODEV;
+ return err;
}
for (card = 0; card < 32; card++) {
+#ifdef SUPPORT_ALOAD
if (! snd_card_load(card))
continue;
+#endif
if (snd_ctl_hw_open(&handle, NULL, card, 0) < 0)
continue;
if (snd_ctl_card_info(handle, &info) < 0) {
More information about the Alsa-devel
mailing list