From: Takashi Sakamoto Date: Sat, 2 Apr 2022 01:46:22 +0000 (+0900) Subject: utils: add utilitiy to generate list of sysnum by prefix of sysname X-Git-Tag: v0.3.0~229 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=a480ba8fdeaecbfea8ce9d175820e363c2c870d0;p=alsa-gobject.git utils: add utilitiy to generate list of sysnum by prefix of sysname It's typically used to generate the list of sysnum over sysfs by sysname prefix. This commit adds utility for it. Signed-off-by: Takashi Sakamoto --- diff --git a/src/ctl/meson.build b/src/ctl/meson.build index 9e4058d..4dfc6f1 100644 --- a/src/ctl/meson.build +++ b/src/ctl/meson.build @@ -32,7 +32,6 @@ privates = files( dependencies = [ gobject_dependency, - libudev_dependency, utils_dependencies, ] diff --git a/src/ctl/query.c b/src/ctl/query.c index a06b8dc..1b89f81 100644 --- a/src/ctl/query.c +++ b/src/ctl/query.c @@ -3,13 +3,6 @@ #include -#include -#include -#include -#include - -#include - /** * SECTION: query * @Title: Global functions in ALSACtl @@ -20,88 +13,6 @@ #define generate_file_error(exception, errno, msg) \ g_set_error_literal(exception, G_FILE_ERROR, g_file_error_from_errno(errno), msg) -static void prepare_udev_enum(struct udev_enumerate **enumerator, - GError **error) -{ - struct udev *ctx; - int err; - - ctx = udev_new(); - if (ctx == NULL) { - generate_file_error(error, errno, "udev_new()"); - return; - } - - *enumerator = udev_enumerate_new(ctx); - if (*enumerator == NULL) { - generate_file_error(error, errno, "udev_enumerate_new()"); - udev_unref(ctx); - return; - } - - err = udev_enumerate_add_match_subsystem(*enumerator, "sound"); - if (err < 0) { - generate_file_error(error, -err, "udev_enumerate_add_match_subsystem()"); - udev_enumerate_unref(*enumerator); - udev_unref(ctx); - return; - } - - err = udev_enumerate_scan_devices(*enumerator); - if (err < 0) { - generate_file_error(error, -err, "udev_enumerate_scan_devices()"); - udev_enumerate_unref(*enumerator); - udev_unref(ctx); - } -} - -static struct udev_device *detect_dev(struct udev_enumerate *enumerator, - struct udev_list_entry *entry, - const char *prefix) -{ - struct udev *ctx = udev_enumerate_get_udev(enumerator); - const char *syspath; - struct udev_device *dev; - const char *sysname; - - syspath = udev_list_entry_get_name(entry); - if (syspath == NULL) - return NULL; - - dev = udev_device_new_from_syspath(ctx, syspath); - if (dev == NULL) - return NULL; - - sysname = udev_device_get_sysname(dev); - if (sysname == NULL) { - udev_device_unref(dev); - return NULL; - } - - if (strstr(sysname, prefix) != sysname) { - udev_device_unref(dev); - return NULL; - } - - return dev; -} - -static void release_udev_enum(struct udev_enumerate *enumerator) -{ - struct udev *ctx = udev_enumerate_get_udev(enumerator); - - udev_enumerate_unref(enumerator); - udev_unref(ctx); -} - -static int compare_guint(const void *l, const void *r) -{ - const guint *x = l; - const guint *y = r; - - return *x > *y; -} - /** * alsactl_get_card_id_list: * @entries: (array length=entry_count)(out): The list of numerical ID for sound @@ -116,58 +27,15 @@ static int compare_guint(const void *l, const void *r) void alsactl_get_card_id_list(guint **entries, gsize *entry_count, GError **error) { - struct udev_enumerate *enumerator = NULL; - struct udev_list_entry *entry, *entry_list; - unsigned int count; - unsigned int index; + int err; g_return_if_fail(entries != NULL); g_return_if_fail(entry_count != NULL); g_return_if_fail(error == NULL || *error == NULL); - prepare_udev_enum(&enumerator, error); - if (*error != NULL) - return; - - entry_list = udev_enumerate_get_list_entry(enumerator); - - count = 0; - udev_list_entry_foreach(entry, entry_list) { - struct udev_device *dev = detect_dev(enumerator, entry, "card"); - if (dev != NULL) { - ++count; - udev_device_unref(dev); - } - } - - // Nothing available. - if (count == 0) - goto end; - - *entries = g_malloc0_n(count, sizeof(**entries)); - - index = 0; - udev_list_entry_foreach(entry, entry_list) { - struct udev_device *dev = detect_dev(enumerator, entry, "card"); - if (dev != NULL) { - const char *sysnum = udev_device_get_sysnum(dev); - long val; - - if (!long_from_string(sysnum, &val)) { - (*entries)[index] = val; - ++index; - } - udev_device_unref(dev); - } - } - - g_warn_if_fail(index == count); - - *entry_count = count; - - qsort(*entries, count, sizeof(guint), compare_guint); -end: - release_udev_enum(enumerator); + err = generate_card_sysnum_list(entries, entry_count); + if (err < 0) + generate_file_error(error, -err, "Fail to generate list of card sysnum"); } /** diff --git a/src/hwdep/meson.build b/src/hwdep/meson.build index 8e8d3f2..5a90533 100644 --- a/src/hwdep/meson.build +++ b/src/hwdep/meson.build @@ -24,7 +24,6 @@ privates = files( dependencies = [ gobject_dependency, - libudev_dependency, utils_dependencies, ] diff --git a/src/hwdep/query.c b/src/hwdep/query.c index 942c18c..f2e61c3 100644 --- a/src/hwdep/query.c +++ b/src/hwdep/query.c @@ -3,17 +3,12 @@ #include -#include -#include -#include #include #include #include #include #include -#include - /** * SECTION: query * @Title: Global functions in ALSAHwdep @@ -21,110 +16,12 @@ * descriptor */ -// 'C' is required apart from emulation of Open Sound System. -#define PREFIX_SYSNAME_TEMPLATE "hwC%u" - #define generate_file_error(error, errno, msg) \ g_set_error_literal(error, G_FILE_ERROR, g_file_error_from_errno(errno), msg) #define generate_file_error_fmt(error, errno, fmt, msg) \ g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno), fmt, msg) -static void prepare_udev_enum(struct udev_enumerate **enumerator, GError **error) -{ - struct udev *ctx; - int err; - - ctx = udev_new(); - if (ctx == NULL) { - generate_file_error(error, errno, "udev_new()"); - return; - } - - *enumerator = udev_enumerate_new(ctx); - if (*enumerator == NULL) { - generate_file_error(error, errno, "udev_enumerate_new()"); - udev_unref(ctx); - return; - } - - err = udev_enumerate_add_match_subsystem(*enumerator, "sound"); - if (err < 0) { - generate_file_error(error, -err, "udev_enumerate_add_match_subsystem()"); - udev_enumerate_unref(*enumerator); - udev_unref(ctx); - return; - } - - err = udev_enumerate_scan_devices(*enumerator); - if (err < 0) { - generate_file_error(error, -err, "udev_enumerate_scan_devices()"); - udev_enumerate_unref(*enumerator); - udev_unref(ctx); - } -} - -static struct udev_device *detect_dev(struct udev_enumerate *enumerator, - struct udev_list_entry *entry, - const char *prefix) -{ - struct udev *ctx = udev_enumerate_get_udev(enumerator); - const char *syspath; - struct udev_device *dev; - const char *sysname; - - syspath = udev_list_entry_get_name(entry); - if (syspath == NULL) - return NULL; - - dev = udev_device_new_from_syspath(ctx, syspath); - if (dev == NULL) - return NULL; - - sysname = udev_device_get_sysname(dev); - if (sysname == NULL) { - udev_device_unref(dev); - return NULL; - } - - if (strstr(sysname, prefix) != sysname) { - udev_device_unref(dev); - return NULL; - } - - return dev; -} - -static void release_udev_enum(struct udev_enumerate *enumerator) -{ - struct udev *ctx = udev_enumerate_get_udev(enumerator); - - udev_enumerate_unref(enumerator); - udev_unref(ctx); -} - -static int compare_guint(const void *l, const void *r) -{ - const guint *x = l; - const guint *y = r; - - return *x > *y; -} - -static unsigned int calculate_digits(unsigned int number) -{ - unsigned int digits = 0; - - while (true) { - number /= 10; - ++digits; - if (number == 0) - break; - } - - return digits; -} - /** * alsahwdep_get_device_id_list: * @card_id: The numerical ID of sound card. @@ -140,66 +37,15 @@ static unsigned int calculate_digits(unsigned int number) void alsahwdep_get_device_id_list(guint card_id, guint **entries, gsize *entry_count, GError **error) { - struct udev_enumerate *enumerator = NULL; - unsigned int length; - char *prefix = NULL; - struct udev_list_entry *entry, *entry_list; - unsigned int count; - unsigned int index; + int err; g_return_if_fail(entries != NULL); g_return_if_fail(entry_count != NULL); g_return_if_fail(error == NULL || *error == NULL); - prepare_udev_enum(&enumerator, error); - if (*error != NULL) - return; - - length = strlen(PREFIX_SYSNAME_TEMPLATE) + calculate_digits(card_id) + 1; - prefix = g_malloc0(length); - - snprintf(prefix, length, PREFIX_SYSNAME_TEMPLATE, card_id); - - entry_list = udev_enumerate_get_list_entry(enumerator); - - count = 0; - udev_list_entry_foreach(entry, entry_list) { - struct udev_device *dev = detect_dev(enumerator, entry, prefix); - if (dev != NULL) { - ++count; - udev_device_unref(dev); - } - } - - // Nothing available. - if (count == 0) - goto end; - - *entries = g_malloc0_n(count, sizeof(**entries)); - - index = 0; - udev_list_entry_foreach(entry, entry_list) { - struct udev_device *dev = detect_dev(enumerator, entry, prefix); - if (dev != NULL) { - const char *sysnum = udev_device_get_sysnum(dev); - long val; - - if (!long_from_string(sysnum, &val)) { - (*entries)[index] = (guint)val; - ++index; - } - udev_device_unref(dev); - } - } - - g_warn_if_fail(index == count); - - *entry_count = count; - - qsort(*entries, count, sizeof(guint), compare_guint); -end: - g_free(prefix); - release_udev_enum(enumerator); + err = generate_hwdep_sysnum_list(entries, entry_count, card_id); + if (err < 0) + generate_file_error(error, -err, "Fail to generate list of hwdep sysnum"); } /** diff --git a/src/rawmidi/meson.build b/src/rawmidi/meson.build index 0299407..1831d8c 100644 --- a/src/rawmidi/meson.build +++ b/src/rawmidi/meson.build @@ -30,7 +30,6 @@ privates = files( dependencies = [ gobject_dependency, - libudev_dependency, utils_dependencies, ] diff --git a/src/rawmidi/query.c b/src/rawmidi/query.c index a4db8c1..8b0e582 100644 --- a/src/rawmidi/query.c +++ b/src/rawmidi/query.c @@ -3,17 +3,12 @@ #include -#include -#include -#include #include #include #include #include #include -#include - /** * SECTION: query * @Title: Global functions in ALSARawmidi @@ -21,110 +16,12 @@ * descriptor */ -// 'C' is required apart from emulation of Open Sound System. -#define PREFIX_SYSNAME_TEMPLATE "midiC%u" - #define generate_file_error(error, errno, msg) \ g_set_error_literal(error, G_FILE_ERROR, g_file_error_from_errno(errno), msg) #define generate_file_error_fmt(error, errno, fmt, msg) \ g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno), fmt, msg) -static void prepare_udev_enum(struct udev_enumerate **enumerator, GError **error) -{ - struct udev *ctx; - int err; - - ctx = udev_new(); - if (ctx == NULL) { - generate_file_error(error, errno, "udev_new()"); - return; - } - - *enumerator = udev_enumerate_new(ctx); - if (*enumerator == NULL) { - generate_file_error(error, errno, "udev_enumerate_new()"); - udev_unref(ctx); - return; - } - - err = udev_enumerate_add_match_subsystem(*enumerator, "sound"); - if (err < 0) { - generate_file_error(error, -err, "udev_enumerate_add_match_subsystem()"); - udev_enumerate_unref(*enumerator); - udev_unref(ctx); - return; - } - - err = udev_enumerate_scan_devices(*enumerator); - if (err < 0) { - generate_file_error(error, -err, "udev_enumerate_scan_devices()"); - udev_enumerate_unref(*enumerator); - udev_unref(ctx); - } -} - -static struct udev_device *detect_dev(struct udev_enumerate *enumerator, - struct udev_list_entry *entry, - const char *prefix) -{ - struct udev *ctx = udev_enumerate_get_udev(enumerator); - const char *syspath; - struct udev_device *dev; - const char *sysname; - - syspath = udev_list_entry_get_name(entry); - if (syspath == NULL) - return NULL; - - dev = udev_device_new_from_syspath(ctx, syspath); - if (dev == NULL) - return NULL; - - sysname = udev_device_get_sysname(dev); - if (sysname == NULL) { - udev_device_unref(dev); - return NULL; - } - - if (strstr(sysname, prefix) != sysname) { - udev_device_unref(dev); - return NULL; - } - - return dev; -} - -static void release_udev_enum(struct udev_enumerate *enumerator) -{ - struct udev *ctx = udev_enumerate_get_udev(enumerator); - - udev_enumerate_unref(enumerator); - udev_unref(ctx); -} - -static int compare_guint(const void *l, const void *r) -{ - const guint *x = l; - const guint *y = r; - - return *x > *y; -} - -static unsigned int calculate_digits(unsigned int number) -{ - unsigned int digits = 0; - - while (true) { - number /= 10; - ++digits; - if (number == 0) - break; - } - - return digits; -} - /** * alsarawmidi_get_device_id_list: * @card_id: The numerical ID of sound card. @@ -140,66 +37,15 @@ static unsigned int calculate_digits(unsigned int number) void alsarawmidi_get_device_id_list(guint card_id, guint **entries, gsize *entry_count, GError **error) { - struct udev_enumerate *enumerator = NULL; - unsigned int length; - char *prefix = NULL; - struct udev_list_entry *entry, *entry_list; - unsigned int count; - unsigned int index; + int err; g_return_if_fail(entries != NULL); g_return_if_fail(entry_count != NULL); g_return_if_fail(error == NULL || *error == NULL); - prepare_udev_enum(&enumerator, error); - if (*error != NULL) - return; - - length = strlen(PREFIX_SYSNAME_TEMPLATE) + calculate_digits(card_id) + 1; - prefix = g_malloc0(length); - - snprintf(prefix, length, PREFIX_SYSNAME_TEMPLATE, card_id); - - entry_list = udev_enumerate_get_list_entry(enumerator); - - count = 0; - udev_list_entry_foreach(entry, entry_list) { - struct udev_device *dev = detect_dev(enumerator, entry, prefix); - if (dev != NULL) { - ++count; - udev_device_unref(dev); - } - } - - // Nothing available. - if (count == 0) - goto end; - - *entries = g_malloc0_n(count, sizeof(**entries)); - - index = 0; - udev_list_entry_foreach(entry, entry_list) { - struct udev_device *dev = detect_dev(enumerator, entry, prefix); - if (dev != NULL) { - const char *sysnum = udev_device_get_sysnum(dev); - long val; - - if (!long_from_string(sysnum, &val)) { - (*entries)[index] = (guint)val; - ++index; - } - udev_device_unref(dev); - } - } - - g_warn_if_fail(index == count); - - *entry_count = count; - - qsort(*entries, count, sizeof(guint), compare_guint); -end: - g_free(prefix); - release_udev_enum(enumerator); + err = generate_rawmidi_sysnum_list(entries, entry_count, card_id); + if (err < 0) + generate_file_error(error, -err, "Fail to generate list of rawmidi sysnum"); } /** diff --git a/src/seq/meson.build b/src/seq/meson.build index 875b34e..ee3b241 100644 --- a/src/seq/meson.build +++ b/src/seq/meson.build @@ -62,7 +62,6 @@ privates = files( dependencies = [ gobject_dependency, - libudev_dependency, utils_dependencies, alsatimer_dependency, ] diff --git a/src/seq/query.c b/src/seq/query.c index 09b640b..8daefba 100644 --- a/src/seq/query.c +++ b/src/seq/query.c @@ -1,16 +1,13 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "privates.h" -#include "utils.h" -#include +#include + #include #include #include -#include #include -#include - -#include +#include /** * SECTION: query diff --git a/src/timer/meson.build b/src/timer/meson.build index a273c4e..2c3a1fb 100644 --- a/src/timer/meson.build +++ b/src/timer/meson.build @@ -44,7 +44,6 @@ privates = files( dependencies = [ gobject_dependency, - libudev_dependency, utils_dependencies, ] diff --git a/src/timer/query.c b/src/timer/query.c index d7e80bf..8deba02 100644 --- a/src/timer/query.c +++ b/src/timer/query.c @@ -3,20 +3,16 @@ #include -#include -#include -#include #include #include #include -#include #include +#include +#include #include #include -#include - /** * SECTION: query * @Title: Global functions in ALSATimer diff --git a/src/utils/sysfs.c b/src/utils/sysfs.c index d7d8306..c8e5b26 100644 --- a/src/utils/sysfs.c +++ b/src/utils/sysfs.c @@ -4,6 +4,7 @@ #include #include #include +#include #define SOUND_SUBSYSTEM "sound" @@ -43,3 +44,131 @@ err_ctx: udev_unref(ctx); return err; } + +static int detect_device(struct udev_device **device, struct udev *ctx, + struct udev_list_entry *entry, const char *prefix) +{ + const char *syspath; + struct udev_device *dev; + const char *sysname; + + syspath = udev_list_entry_get_name(entry); + if (syspath == NULL) + return -errno; + + dev = udev_device_new_from_syspath(ctx, syspath); + if (dev == NULL) + return -errno; + + sysname = udev_device_get_sysname(dev); + if (sysname == NULL) { + udev_device_unref(dev); + return -errno; + } + + if (strstr(sysname, prefix) != sysname) { + udev_device_unref(dev); + return -ENODEV; + } + + *device = dev; + + return 0; +} + +static int compare_u32(const void *l, const void *r) +{ + const unsigned int *x = l; + const unsigned int *y = r; + + return *x > *y; +} + +int generate_sysnum_list_by_sysname_prefix(unsigned int **entries, unsigned long *entry_count, + const char *prefix) +{ + struct udev *ctx; + struct udev_enumerate *enumerator; + unsigned int count; + struct udev_list_entry *entry, *entry_list; + unsigned int index; + int err; + + ctx = udev_new(); + if (ctx == NULL) + return -errno; + + enumerator = udev_enumerate_new(ctx); + if (enumerator == NULL) { + err = -errno; + goto err_ctx; + } + + err = udev_enumerate_add_match_subsystem(enumerator, SOUND_SUBSYSTEM); + if (err < 0) { + goto err_enum; + } + + err = udev_enumerate_scan_devices(enumerator); + if (err < 0) + goto err_enum; + + count = 0; + entry_list = udev_enumerate_get_list_entry(enumerator); + udev_list_entry_foreach(entry, entry_list) { + struct udev_device *dev; + int err; + + err = detect_device(&dev, ctx, entry, prefix); + if (err < 0) + continue; + + ++count; + udev_device_unref(dev); + } + + // Nothing available. + if (count == 0) + goto err_enum; + + *entries = calloc(count, sizeof(**entries)); + if (*entries == NULL) { + err = -ENOMEM; + goto err_enum; + } + + index = 0; + udev_list_entry_foreach(entry, entry_list) { + struct udev_device *dev; + const char *sysnum; + long val; + int err; + + err = detect_device(&dev, ctx, entry, prefix); + if (err < 0) + continue; + + sysnum = udev_device_get_sysnum(dev); + if (sysnum != NULL && !long_from_string(sysnum, &val)) { + (*entries)[index] = (unsigned int)val; + ++index; + } + + udev_device_unref(dev); + } + + if (index != count) { + err = -ENODATA; + goto err_enum; + } + + *entry_count = count; + + qsort(*entries, count, sizeof(unsigned int), compare_u32); +err_enum: + udev_enumerate_unref(enumerator); +err_ctx: + udev_unref(ctx); + + return err; +} diff --git a/src/utils/utils.h b/src/utils/utils.h index 051e30d..a3861d6 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -6,10 +6,15 @@ #include #include -#define CARD_SYSNAME_TEMPLATE "card%u" +#define CARD_SYSNAME_PREFIX "card" +#define CARD_SYSNAME_TEMPLATE CARD_SYSNAME_PREFIX "%u" #define CONTROL_SYSNAME_TEMPLATE "controlC%u" -#define RAWMIDI_SYSNAME_TEMPLATE "midiC%uD%u" -#define HWDEP_SYSNAME_TEMPLATE "hwC%uD%u" +// 'C' is required apart from emulation of Open Sound System. +#define RAWMIDI_SYSNAME_PREFIX_TEMPLATE "midiC%u" +#define RAWMIDI_SYSNAME_TEMPLATE RAWMIDI_SYSNAME_PREFIX_TEMPLATE "D%u" +// 'C' is required apart from emulation of Open Sound System. +#define HWDEP_SYSNAME_PREFIX_TEMPLATE "hwC%u" +#define HWDEP_SYSNAME_TEMPLATE HWDEP_SYSNAME_PREFIX_TEMPLATE "D%u" #define TIMER_SYSNAME "timer" #define SEQ_SYSNAME "seq" @@ -20,6 +25,9 @@ int allocate_string(char **dst, const char *template, va_list ap); int lookup_and_allocate_string_by_sysname(char **name, const char *sysname, const char *(*func)(struct udev_device *)); +int generate_sysnum_list_by_sysname_prefix(unsigned int **entries, unsigned long *entry_count, + const char *prefix); + static inline int lookup_and_allocate_name_by_sysname(char **name, const char *(*func)(struct udev_device *), const char *fmt, va_list ap) @@ -121,4 +129,39 @@ static inline int lookup_and_allocate_seq_devname(char **devname) return lookup_and_allocate_devname_by_sysname(devname, SEQ_SYSNAME); } +static inline int generate_sysnum_list(unsigned int **entries, unsigned long *entry_count, + const char *fmt, ...) +{ + char *prefix; + va_list ap; + int err; + + va_start(ap, fmt); + err = allocate_string(&prefix, fmt, ap); + va_end(ap); + + if (err >= 0) + err = generate_sysnum_list_by_sysname_prefix(entries, entry_count, prefix); + free(prefix); + + return err; +} + +static inline int generate_card_sysnum_list(unsigned int **entries, unsigned long *entry_count) +{ + return generate_sysnum_list(entries, entry_count, CARD_SYSNAME_PREFIX); +} + +static inline int generate_hwdep_sysnum_list(unsigned int **entries, unsigned long *entry_count, + unsigned int card_id) +{ + return generate_sysnum_list(entries, entry_count, HWDEP_SYSNAME_PREFIX_TEMPLATE, card_id); +} + +static inline int generate_rawmidi_sysnum_list(unsigned int **entries, unsigned long *entry_count, + unsigned int card_id) +{ + return generate_sysnum_list(entries, entry_count, RAWMIDI_SYSNAME_PREFIX_TEMPLATE, card_id); +} + #endif