mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-14 04:55:41 +01:00
alsactl: safe state store and memory allocation cleanups
- store new configuration to file + ".new" extension, rename later - free the configuration tree on exit from load_state()/save_state() - call snd_config_update_free_global() at the end of command blocks Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
6de3c709b3
commit
e3e85a851c
2 changed files with 55 additions and 20 deletions
|
@ -176,6 +176,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (!strcmp(argv[optind], "init")) {
|
if (!strcmp(argv[optind], "init")) {
|
||||||
res = init(initfile, cardname);
|
res = init(initfile, cardname);
|
||||||
|
snd_config_update_free_global();
|
||||||
} else if (!strcmp(argv[optind], "store")) {
|
} else if (!strcmp(argv[optind], "store")) {
|
||||||
res = save_state(cfgfile, cardname);
|
res = save_state(cfgfile, cardname);
|
||||||
} else if (!strcmp(argv[optind], "restore")) {
|
} else if (!strcmp(argv[optind], "restore")) {
|
||||||
|
|
|
@ -1546,6 +1546,7 @@ int save_state(const char *file, const char *cardname)
|
||||||
snd_input_t *in;
|
snd_input_t *in;
|
||||||
snd_output_t *out;
|
snd_output_t *out;
|
||||||
int stdio;
|
int stdio;
|
||||||
|
char *nfile = NULL;
|
||||||
|
|
||||||
err = snd_config_top(&config);
|
err = snd_config_top(&config);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
@ -1553,13 +1554,22 @@ int save_state(const char *file, const char *cardname)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
stdio = !strcmp(file, "-");
|
stdio = !strcmp(file, "-");
|
||||||
|
if (!stdio) {
|
||||||
|
nfile = malloc(strlen(file) + 5);
|
||||||
|
if (nfile == NULL) {
|
||||||
|
error("No enough memory...");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
strcpy(nfile, file);
|
||||||
|
strcat(nfile, ".new");
|
||||||
|
}
|
||||||
if (!stdio && (err = snd_input_stdio_open(&in, file, "r")) >= 0) {
|
if (!stdio && (err = snd_input_stdio_open(&in, file, "r")) >= 0) {
|
||||||
err = snd_config_load(config, in);
|
err = snd_config_load(config, in);
|
||||||
snd_input_close(in);
|
snd_input_close(in);
|
||||||
#if 0
|
#if 0
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
error("snd_config_load error: %s", snd_strerror(err));
|
error("snd_config_load error: %s", snd_strerror(err));
|
||||||
return err;
|
goto out;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1575,17 +1585,19 @@ int save_state(const char *file, const char *cardname)
|
||||||
if (card < 0) {
|
if (card < 0) {
|
||||||
if (first) {
|
if (first) {
|
||||||
if (ignore_nocards) {
|
if (ignore_nocards) {
|
||||||
return 0;
|
err = 0;
|
||||||
|
goto out;
|
||||||
} else {
|
} else {
|
||||||
error("No soundcards found...");
|
error("No soundcards found...");
|
||||||
return -ENODEV;
|
err = -ENODEV;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
first = 0;
|
first = 0;
|
||||||
if ((err = get_controls(card, config)))
|
if ((err = get_controls(card, config)))
|
||||||
return err;
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int cardno;
|
int cardno;
|
||||||
|
@ -1593,26 +1605,39 @@ int save_state(const char *file, const char *cardname)
|
||||||
cardno = snd_card_get_index(cardname);
|
cardno = snd_card_get_index(cardname);
|
||||||
if (cardno < 0) {
|
if (cardno < 0) {
|
||||||
error("Cannot find soundcard '%s'...", cardname);
|
error("Cannot find soundcard '%s'...", cardname);
|
||||||
return cardno;
|
err = cardno;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
if ((err = get_controls(cardno, config))) {
|
if ((err = get_controls(cardno, config))) {
|
||||||
return err;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stdio)
|
if (stdio) {
|
||||||
err = snd_output_stdio_attach(&out, stdout, 0);
|
err = snd_output_stdio_attach(&out, stdout, 0);
|
||||||
else
|
} else {
|
||||||
err = snd_output_stdio_open(&out, file, "w");
|
err = snd_output_stdio_open(&out, nfile, "w");
|
||||||
|
}
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
error("Cannot open %s for writing: %s", file, snd_strerror(err));
|
error("Cannot open %s for writing: %s", file, snd_strerror(err));
|
||||||
return -errno;
|
err = -errno;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
err = snd_config_save(config, out);
|
err = snd_config_save(config, out);
|
||||||
snd_output_close(out);
|
snd_output_close(out);
|
||||||
if (err < 0)
|
if (err < 0) {
|
||||||
error("snd_config_save: %s", snd_strerror(err));
|
error("snd_config_save: %s", snd_strerror(err));
|
||||||
return 0;
|
} else {
|
||||||
|
//unlink(file);
|
||||||
|
err = rename(nfile, file);
|
||||||
|
if (err < 0)
|
||||||
|
error("rename failed: %s (%s)", strerror(-err), file);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
free(nfile);
|
||||||
|
snd_config_delete(config);
|
||||||
|
snd_config_update_free_global();
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_state(const char *file, const char *initfile, const char *cardname,
|
int load_state(const char *file, const char *initfile, const char *cardname,
|
||||||
|
@ -1638,7 +1663,7 @@ int load_state(const char *file, const char *initfile, const char *cardname,
|
||||||
snd_input_close(in);
|
snd_input_close(in);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
error("snd_config_load error: %s", snd_strerror(err));
|
error("snd_config_load error: %s", snd_strerror(err));
|
||||||
return err;
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int card, first = 1;
|
int card, first = 1;
|
||||||
|
@ -1650,7 +1675,8 @@ int load_state(const char *file, const char *initfile, const char *cardname,
|
||||||
card = snd_card_get_index(cardname);
|
card = snd_card_get_index(cardname);
|
||||||
if (card < 0) {
|
if (card < 0) {
|
||||||
error("Cannot find soundcard '%s'...", cardname);
|
error("Cannot find soundcard '%s'...", cardname);
|
||||||
return -ENODEV;
|
err = -ENODEV;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
goto single;
|
goto single;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1676,7 +1702,8 @@ single:
|
||||||
}
|
}
|
||||||
if (first)
|
if (first)
|
||||||
finalerr = 0; /* no cards, no error code */
|
finalerr = 0; /* no cards, no error code */
|
||||||
return finalerr;
|
err = finalerr;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cardname) {
|
if (!cardname) {
|
||||||
|
@ -1691,10 +1718,12 @@ single:
|
||||||
if (card < 0) {
|
if (card < 0) {
|
||||||
if (first) {
|
if (first) {
|
||||||
if (ignore_nocards) {
|
if (ignore_nocards) {
|
||||||
return 0;
|
err = 0;
|
||||||
|
goto out;
|
||||||
} else {
|
} else {
|
||||||
error("No soundcards found...");
|
error("No soundcards found...");
|
||||||
return -ENODEV;
|
err = -ENODEV;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1721,7 +1750,8 @@ single:
|
||||||
cardno = snd_card_get_index(cardname);
|
cardno = snd_card_get_index(cardname);
|
||||||
if (cardno < 0) {
|
if (cardno < 0) {
|
||||||
error("Cannot find soundcard '%s'...", cardname);
|
error("Cannot find soundcard '%s'...", cardname);
|
||||||
return -ENODEV;
|
err = -ENODEV;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
/* do a check if controls matches state file */
|
/* do a check if controls matches state file */
|
||||||
if (do_init && set_controls(cardno, config, 0)) {
|
if (do_init && set_controls(cardno, config, 0)) {
|
||||||
|
@ -1734,8 +1764,12 @@ single:
|
||||||
if ((err = set_controls(cardno, config, 1))) {
|
if ((err = set_controls(cardno, config, 1))) {
|
||||||
initfailed(cardno, "restore", err);
|
initfailed(cardno, "restore", err);
|
||||||
if (!force_restore)
|
if (!force_restore)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = finalerr;
|
||||||
|
out:
|
||||||
|
snd_config_delete(config);
|
||||||
|
snd_config_update_free_global();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return finalerr;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue