#include <string.h>
#include <errno.h>
#include <stdio.h>
+#include <stdbool.h>
#include <libudev.h>
+#define CARD_SYSNAME_TEMPLATE "card%u"
+
// For error handling.
G_DEFINE_QUARK("alsactl-error", alsactl_error)
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_try_malloc0(length + 1);
+ if (*sysname == NULL) {
+ generate_error(error, ENOMEM);
+ return;
+ }
+
+ 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_error(error, errno);
+ return false;
+ }
+
+ dev = udev_device_new_from_subsystem_sysname(ctx, "sound", sysname);
+ if (dev == NULL) {
+ generate_error(error, errno);
+ 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.
+ * @sysname: (out): The string for sysname of the sound card.
+ * @error: A #GError.
+ *
+ * Allocate sysname for the sound card and return it when it exists.
+ */
+void alsactl_get_card_sysname(guint card_id, char **sysname, GError **error)
+{
+ char *name;
+
+ g_return_if_fail(sysname != 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;
+}