From: Takashi Sakamoto Date: Sat, 2 Apr 2022 01:46:22 +0000 (+0900) Subject: utils: add utilities to request control ioctl X-Git-Tag: v0.3.0~228 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=c0ed3da8a1099850151cfe32a4085c01d30ab208;p=alsa-gobject.git utils: add utilities to request control ioctl In ALSA HwDep and RawMidi interface, some functions are implemented via ALSA control character device. This commit adds utility to perform ioctl in ALSA control character device for the purpose. Signed-off-by: Takashi Sakamoto --- diff --git a/src/hwdep/query.c b/src/hwdep/query.c index f2e61c3..5793467 100644 --- a/src/hwdep/query.c +++ b/src/hwdep/query.c @@ -3,11 +3,7 @@ #include -#include -#include -#include #include -#include /** * SECTION: query @@ -96,35 +92,6 @@ void alsahwdep_get_hwdep_devnode(guint card_id, guint device_id, generate_file_error(error, -err, "Fail to generate hwdep devname"); } -static void hwdep_perform_ctl_ioctl(guint card_id, long request, void *data, - const char *req_label, GError **error) -{ - char *devname; - int fd; - int err; - - g_return_if_fail(error == NULL || *error == NULL); - - err = lookup_and_allocate_control_devname(&devname, card_id); - if (err < 0) { - generate_file_error(error, -err, "Fail to generate control devname"); - return; - } - - fd = open(devname, O_RDONLY | O_NONBLOCK); - if (fd < 0) { - generate_file_error_fmt(error, errno, "open(%s)", devname); - goto end; - } - - if (ioctl(fd, request, data) < 0) - generate_file_error_fmt(error, errno, "ioctl(%s)", req_label); - - close(fd); -end: - free(devname); -} - /** * alsahwdep_get_device_info: * @card_id: The numberical value for sound card to query. @@ -142,6 +109,7 @@ void alsahwdep_get_device_info(guint card_id, guint device_id, GError **error) { struct snd_hwdep_info *info; + int err; g_return_if_fail(device_info != NULL); g_return_if_fail(error == NULL || *error == NULL); @@ -151,7 +119,9 @@ void alsahwdep_get_device_info(guint card_id, guint device_id, info->device = device_id; info->card = card_id; - hwdep_perform_ctl_ioctl(card_id, SNDRV_CTL_IOCTL_HWDEP_INFO, info, "HWDEP_INFO", error); - if (*error != NULL) + err = request_ctl_ioctl(card_id, SNDRV_CTL_IOCTL_HWDEP_INFO, info); + if (err < 0) { + generate_file_error(error, -err, "ioctl(HWDEP_INFO)"); g_object_unref(*device_info); + } } diff --git a/src/rawmidi/query.c b/src/rawmidi/query.c index 8b0e582..0be13f2 100644 --- a/src/rawmidi/query.c +++ b/src/rawmidi/query.c @@ -3,11 +3,7 @@ #include -#include -#include -#include #include -#include /** * SECTION: query @@ -96,37 +92,6 @@ void alsarawmidi_get_rawmidi_devnode(guint card_id, guint device_id, generate_file_error(error, -err, "Fail to generate rawmidi devname"); } -static void rawmidi_perform_ctl_ioctl(guint card_id, long request, void *data, - const char *req_label, int *ctl_fd, GError **error) -{ - char *devname; - int fd; - int err; - - err = lookup_and_allocate_control_devname(&devname, card_id); - if (err < 0) { - generate_file_error(error, -err, "Fail to generate control devname"); - return; - } - - fd = open(devname, O_RDONLY); - if (fd < 0) { - generate_file_error_fmt(error, errno, "open(%s)", devname); - goto end; - } - - if (ioctl(fd, request, data) < 0) - generate_file_error_fmt(error, errno, "ioctl(%s)", req_label); - - // The caller is responsible for closing the file descriptor. - if (ctl_fd != NULL) - *ctl_fd = fd; - else - close(fd); -end: - free(devname); -} - /** * alsarawmidi_get_subdevice_id_list: * @card_id: The numberical value for sound card to query. @@ -155,14 +120,17 @@ void alsarawmidi_get_subdevice_id_list(guint card_id, guint device_id, .subdevice = 0, }; int i; + int err; g_return_if_fail(entries != NULL); g_return_if_fail(entry_count != NULL); g_return_if_fail(error == NULL || *error == NULL); - rawmidi_perform_ctl_ioctl(card_id, SNDRV_CTL_IOCTL_RAWMIDI_INFO, &info, "RAWMIDI_INFO", NULL, error); - if (*error != NULL) + err = request_ctl_ioctl(card_id, SNDRV_CTL_IOCTL_RAWMIDI_INFO, &info); + if (err < 0) { + generate_file_error(error, -err, "RAWMIDI_INFO"); return; + } *entries = g_malloc0_n(info.subdevices_count, sizeof(guint)); @@ -193,6 +161,7 @@ void alsarawmidi_get_substream_info(guint card_id, guint device_id, GError **error) { struct snd_rawmidi_info *info; + int err; g_return_if_fail(substream_info != NULL); g_return_if_fail(error == NULL || *error == NULL); @@ -205,14 +174,19 @@ void alsarawmidi_get_substream_info(guint card_id, guint device_id, info->stream = direction; info->card = card_id; - rawmidi_perform_ctl_ioctl(card_id, SNDRV_CTL_IOCTL_RAWMIDI_INFO, info, "RAWMIDI_INFO", NULL, error); - if (*error != NULL) + err = request_ctl_ioctl(card_id, SNDRV_CTL_IOCTL_RAWMIDI_INFO, info); + if (err < 0) { g_object_unref(*substream_info); + generate_file_error(error, -err, "RAWMIDI_INFO"); + } } void rawmidi_select_subdevice(guint card_id, guint subdevice_id, int *ctl_fd, GError **error) { guint data = subdevice_id; - rawmidi_perform_ctl_ioctl(card_id, SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE, - &data, "RAWMIDI_PREFER_SUBDEVICE", ctl_fd, error); + int err; + + err = request_ctl_ioctl_opened(ctl_fd, card_id, SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE, &data); + if (err < 0) + generate_file_error(error, -err, "RAWMIDI_PREFER_SUBDEVICE"); } diff --git a/src/utils/ioctl.c b/src/utils/ioctl.c new file mode 100644 index 0000000..f985cd6 --- /dev/null +++ b/src/utils/ioctl.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +#include "utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +int request_ctl_ioctl_opened(int *fd, unsigned int card_id, long request, void *data) +{ + char *devname; + int err; + + if (fd == NULL) + return -EINVAL; + + err = lookup_and_allocate_control_devname(&devname, card_id); + if (err < 0) + return err; + + *fd = open(devname, O_RDONLY | O_NONBLOCK); + free(devname); + if (*fd < 0) + return -errno; + + if (ioctl(*fd, request, data) < 0) + return -errno; + + return 0; +} + +int request_ctl_ioctl(unsigned int card_id, long request, void *data) +{ + int fd; + int err; + + err = request_ctl_ioctl_opened(&fd, card_id, request, data); + close(fd); + + return err; +} diff --git a/src/utils/meson.build b/src/utils/meson.build index d418eaf..b23d8df 100644 --- a/src/utils/meson.build +++ b/src/utils/meson.build @@ -5,6 +5,7 @@ headers = [ sources = [ 'string.c', 'sysfs.c', + 'ioctl.c', ] dependencies = [ diff --git a/src/utils/utils.h b/src/utils/utils.h index a3861d6..67ba1cf 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -28,6 +28,9 @@ int lookup_and_allocate_string_by_sysname(char **name, const char *sysname, int generate_sysnum_list_by_sysname_prefix(unsigned int **entries, unsigned long *entry_count, const char *prefix); +int request_ctl_ioctl_opened(int *fd, unsigned int card_id, long request, void *data); +int request_ctl_ioctl(unsigned int card_id, long request, void *data); + static inline int lookup_and_allocate_name_by_sysname(char **name, const char *(*func)(struct udev_device *), const char *fmt, va_list ap)