Last active
September 2, 2017 04:25
-
-
Save takaswie/cd670ee88b7fd25c68780610ad8ad54f to your computer and use it in GitHub Desktop.
A small program to check logical contradiction between member count and dimension info.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <sys/ioctl.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <errno.h> | |
#include <sound/asound.h> | |
static const char *const elem_iface_labels[] = { | |
[SNDRV_CTL_ELEM_IFACE_CARD] = "card", | |
[SNDRV_CTL_ELEM_IFACE_HWDEP] = "hwdep", | |
[SNDRV_CTL_ELEM_IFACE_MIXER] = "mixer", | |
[SNDRV_CTL_ELEM_IFACE_PCM] = "pcm", | |
[SNDRV_CTL_ELEM_IFACE_RAWMIDI] = "rawmidi", | |
[SNDRV_CTL_ELEM_IFACE_TIMER] = "timer", | |
[SNDRV_CTL_ELEM_IFACE_SEQUENCER] = "sequencer", | |
}; | |
static const char *const elem_type_labels[] = { | |
[SNDRV_CTL_ELEM_TYPE_BOOLEAN] = "boolean", | |
[SNDRV_CTL_ELEM_TYPE_INTEGER] = "integer", | |
[SNDRV_CTL_ELEM_TYPE_ENUMERATED] = "enumerated", | |
[SNDRV_CTL_ELEM_TYPE_BYTES] = "bytes", | |
[SNDRV_CTL_ELEM_TYPE_IEC958] = "iec60958", | |
[SNDRV_CTL_ELEM_TYPE_INTEGER64] = "integer64", | |
}; | |
static void dump_elem_info(struct snd_ctl_elem_info *info) | |
{ | |
unsigned int cols; | |
int i; | |
printf("numid: %u\n", info->id.numid); | |
printf(" iface: %s\n", elem_iface_labels[info->id.iface]); | |
printf(" device: %u\n", info->id.device); | |
printf(" subdevice: %u\n", info->id.subdevice); | |
printf(" name: %s\n", info->id.name); | |
printf(" index: %u\n", info->id.index); | |
printf(" type: %s\n", elem_type_labels[info->type]); | |
printf(" count: %u\n", info->count); | |
if (info->dimen.d[0] > 0) { | |
printf(" dimension:\n"); | |
for (i = 0; | |
i < sizeof(info->dimen.d) / sizeof(info->dimen.d[0]); | |
++i) { | |
cols = info->dimen.d[i]; | |
if (cols == 0) | |
continue; | |
printf(" %d: %u %u\n", i, cols, info->count / cols); | |
info->count /= cols; | |
} | |
} | |
} | |
static int enumerate_elems(int fd, struct snd_ctl_elem_id *ids, | |
unsigned int count) | |
{ | |
struct snd_ctl_elem_info info; | |
int i; | |
for (i = 0; i < count; ++i) { | |
memset(&info, 0, sizeof(info)); | |
info.id = ids[i]; | |
if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_INFO, &info) < 0) { | |
printf("ioctl(2) with ELEM_INFO: %s\n", | |
strerror(errno)); | |
return -errno; | |
} | |
dump_elem_info(&info); | |
} | |
return 0; | |
} | |
static int list_elems(int fd) | |
{ | |
struct snd_ctl_elem_list list = {0}; | |
int err = 0; | |
if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &list) < 0) { | |
printf("ioctl(2) with ELEM_LIST: %s\n", strerror(errno)); | |
return -errno; | |
} | |
list.pids = calloc(list.count, sizeof(*list.pids)); | |
if (list.pids == NULL) { | |
printf("calloc(3): %s\n", strerror(errno)); | |
return -ENOMEM; | |
} | |
list.space = list.count; | |
if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &list) < 0) { | |
printf("ioctl(2) with ELEM_LIST: %s\n", strerror(errno)); | |
err = -errno; | |
goto end; | |
} | |
err = enumerate_elems(fd, list.pids, list.count); | |
end: | |
free(list.pids); | |
return err; | |
} | |
int main(int argc, const char *argv[]) | |
{ | |
const char *path; | |
int fd; | |
int err; | |
if (argc == 1) { | |
printf("At least, one argument is required for a path of " | |
"special file for ALSA control character device.\n"); | |
return EXIT_FAILURE; | |
} | |
path = argv[1]; | |
fd = open(path, O_RDONLY); | |
if (fd < 0) { | |
printf("open(2): %s\n", strerror(errno)); | |
return EXIT_FAILURE; | |
} | |
err = list_elems(fd); | |
end: | |
close(fd); | |
if (err < 0) | |
return EXIT_FAILURE; | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment