]> git.alsa-project.org Git - alsa-gobject.git/commitdiff
utils: add utilities to allocate string information for device
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sat, 2 Apr 2022 01:46:22 +0000 (10:46 +0900)
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sat, 2 Apr 2022 01:46:22 +0000 (10:46 +0900)
It's typically used to look for string information over sysfs according to
sysname.

This commit adds utilities for it.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
src/ctl/query.c
src/hwdep/query.c
src/rawmidi/query.c
src/seq/query.c
src/timer/query.c
src/utils/meson.build
src/utils/string.c
src/utils/sysfs.c [new file with mode: 0644]
src/utils/utils.h

index 373b69df610645a7abe6c9907cacc382ffbfed13..a06b8dc38c43824c095958239e6399225c4f8165 100644 (file)
@@ -17,9 +17,6 @@
  *                     descriptor
  */
 
-#define CARD_SYSNAME_TEMPLATE       "card%u"
-#define CONTROL_SYSNAME_TEMPLATE    "controlC%u"
-
 #define generate_file_error(exception, errno, msg) \
         g_set_error_literal(exception, G_FILE_ERROR, g_file_error_from_errno(errno), msg)
 
@@ -173,52 +170,6 @@ end:
     release_udev_enum(enumerator);
 }
 
-static void allocate_sysname(char **sysname ,const char *template,
-                             guint card_id, GError **error)
-{
-    unsigned int digits;
-    unsigned int number;
-    unsigned int length;
-
-    digits = 0;
-    number = card_id;
-    while (number > 0) {
-        number /= 10;
-        ++digits;
-    }
-
-    length = strlen(template) + digits;
-    *sysname = g_malloc0(length + 1);
-
-    snprintf(*sysname, length, template, card_id);
-}
-
-static bool check_existence(char *sysname, GError **error)
-{
-    struct udev *ctx;
-    struct udev_device *dev;
-    bool result;
-
-    ctx = udev_new();
-    if (ctx == NULL) {
-        generate_file_error(error, errno, "udev_new()");
-        return false;
-    }
-
-    dev = udev_device_new_from_subsystem_sysname(ctx, "sound", sysname);
-    if (dev == NULL) {
-        generate_file_error(error, errno, "udev_device_new_from_subsystem_sysname()");
-        result = false;
-    } else {
-        result = true;
-    }
-    udev_device_unref(dev);
-
-    udev_unref(ctx);
-
-    return result;
-}
-
 /**
  * alsactl_get_card_sysname:
  * @card_id: The numeridcal ID of sound card.
@@ -231,21 +182,14 @@ static bool check_existence(char *sysname, GError **error)
  */
 void alsactl_get_card_sysname(guint card_id, char **sysname, GError **error)
 {
-    char *name;
+    int err;
 
     g_return_if_fail(sysname != NULL);
     g_return_if_fail(error == NULL || *error == NULL);
 
-    allocate_sysname(&name, CARD_SYSNAME_TEMPLATE, card_id, error);
-    if (*error != NULL)
-        return;
-
-    if (!check_existence(name, error)) {
-        g_free(name);
-        return;
-    }
-
-    *sysname = name;
+    err = lookup_and_allocate_card_sysname(sysname, card_id);
+    if (err < 0)
+        generate_file_error(error, -err, "Fail to generate card sysname");
 }
 
 /**
@@ -261,21 +205,14 @@ void alsactl_get_card_sysname(guint card_id, char **sysname, GError **error)
  */
 void alsactl_get_control_sysname(guint card_id, char **sysname, GError **error)
 {
-    char *name;
+    int err;
 
     g_return_if_fail(sysname != NULL);
     g_return_if_fail(error == NULL || *error == NULL);
 
-    allocate_sysname(&name, CONTROL_SYSNAME_TEMPLATE, card_id, error);
-    if (*error != NULL)
-        return;
-
-    if (!check_existence(name, error)) {
-        g_free(name);
-        return;
-    }
-
-    *sysname = name;
+    err = lookup_and_allocate_control_sysname(sysname, card_id);
+    if (err < 0)
+        generate_file_error(error, -err, "Fail to generate control sysname");
 }
 
 /**
@@ -291,40 +228,12 @@ void alsactl_get_control_sysname(guint card_id, char **sysname, GError **error)
  */
 void alsactl_get_control_devnode(guint card_id, char **devnode, GError **error)
 {
-    char *sysname;
-    struct udev *ctx;
-    struct udev_device *dev;
-    const char *node;
+    int err;
 
     g_return_if_fail(devnode != NULL);
     g_return_if_fail(error == NULL || *error == NULL);
 
-    allocate_sysname(&sysname, CONTROL_SYSNAME_TEMPLATE, card_id, error);
-    if (*error != NULL)
-        return;
-
-    ctx = udev_new();
-    if (ctx == NULL) {
-        generate_file_error(error, errno, "udev_new()");
-        g_free(sysname);
-        return;
-    }
-
-    dev = udev_device_new_from_subsystem_sysname(ctx, "sound", sysname);
-    if (dev == NULL) {
-        generate_file_error(error, ENODEV, "udev_device_new_from_subsystem_sysname()");
-        g_free(sysname);
-        udev_unref(ctx);
-        return;
-    }
-    g_free(sysname);
-
-    node = udev_device_get_devnode(dev);
-    if (node != NULL)
-        *devnode = g_strdup(node);
-    else
-        generate_file_error(error, ENODEV, "udev_device_get_devnode()");
-
-    udev_device_unref(dev);
-    udev_unref(ctx);
+    err = lookup_and_allocate_control_devname(devnode, card_id);
+    if (err < 0)
+        generate_file_error(error, -err, "Fail to generate control devname");
 }
index c345a870ab8953677193657f53c8dddcf585d176..942c18c71291fb42bcc9c150a1b42a573797262d 100644 (file)
@@ -23,8 +23,6 @@
 
 // 'C' is required apart from emulation of Open Sound System.
 #define PREFIX_SYSNAME_TEMPLATE     "hwC%u"
-#define HWDEP_SYSNAME_TEMPLATE      "hwC%uD%u"
-#define CTL_SYSNAME_TEMPLATE        "controlC%u"
 
 #define generate_file_error(error, errno, msg) \
         g_set_error_literal(error, G_FILE_ERROR, g_file_error_from_errno(errno), msg)
@@ -218,37 +216,14 @@ end:
 void alsahwdep_get_hwdep_sysname(guint card_id, guint device_id,
                                  char **sysname, GError **error)
 {
-    unsigned int length;
-    char *name;
-    struct udev *ctx;
-    struct udev_device *dev;
+    int err;
 
     g_return_if_fail(sysname != NULL);
     g_return_if_fail(error == NULL || *error == NULL);
 
-    length = strlen(HWDEP_SYSNAME_TEMPLATE) + calculate_digits(card_id) +
-             calculate_digits(device_id) + 1;
-    name = g_malloc0(length);
-
-    snprintf(name, length, HWDEP_SYSNAME_TEMPLATE, card_id, device_id);
-
-    ctx = udev_new();
-    if (ctx == NULL) {
-        generate_file_error(error, errno, "udev_new()");
-        g_free(name);
-        return;
-    }
-
-    dev = udev_device_new_from_subsystem_sysname(ctx, "sound", name);
-    if (dev == NULL) {
-        generate_file_error(error, ENODEV, "udev_device_new_from_subsystem_sysname()");
-        g_free(name);
-    } else {
-        *sysname = name;
-        udev_device_unref(dev);
-    }
-
-    udev_unref(ctx);
+    err = lookup_and_allocate_hwdep_sysname(sysname, card_id, device_id);
+    if (err < 0)
+        generate_file_error(error, -err, "Fail to generate hwdep sysname");
 }
 
 /**
@@ -265,95 +240,43 @@ void alsahwdep_get_hwdep_sysname(guint card_id, guint device_id,
 void alsahwdep_get_hwdep_devnode(guint card_id, guint device_id,
                                  char **devnode, GError **error)
 {
-    unsigned int length;
-    char *name;
-    struct udev *ctx;
-    struct udev_device *dev;
-    const char *node;
+    int err;
 
     g_return_if_fail(devnode != NULL);
     g_return_if_fail(error == NULL || *error == NULL);
 
-    length = strlen(HWDEP_SYSNAME_TEMPLATE) + calculate_digits(card_id) +
-             calculate_digits(device_id) + 1;
-    name = g_malloc0(length);
-
-    snprintf(name, length, HWDEP_SYSNAME_TEMPLATE, card_id, device_id);
-
-    ctx = udev_new();
-    if (ctx == NULL) {
-        generate_file_error(error, errno, "udev_new()");
-        g_free(name);
-        return;
-    }
-
-    dev = udev_device_new_from_subsystem_sysname(ctx, "sound", name);
-    g_free(name);
-    if (dev == NULL) {
-        generate_file_error(error, ENODEV, "udev_device_new_from_subsystem_sysname()");
-        udev_unref(ctx);
-        return;
-    }
-
-    node = udev_device_get_devnode(dev);
-    if (node == NULL)
-        generate_file_error(error, ENOENT, "udev_device_get_devnode()");
-    else
-        *devnode = g_strdup(node);
-
-    udev_device_unref(dev);
-    udev_unref(ctx);
+    err = lookup_and_allocate_hwdep_devname(devnode, card_id, device_id);
+    if (err < 0)
+        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)
 {
-    unsigned int length;
-    char *sysname;
-    struct udev *ctx;
-    struct udev_device *dev;
-    const char *devnode;
+    char *devname;
     int fd;
+    int err;
 
-    length = strlen(CTL_SYSNAME_TEMPLATE) + calculate_digits(card_id) + 1;
-    sysname = g_malloc0(length);
-
-    snprintf(sysname, length, CTL_SYSNAME_TEMPLATE, card_id);
-
-    ctx = udev_new();
-    if (ctx == NULL) {
-        generate_file_error(error, errno, "udev_new()");
-        goto err_sysname;
-    }
-
-    dev = udev_device_new_from_subsystem_sysname(ctx, "sound", sysname);
-    if (dev == NULL) {
-        generate_file_error(error, errno, "udev_device_new_from_subsystem_sysname()");
-        goto err_ctx;
-    }
+    g_return_if_fail(error == NULL || *error == NULL);
 
-    devnode = udev_device_get_devnode(dev);
-    if (devnode == NULL) {
-        generate_file_error(error, ENODEV, "udev_device_get_devnode()");
-        goto err_device;
+    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(devnode, O_RDONLY | O_NONBLOCK);
+    fd = open(devname, O_RDONLY | O_NONBLOCK);
     if (fd < 0) {
-        generate_file_error_fmt(error, errno, "open(%s)", devnode);
-        goto err_device;
+        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);
+       if (ioctl(fd, request, data) < 0)
+           generate_file_error_fmt(error, errno, "ioctl(%s)", req_label);
 
-    close(fd);
-err_device:
-    udev_device_unref(dev);
-err_ctx:
-    udev_unref(ctx);
-err_sysname:
-    g_free(sysname);
+       close(fd);
+end:
+    free(devname);
 }
 
 /**
index e078b3989343dc41f91e450e127e1cab0c10aee4..a4db8c130ba530f594e5ce9c863eaa46fe76d231 100644 (file)
@@ -23,8 +23,6 @@
 
 // 'C' is required apart from emulation of Open Sound System.
 #define PREFIX_SYSNAME_TEMPLATE     "midiC%u"
-#define RAWMIDI_SYSNAME_TEMPLATE    "midiC%uD%u"
-#define CTL_SYSNAME_TEMPLATE        "controlC%u"
 
 #define generate_file_error(error, errno, msg)    \
     g_set_error_literal(error, G_FILE_ERROR, g_file_error_from_errno(errno), msg)
@@ -218,37 +216,14 @@ end:
 void alsarawmidi_get_rawmidi_sysname(guint card_id, guint device_id,
                                      char **sysname, GError **error)
 {
-    unsigned int length;
-    char *name;
-    struct udev *ctx;
-    struct udev_device *dev;
+    int err;
 
     g_return_if_fail(sysname != NULL);
     g_return_if_fail(error == NULL || *error == NULL);
 
-    length = strlen(RAWMIDI_SYSNAME_TEMPLATE) + calculate_digits(card_id) +
-             calculate_digits(device_id) + 1;
-    name = g_malloc0(length);
-
-    snprintf(name, length, RAWMIDI_SYSNAME_TEMPLATE, card_id, device_id);
-
-    ctx = udev_new();
-    if (ctx == NULL) {
-        generate_file_error(error, errno, "udev_new()");
-        g_free(name);
-        return;
-    }
-
-    dev = udev_device_new_from_subsystem_sysname(ctx, "sound", name);
-    if (dev == NULL) {
-        generate_file_error(error, ENODEV, "udev_device_new_from_subsystem_sysname()");
-        g_free(name);
-    } else {
-        *sysname = name;
-        udev_device_unref(dev);
-    }
-
-    udev_unref(ctx);
+    err = lookup_and_allocate_rawmidi_sysname(sysname, card_id, device_id);
+    if (err < 0)
+        generate_file_error(error, -err, "Fail to generate rawmidi sysname");
 }
 
 /**
@@ -265,83 +240,33 @@ void alsarawmidi_get_rawmidi_sysname(guint card_id, guint device_id,
 void alsarawmidi_get_rawmidi_devnode(guint card_id, guint device_id,
                                      char **devnode, GError **error)
 {
-    unsigned int length;
-    char *name;
-    struct udev *ctx;
-    struct udev_device *dev;
-    const char *node;
+    int err;
 
     g_return_if_fail(devnode != NULL);
     g_return_if_fail(error == NULL || *error == NULL);
 
-    length = strlen(RAWMIDI_SYSNAME_TEMPLATE) + calculate_digits(card_id) +
-             calculate_digits(device_id) + 1;
-    name = g_malloc0(length);
-
-    snprintf(name, length, RAWMIDI_SYSNAME_TEMPLATE, card_id, device_id);
-
-    ctx = udev_new();
-    if (ctx == NULL) {
-        generate_file_error(error, errno, "udev_new()");
-        g_free(name);
-        return;
-    }
-
-    dev = udev_device_new_from_subsystem_sysname(ctx, "sound", name);
-    g_free(name);
-    if (dev == NULL) {
-        generate_file_error(error, ENODEV, "udev_device_new_from_subsystem_sysname()");
-        udev_unref(ctx);
-        return;
-    }
-
-    node = udev_device_get_devnode(dev);
-    if (node == NULL)
-        generate_file_error(error, ENOENT, "udev_device_get_devnode()");
-    else
-        *devnode = g_strdup(node);
-
-    udev_device_unref(dev);
-    udev_unref(ctx);
+    err = lookup_and_allocate_rawmidi_devname(devnode, card_id, device_id);
+    if (err < 0)
+        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)
 {
-    unsigned int length;
-    char *sysname;
-    struct udev *ctx;
-    struct udev_device *dev;
-    const char *devnode;
+    char *devname;
     int fd;
+    int err;
 
-    length = strlen(CTL_SYSNAME_TEMPLATE) + calculate_digits(card_id) + 1;
-    sysname = g_malloc0(length);
-
-    snprintf(sysname, length, CTL_SYSNAME_TEMPLATE, card_id);
-
-    ctx = udev_new();
-    if (ctx == NULL) {
-        generate_file_error(error, errno, "udev_new()");
-        goto err_sysname;
-    }
-
-    dev = udev_device_new_from_subsystem_sysname(ctx, "sound", sysname);
-    if (dev == NULL) {
-        generate_file_error(error, errno, "udev_device_new_from_subsystem_sysname()");
-        goto err_ctx;
-    }
-
-    devnode = udev_device_get_devnode(dev);
-    if (devnode == NULL) {
-        generate_file_error(error, ENODEV, "udev_device_get_devnode()");
-        goto err_device;
+    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(devnode, O_RDONLY);
+    fd = open(devname, O_RDONLY);
     if (fd < 0) {
-        generate_file_error_fmt(error, errno, "open(%s)", devnode);
-        goto err_device;
+        generate_file_error_fmt(error, errno, "open(%s)", devname);
+        goto end;
     }
 
     if (ioctl(fd, request, data) < 0)
@@ -352,12 +277,8 @@ static void rawmidi_perform_ctl_ioctl(guint card_id, long request, void *data,
         *ctl_fd = fd;
     else
         close(fd);
-err_device:
-    udev_device_unref(dev);
-err_ctx:
-    udev_unref(ctx);
-err_sysname:
-    g_free(sysname);
+end:
+    free(devname);
 }
 
 /**
index da956899123b7771b0936859ec916d25d6646c35..09b640b9017784088999d5b6ab61c4ba429cbb58 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: LGPL-3.0-or-later
 #include "privates.h"
+#include "utils.h"
 
 #include <errno.h>
 #include <sys/types.h>
@@ -18,8 +19,6 @@
  *                     descriptor
  */
 
-#define SEQ_SYSNAME   "seq"
-
 #define generate_file_error(exception, errno, msg) \
         g_set_error_literal(exception, G_FILE_ERROR, g_file_error_from_errno(errno), msg)
 
  */
 void alsaseq_get_seq_sysname(gchar **sysname, GError **error)
 {
-    struct udev *ctx;
-    struct udev_device *dev;
-    const char *name;
+    int err;
 
     g_return_if_fail(sysname != NULL);
     g_return_if_fail(error == NULL || *error == NULL);
 
-    ctx = udev_new();
-    if (ctx == NULL) {
-        generate_file_error(error, errno, "udev_new()");
-        return;
-    }
-
-    dev = udev_device_new_from_subsystem_sysname(ctx, "sound", SEQ_SYSNAME);
-    if (dev == NULL) {
-        generate_file_error(error, errno, "udev_enumerate_new()");
-        udev_unref(ctx);
-        return;
-    }
-
-    name = udev_device_get_sysname(dev);
-    if (name == NULL) {
-        generate_file_error(error, errno, "udev_enumerate_add_match_subsystem()");
-        udev_device_unref(dev);
-        udev_unref(ctx);
-        return;
-    }
-
-    *sysname = g_strdup(name);
-
-    udev_device_unref(dev);
-    udev_unref(ctx);
+    err = lookup_and_allocate_seq_sysname(sysname);
+    if (err < 0)
+        generate_file_error(error, -err, "Fail to generate seq sysname");
 }
 
 /**
@@ -82,56 +57,29 @@ void alsaseq_get_seq_sysname(gchar **sysname, GError **error)
  */
 void alsaseq_get_seq_devnode(gchar **devnode, GError **error)
 {
-    struct udev *ctx;
-    struct udev_device *dev;
-    const char *node;
+    int err;
 
     g_return_if_fail(devnode != NULL);
     g_return_if_fail(error == NULL || *error == NULL);
 
-    ctx = udev_new();
-    if (ctx == NULL) {
-        generate_file_error(error, errno, "udev_new()");
-        return;
-    }
-
-    dev = udev_device_new_from_subsystem_sysname(ctx, "sound", SEQ_SYSNAME);
-    if (dev == NULL) {
-        generate_file_error(error, errno, "udev_device_new_from_subsystem_sysname()");
-        udev_unref(ctx);
-        return;
-    }
-
-    node = udev_device_get_devnode(dev);
-    if (node == NULL) {
-        generate_file_error(error, ENODEV, "udev_device_get_devnode()");
-        udev_device_unref(dev);
-        udev_unref(ctx);
-        return;
-    }
-
-    *devnode = g_strdup(node);
-
-    udev_device_unref(dev);
-    udev_unref(ctx);
+    err = lookup_and_allocate_seq_devname(devnode);
+    if (err < 0)
+        generate_file_error(error, -err, "Fail to generate seq devname");
 }
 
 static int open_fd(GError **error)
 {
-    char *devnode;
+    char *devname;
     int fd;
 
-    alsaseq_get_seq_devnode(&devnode, error);
+    alsaseq_get_seq_devnode(&devname, error);
     if (*error != NULL)
         return -1;
 
-    fd = open(devnode, O_RDONLY);
-    if (fd < 0) {
-        generate_file_error_fmt(error, errno, "open(%s)", devnode);
-        g_free(devnode);
-        return -1;
-    }
-    g_free(devnode);
+    fd = open(devname, O_RDONLY);
+    if (fd < 0)
+        generate_file_error_fmt(error, errno, "open(%s)", devname);
+    g_free(devname);
 
     return fd;
 }
