[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