diff --git a/alsactl/alsactl.h b/alsactl/alsactl.h index 0e24d60..ca723e3 100644 --- a/alsactl/alsactl.h +++ b/alsactl/alsactl.h @@ -1,3 +1,4 @@ +#include #include extern int debugflag; @@ -9,6 +10,13 @@ extern char *command; extern char *statefile; extern char *lockfile; +struct snd_card_iterator { + int card; + char name[16]; + bool single; + bool first; +}; + void info_(const char *fcn, long line, const char *fmt, ...); void error_(const char *fcn, long line, const char *fmt, ...); void cerror_(const char *fcn, long line, int cond, const char *fmt, ...); @@ -32,6 +40,11 @@ void error_handler(const char *file, int line, const char *function, int err, co #define FLAG_UCM_BOOT (1<<2) #define FLAG_UCM_DEFAULTS (1<<3) +void snd_card_iterator_init(struct snd_card_iterator *iter, int cardno); +int snd_card_iterator_sinit(struct snd_card_iterator *iter, const char *cardname); +const char *snd_card_iterator_next(struct snd_card_iterator *iter); +int snd_card_iterator_error(struct snd_card_iterator *iter); + int load_configuration(const char *file, snd_config_t **top, int *open_failed); int init(const char *file, int flags, const char *cardname); int init_ucm(int flags, int cardno); diff --git a/alsactl/clean.c b/alsactl/clean.c index 4808225..6dfc6d3 100644 --- a/alsactl/clean.c +++ b/alsactl/clean.c @@ -182,46 +182,15 @@ fin_err: int clean(const char *cardname, char *const *extra_args) { + struct snd_card_iterator iter; int err; - if (!cardname) { - int card, first = 1; - - card = -1; - /* find each installed soundcards */ - while (1) { - if (snd_card_next(&card) < 0) - break; - if (card < 0) { - if (first) { - if (ignore_nocards) { - err = 0; - goto out; - } else { - error("No soundcards found..."); - err = -ENODEV; - goto out; - } - } - break; - } - first = 0; - if ((err = clean_controls(card, extra_args))) - goto out; - } - } else { - int cardno; - - cardno = snd_card_get_index(cardname); - if (cardno < 0) { - error("Cannot find soundcard '%s'...", cardname); - err = cardno; - goto out; - } - if ((err = clean_controls(cardno, extra_args))) { - goto out; - } + err = snd_card_iterator_sinit(&iter, cardname); + if (err < 0) + return err; + while (snd_card_iterator_next(&iter)) { + if ((err = clean_controls(iter.card, extra_args))) + return err; } -out: - return err; + return snd_card_iterator_error(&iter); } diff --git a/alsactl/init_parse.c b/alsactl/init_parse.c index 4034b4d..ab2c906 100644 --- a/alsactl/init_parse.c +++ b/alsactl/init_parse.c @@ -1746,63 +1746,33 @@ static int parse(struct space *space, const char *filename) int init(const char *filename, int flags, const char *cardname) { struct space *space; - int err = 0, lasterr = 0, card, first; + struct snd_card_iterator iter; + int err = 0, lasterr = 0; sysfs_init(); - if (!cardname) { - first = 1; - card = -1; - while (1) { - if (snd_card_next(&card) < 0) - break; - if (card < 0) { - if (first) { - if (ignore_nocards) - return 0; - error("No soundcards found..."); - return -ENODEV; - } - break; - } - first = 0; - err = init_ucm(flags, card); - if (err == 0) - continue; - err = init_space(&space, card); - if (err == 0) { - space->rootdir = new_root_dir(filename); - if (space->rootdir != NULL) - err = parse(space, filename); - if (err <= -99) { /* non-fatal errors */ - if (lasterr == 0) - lasterr = err; - err = 0; - } - free_space(space); - } - if (err < 0) - break; - } - err = lasterr; - } else { - card = snd_card_get_index(cardname); - if (card < 0) { - error("Cannot find soundcard '%s'...", cardname); - goto error; - } - err = init_ucm(flags, card); + err = snd_card_iterator_sinit(&iter, cardname); + while (snd_card_iterator_next(&iter)) { + err = init_ucm(flags, iter.card); if (err == 0) - return 0; - memset(&space, 0, sizeof(space)); - err = init_space(&space, card); - if (err == 0) { - space->rootdir = new_root_dir(filename); - if (space->rootdir != NULL) - err = parse(space, filename); - free_space(space); + continue; + err = init_space(&space, iter.card); + if (err != 0) + continue; + space->rootdir = new_root_dir(filename); + if (space->rootdir != NULL) { + err = parse(space, filename); + if (!cardname && err <= -99) { /* non-fatal errors */ + if (lasterr == 0) + lasterr = err; + err = 0; + } } + free_space(space); + if (err < 0) + goto out; } - error: + err = lasterr ? lasterr : snd_card_iterator_error(&iter); +out: sysfs_cleanup(); return err; } diff --git a/alsactl/monitor.c b/alsactl/monitor.c index fa6cd85..4c02557 100644 --- a/alsactl/monitor.c +++ b/alsactl/monitor.c @@ -28,11 +28,12 @@ #include #include #include -#include #include #include "list.h" +#include "alsactl.h" + struct src_entry { snd_ctl_t *handle; char *name; @@ -40,29 +41,6 @@ struct src_entry { struct list_head list; }; -struct snd_card_iterator { - int card; - char name[16]; -}; - -void snd_card_iterator_init(struct snd_card_iterator *iter) -{ - iter->card = -1; - memset(iter->name, 0, sizeof(iter->name)); -} - -static const char *snd_card_iterator_next(struct snd_card_iterator *iter) -{ - if (snd_card_next(&iter->card) < 0) - return NULL; - if (iter->card < 0) - return NULL; - - snprintf(iter->name, sizeof(iter->name), "hw:%d", iter->card); - - return (const char *)iter->name; -} - static void remove_source_entry(struct src_entry *entry) { list_del(&entry->list); @@ -159,7 +137,7 @@ static int prepare_source_entry(struct list_head *srcs, const char *name) struct snd_card_iterator iter; const char *cardname; - snd_card_iterator_init(&iter); + snd_card_iterator_init(&iter, -1); while ((cardname = snd_card_iterator_next(&iter))) { if (seek_entry_by_name(srcs, cardname)) continue; diff --git a/alsactl/state.c b/alsactl/state.c index e39e878..0612970 100644 --- a/alsactl/state.c +++ b/alsactl/state.c @@ -1544,6 +1544,7 @@ int save_state(const char *file, const char *cardname) int stdio; char *nfile = NULL; int lock_fd = -EINVAL; + struct snd_card_iterator iter; err = snd_config_top(&config); if (err < 0) { @@ -1577,45 +1578,18 @@ int save_state(const char *file, const char *cardname) #endif } - if (!cardname) { - int card, first = 1; - - card = -1; - /* find each installed soundcards */ - while (1) { - if (snd_card_next(&card) < 0) - break; - if (card < 0) { - if (first) { - if (ignore_nocards) { - err = 0; - goto out; - } else { - error("No soundcards found..."); - err = -ENODEV; - goto out; - } - } - break; - } - first = 0; - if ((err = get_controls(card, config))) - goto out; - } - } else { - int cardno; - - cardno = snd_card_get_index(cardname); - if (cardno < 0) { - error("Cannot find soundcard '%s'...", cardname); - err = cardno; + err = snd_card_iterator_sinit(&iter, cardname); + if (err < 0) + goto out; + while (snd_card_iterator_next(&iter)) { + if ((err = get_controls(iter.card, config))) goto out; - } - if ((err = get_controls(cardno, config))) { - goto out; - } } - + if (iter.first) { + err = snd_card_iterator_error(&iter); + goto out; + } + if (stdio) { err = snd_output_stdio_attach(&out, stdout, 0); } else { @@ -1648,119 +1622,58 @@ int load_state(const char *file, const char *initfile, int initflags, const char *cardname, int do_init) { int err, finalerr = 0, open_failed; + struct snd_card_iterator iter; snd_config_t *config; + const char *cardname1; err = load_configuration(file, &config, &open_failed); if (err < 0 && !open_failed) return err; if (open_failed) { - int card, first = 1; - char cardname1[16]; - error("Cannot open %s for reading: %s", file, snd_strerror(err)); finalerr = err; - if (cardname) { - card = snd_card_get_index(cardname); - if (card < 0) { - error("Cannot find soundcard '%s'...", cardname); - err = -ENODEV; - goto out; - } - goto single; - } else { - card = -1; - } - /* find each installed soundcards */ - while (!cardname) { - if (snd_card_next(&card) < 0) - break; - if (card < 0) - break; -single: - first = 0; + + err = snd_card_iterator_sinit(&iter, cardname); + if (err < 0) + return err; + while ((cardname1 = snd_card_iterator_next(&iter)) != NULL) { if (!do_init) break; - sprintf(cardname1, "%i", card); err = init(initfile, initflags | FLAG_UCM_FBOOT | FLAG_UCM_BOOT, cardname1); if (err < 0) { finalerr = err; - initfailed(card, "init", err); + initfailed(iter.card, "init", err); } - initfailed(card, "restore", -ENOENT); + initfailed(iter.card, "restore", -ENOENT); } - if (first) - finalerr = 0; /* no cards, no error code */ err = finalerr; + if (iter.first) + err = 0; /* no cards, no error code */ goto out; } - if (!cardname) { - int card, first = 1; - char cardname1[16]; - - card = -1; - /* find each installed soundcards */ - while (1) { - if (snd_card_next(&card) < 0) - break; - if (card < 0) { - if (first) { - if (ignore_nocards) { - err = 0; - goto out; - } else { - error("No soundcards found..."); - err = -ENODEV; - goto out; - } - } - break; - } - first = 0; - /* error is ignored */ - init_ucm(initflags | FLAG_UCM_FBOOT, card); - /* do a check if controls matches state file */ - if (do_init && set_controls(card, config, 0)) { - sprintf(cardname1, "%i", card); - err = init(initfile, initflags | FLAG_UCM_BOOT, cardname1); - if (err < 0) { - initfailed(card, "init", err); - finalerr = err; - } - } - if ((err = set_controls(card, config, 1))) { - if (!force_restore) - finalerr = err; - initfailed(card, "restore", err); - } - } - } else { - int cardno; - - cardno = snd_card_get_index(cardname); - if (cardno < 0) { - error("Cannot find soundcard '%s'...", cardname); - err = -ENODEV; - goto out; - } + err = snd_card_iterator_sinit(&iter, cardname); + if (err < 0) + goto out; + while ((cardname1 = snd_card_iterator_next(&iter)) != NULL) { /* error is ignored */ - init_ucm(initflags | FLAG_UCM_FBOOT, cardno); + init_ucm(initflags | FLAG_UCM_FBOOT, iter.card); /* do a check if controls matches state file */ - if (do_init && set_controls(cardno, config, 0)) { - err = init(initfile, initflags | FLAG_UCM_BOOT, cardname); + if (do_init && set_controls(iter.card, config, 0)) { + err = init(initfile, initflags | FLAG_UCM_BOOT, cardname1); if (err < 0) { - initfailed(cardno, "init", err); + initfailed(iter.card, "init", err); finalerr = err; } } - if ((err = set_controls(cardno, config, 1))) { - initfailed(cardno, "restore", err); + if ((err = set_controls(iter.card, config, 1))) { if (!force_restore) - goto out; + finalerr = err; + initfailed(iter.card, "restore", err); } } - err = finalerr; + err = finalerr ? finalerr : snd_card_iterator_error(&iter); out: snd_config_delete(config); snd_config_update_free_global(); diff --git a/alsactl/utils.c b/alsactl/utils.c index ede7319..d0b1ac6 100644 --- a/alsactl/utils.c +++ b/alsactl/utils.c @@ -233,3 +233,54 @@ out: return 0; } } + +void snd_card_iterator_init(struct snd_card_iterator *iter, int cardno) +{ + iter->card = cardno; + iter->single = cardno >= 0; + iter->first = true; + iter->name[0] = '\0'; +} + +int snd_card_iterator_sinit(struct snd_card_iterator *iter, const char *cardname) +{ + int cardno = -1; + + if (cardname) { + cardno = snd_card_get_index(cardname); + if (cardno < 0) { + error("Cannot find soundcard '%s'...", cardname); + return cardno; + } + } + snd_card_iterator_init(iter, cardno); + return 0; +} + +const char *snd_card_iterator_next(struct snd_card_iterator *iter) +{ + if (iter->single) { + if (iter->first) { + iter->first = false; + goto retval; + } + return NULL; + } + if (snd_card_next(&iter->card) < 0) { + if (!ignore_nocards && iter->first) + error("No soundcards found..."); + return NULL; + } + iter->first = false; + if (iter->card < 0) + return NULL; +retval: + snprintf(iter->name, sizeof(iter->name), "hw:%d", iter->card); + + return (const char *)iter->name; +} + +int snd_card_iterator_error(struct snd_card_iterator *iter) +{ + return iter->first ? (ignore_nocards ? 0 : -ENODEV) : 0; +}