index 38904e998aa424f2e111cc10075087c6da8f0614..d7e80bf527fc620c706ba3fd90d8611b8f974e38 100644 (file)
@@ -24,7 +24,6 @@
  *                     file descriptor
  */
 
-#define TIMER_SYSNAME_TEMPLATE  "timer"
 #define SYSFS_SND_TIMER_NODE    "/sys/module/snd_timer/"
 
 #define generate_file_error(exception, errno, msg) \
 #define generate_file_error_fmt(exception, errno, fmt, msg) \
         g_set_error(exception, G_FILE_ERROR, g_file_error_from_errno(errno), fmt, msg)
 
-static bool check_existence(char *sysname, GError **error)
-{
-    struct udev *ctx;
-    struct udev_device *dev;
-    bool result;
-
-    ctx = udev_new();
-    if (ctx == NULL) {
-        generate_file_error(error, errno, "udev_new()");
-        return false;
-    }
-
-    dev = udev_device_new_from_subsystem_sysname(ctx, "sound", sysname);
-    if (dev == NULL) {
-        generate_file_error(error, errno, "udev_device_new_from_subsystem_sysname()");
-        result = false;
-    } else {
-        result = true;
-    }
-    udev_device_unref(dev);
-
-    udev_unref(ctx);
-
-    return result;
-}
-
 /**
  * alsatimer_get_sysname:
  * @sysname: (out): The string for sysname of ALSA Timer.
@@ -70,19 +43,14 @@ static bool check_existence(char *sysname, GError **error)
  */
 void alsatimer_get_sysname(char **sysname, GError **error)
 {
-    char *name;
+    int err;
 
     g_return_if_fail(sysname != NULL);
     g_return_if_fail(error == NULL || *error == NULL);
 
-    name = g_strdup(TIMER_SYSNAME_TEMPLATE);
-
-    if (!check_existence(name, error)) {
-        g_free(name);
-        return;
-    }
-
-    *sysname = name;
+    err = lookup_and_allocate_timer_sysname(sysname);
+    if (err < 0)
+        generate_file_error(error, -err, "Fail to generate timer sysname");
 }
 
 /**
@@ -96,54 +64,29 @@ void alsatimer_get_sysname(char **sysname, GError **error)
  */
 void alsatimer_get_devnode(char **devnode, GError **error)
 {
-    struct udev *ctx;
-    struct udev_device *dev;
-    const char *node;
+    int err;
 
     g_return_if_fail(devnode != NULL);
     g_return_if_fail(error == NULL || *error == NULL);
 
-    ctx = udev_new();
-    if (ctx == NULL) {
-        generate_file_error(error, errno, "udev_new()");
-        return;
-    }
-
-    dev = udev_device_new_from_subsystem_sysname(ctx, "sound",
-                                                 TIMER_SYSNAME_TEMPLATE);
-    if (dev == NULL) {
-        generate_file_error(error, ENODEV, "udev_device_new_from_subsystem_sysname()");
-        udev_unref(ctx);
-        return;
-    }
-
-    node = udev_device_get_devnode(dev);
-    if (node != NULL)
-        *devnode = g_strdup(node);
-    else
-        generate_file_error(error, ENODEV, "udev_device_get_devnode()");
-
-    udev_device_unref(dev);
-    udev_unref(ctx);
+    err = lookup_and_allocate_timer_devname(devnode);
+    if (err < 0)
+        generate_file_error(error, -err, "Fail to generate timer devname");
 }
 
 static int open_fd(GError **error)
 {
-    char *devnode;
+    char *devname;
     int fd;
 
-    alsatimer_get_devnode(&devnode, error);
+    alsatimer_get_devnode(&devname, error);
     if (*error != NULL)
         return -1;
 
-    fd = open(devnode, O_RDONLY);
-    if (fd < 0) {
-        generate_file_error_fmt(error, errno, "open(%s)", devnode);
-       g_free(devnode);
-        return -1;
-    }
-
-    g_free(devnode);
+    fd = open(devname, O_RDONLY);
+    if (fd < 0)
+        generate_file_error_fmt(error, errno, "open(%s)", devname);
+    g_free(devname);
 
     return fd;
 }
