[alsa-devel] different return value from some ioctl commands for x86 binary executed on x86_64

Takashi Iwai tiwai at suse.de
Thu Mar 17 10:51:38 CET 2016


On Thu, 17 Mar 2016 04:52:52 +0100,
Takashi Sakamoto wrote:
> 
> Hi,
> 
> When testing ioctl compatibility layer for ALSA ctl interface, I found
> that error code of some ioctl commands are different depending on binary
> architecture.
> 
> The commands are SNDRV_CTL_IOCTL_ELEM_READ/SNDRV_CTL_IOCTL_ELEM_WRITE.
> When passing data for non-existent element, ENOENT is returned by the
> core implementation. On the other hand, ENXIO is returned by the
> compatibility layer.
> 
> This code is for reproduction of this bug.
> 
> #include <stdio.h>
> #include <stdlib.h>
> #include <stdbool.h>
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <sys/ioctl.h>
> #include <errno.h>
> #include <string.h>
> 
> #include <sound/asound.h>
> 
> static void check_elem_read(int fd)
> {
>         struct snd_ctl_elem_value data = {0};
>         if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_READ, &data) < 0) {
>                 printf("ioctl(SNDRV_CTL_IOCTL_ELEM_READ): %s\n",
>                        strerror(errno));
>         }
> }
> 
> static void check_elem_write(int fd)
> {
>         struct snd_ctl_elem_value data = {0};
>         if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &data) < 0) {
>                 printf("ioctl(SNDRV_CTL_IOCTL_ELEM_WRITE): %s\n",
>                        strerror(errno));
>         }
> }
> 
> int main(void)
> {
>         int fd;
> 
>         fd = open("/dev/snd/controlC0", O_RDONLY);
>         if (fd < 0) {
>                 printf("open(2): %s\n", strerror(errno));
>                 return EXIT_FAILURE;
>         }
> 
>         check_elem_read(fd);
>         check_elem_write(fd);
> 
>         return EXIT_SUCCESS;
> }
> 
> I tested on x86_64 machine with enough support for multi-arch.
> 
> $ gcc -Wall -m64 -o ./test ./test.c ; ./test
> ioctl(SNDRV_CTL_IOCTL_ELEM_READ): No such file or directory
> ioctl(SNDRV_CTL_IOCTL_ELEM_WRITE): No such file or directory
> 
> $ gcc -Wall -m32 -o ./test ./test.c ; ./test
> ioctl(SNDRV_CTL_IOCTL_ELEM_READ): No such device or address
> ioctl(SNDRV_CTL_IOCTL_ELEM_WRITE): No such device or address
> 
> 
> This bug is due to return value of condition statement for
> 'snd_ctl_find()'. I wrote a patch to fix it.
> 
> 
> >From d7a8fd14a1bc100dbaf9bf28af47094d5ccb882b Mon Sep 17 00:00:00 2001
> From: Takashi Sakamoto <o-takashi at sakamocchi.jp>
> Date: Wed, 16 Mar 2016 13:40:31 +0900
> Subject: [PATCH] ALSA: ctl: change error code in compatibility layer so that
>  it's the same code as core implementation
> 
> In control compatibility layer, when no elements are found by
> ELEM_READ/ELEM_WRITE ioctl commands, ENXIO is returned. On the other
> hand, in core implementation, ENOENT is returned. This is not good for
> applications.
> 
> This commit changes the return value from the compatibility layer so
> that the same error code is returned.
> 
> diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
> index 0608f21..1fa7076 100644
> --- a/sound/core/control_compat.c
> +++ b/sound/core/control_compat.c
> @@ -196,7 +196,7 @@ static int get_ctl_type(struct snd_card *card,
> struct snd_ctl_elem_id *id,
>         kctl = snd_ctl_find_id(card, id);
>         if (! kctl) {
>                 up_read(&card->controls_rwsem);
> -               return -ENXIO;
> +               return -ENOENT;
>         }
>         info = kzalloc(sizeof(*info), GFP_KERNEL);
>         if (info == NULL) {
> 
> Well, it's already in merge window for Linux 4.6. I don't mind to
> postpone this patch to next developing cycle, while I also think it
> better to fix the bug now. So I leave the decision to maintainers.

Looks good to me, and trivial enough to be merged for 4.6.
Please resubmit with a proper sign off.


thanks,

Takashi


More information about the Alsa-devel mailing list