index 20cf8d00531b6c4260c1bbf1b0c77308da51358f..d418eaf324eb83dec2e4459934fc725541b4c7e6 100644 (file)
@@ -4,9 +4,11 @@ headers = [
 
 sources = [
   'string.c',
+  'sysfs.c',
 ]
 
 dependencies = [
+  dependency('libudev'),
 ]
 
 static_library = static_library('utils',
index 72689dee6b19fccb5f15bfb924af61ab53597fac..fe0ab13c2706a500c2140276dc86f6e2761c3973 100644 (file)
@@ -1,6 +1,8 @@
 // SPDX-License-Identifier: LGPL-3.0-or-later
-#include <stdlib.h>
+#include "utils.h"
+
 #include <errno.h>
+#include <stdio.h>
 
 long long_from_string(const char *literal, long *number)
 {
@@ -16,3 +18,30 @@ long long_from_string(const char *literal, long *number)
     *number = val;
     return 0;
 }
+
+int allocate_string(char **dst, const char *template, va_list ap)
+{
+    char *label;
+    int size;
+    va_list aq;
+
+    va_copy(aq, ap);
+    size = vsnprintf(NULL, 0, template, aq);
+    va_end(aq);
+
+    if (size < 0)
+        return -EINVAL;
+    size += 1;
+
+    label = malloc(size);
+    if (label == NULL)
+        return -ENOMEM;
+
+    va_copy(aq, ap);
+    vsnprintf(label, size, template, aq);
+    va_end(aq);
+
+    *dst = label;
+
+    return 0;
+}
diff --git a/src/utils/sysfs.c b/src/utils/sysfs.c
new file mode 100644 (file)
index 0000000..d7d8306
--- /dev/null
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: LGPL-3.0-or-later
+#include "utils.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#define SOUND_SUBSYSTEM     "sound"
+
+int lookup_and_allocate_string_by_sysname(char **name, const char *sysname,
+                                          const char *(*func)(struct udev_device *))
+{
+    struct udev *ctx;
+    struct udev_device *device;
+    const char *n;
+    int err = 0;
+
+    if (name == NULL || sysname == NULL || func == NULL)
+        return -EINVAL;
+
+    ctx = udev_new();
+    if (ctx == NULL)
+        return -errno;
+
+    device = udev_device_new_from_subsystem_sysname(ctx, SOUND_SUBSYSTEM, sysname);
+    if (device == NULL) {
+        err = -errno;
+        goto err_ctx;
+    }
+
+    n = func(device);
+    if (n == NULL) {
+        err = -errno;
+        goto err_dev;
+    }
+
+    *name = strdup(n);
+    if (*name == NULL)
+        err = -ENOMEM;
+err_dev:
+    udev_device_unref(device);
+err_ctx:
+    udev_unref(ctx);
+    return err;
+}
index 43257855763771a9ed02dc36270c0abd1ab6e330..051e30d709c52f299318fe9a49f4096bc85c2ac9 100644 (file)
@@ -2,6 +2,123 @@
 #ifndef __ALSA_GOBJECT_UTILS_H__
 #define __ALSA_GOBJECT_UTILS_H__
 
+#include <stdlib.h>
+#include <stdarg.h>
+#include <libudev.h>
+
+#define CARD_SYSNAME_TEMPLATE           "card%u"
+#define CONTROL_SYSNAME_TEMPLATE        "controlC%u"
+#define RAWMIDI_SYSNAME_TEMPLATE        "midiC%uD%u"
+#define HWDEP_SYSNAME_TEMPLATE          "hwC%uD%u"
+#define TIMER_SYSNAME                   "timer"
+#define SEQ_SYSNAME                     "seq"
+
 long long_from_string(const char *literal, long *number);
 
+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 *));
+
+static inline int lookup_and_allocate_name_by_sysname(char **name,
+                                                      const char *(*func)(struct udev_device *),
+                                                      const char *fmt, va_list ap)
+{
+    char *sysname;
+    int err;
+
+    err = allocate_string(&sysname, fmt, ap);
+    if (err >= 0)
+        err = lookup_and_allocate_string_by_sysname(name, sysname, func);
+    free(sysname);
+    return err;
+}
+
+static inline int lookup_and_allocate_sysname_by_sysname(char **sysname, const char *fmt, ...)
+{
+    va_list ap;
+    int err;
+
+    va_start(ap, fmt);
+    err = lookup_and_allocate_name_by_sysname(sysname, udev_device_get_sysname, fmt, ap);
+    va_end(ap);
+
+    return err;
+}
+
+static inline int lookup_and_allocate_devname_by_sysname(char **devname, const char *fmt, ...)
+{
+    va_list ap;
+    int err;
+
+    va_start(ap, fmt);
+    err = lookup_and_allocate_name_by_sysname(devname, udev_device_get_devnode, fmt, ap);
+    va_end(ap);
+
+    return err;
+}
+
+static inline int lookup_and_allocate_card_sysname(char **sysname, unsigned int card_id)
+{
+    return lookup_and_allocate_sysname_by_sysname(sysname, CARD_SYSNAME_TEMPLATE, card_id);
+}
+
+static inline int lookup_and_allocate_control_sysname(char **sysname, unsigned int card_id)
+{
+    return lookup_and_allocate_sysname_by_sysname(sysname, CONTROL_SYSNAME_TEMPLATE, card_id);
+}
+
+static inline int lookup_and_allocate_control_devname(char **devname, unsigned int card_id)
+{
+    return lookup_and_allocate_devname_by_sysname(devname, CONTROL_SYSNAME_TEMPLATE, card_id);
+}
+
+static inline int lookup_and_allocate_hwdep_sysname(char **sysname, unsigned int card_id,
+                                                    unsigned int device_id)
+{
+    return lookup_and_allocate_sysname_by_sysname(sysname, HWDEP_SYSNAME_TEMPLATE, card_id,
+                                                  device_id);
+}
+
+static inline int lookup_and_allocate_hwdep_devname(char **devname, unsigned int card_id,
+                                                    unsigned int device_id)
+{
+    return lookup_and_allocate_devname_by_sysname(devname, HWDEP_SYSNAME_TEMPLATE, card_id,
+                                                  device_id);
+}
+
+static inline int lookup_and_allocate_rawmidi_sysname(char **sysname, unsigned int card_id,
+                                                      unsigned int device_id)
+{
+    return lookup_and_allocate_sysname_by_sysname(sysname, RAWMIDI_SYSNAME_TEMPLATE, card_id,
+                                                  device_id);
+}
+
+static inline int lookup_and_allocate_rawmidi_devname(char **devname, unsigned int card_id,
+                                                      unsigned int device_id)
+{
+    return lookup_and_allocate_devname_by_sysname(devname, RAWMIDI_SYSNAME_TEMPLATE, card_id,
+                                                  device_id);
+}
+
+static inline int lookup_and_allocate_timer_sysname(char **sysname)
+{
+    return lookup_and_allocate_sysname_by_sysname(sysname, TIMER_SYSNAME);
+}
+
+static inline int lookup_and_allocate_timer_devname(char **devname)
+{
+    return lookup_and_allocate_devname_by_sysname(devname, TIMER_SYSNAME);
+}
+
+static inline int lookup_and_allocate_seq_sysname(char **sysname)
+{
+    return lookup_and_allocate_sysname_by_sysname(sysname, SEQ_SYSNAME);
+}
+
+static inline int lookup_and_allocate_seq_devname(char **devname)
+{
+    return lookup_and_allocate_devname_by_sysname(devname, SEQ_SYSNAME);
+}
+
 #endif