summaryrefslogtreecommitdiff
path: root/alsactl/state.c
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2013-04-03 11:13:41 +0200
committerJaroslav Kysela <perex@perex.cz>2013-04-03 11:16:46 +0200
commite3e85a851cef51155bb9c23f5da526a9b9817dcf (patch)
tree95180baf38ae449bb8844230bd73ab0edce3faff /alsactl/state.c
parent6de3c709b34c263e93a326e0a025c419ff3dd0f7 (diff)
downloadalsa-utils-e3e85a851cef51155bb9c23f5da526a9b9817dcf.tar.gz
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>
Diffstat (limited to 'alsactl/state.c')
-rw-r--r--alsactl/state.c74
1 files changed, 54 insertions, 20 deletions
diff --git a/alsactl/state.c b/alsactl/state.c
index fec000d..1eab02e 100644
--- a/alsactl/state.c
+++ b/alsactl/state.c
@@ -1546,6 +1546,7 @@ int save_state(const char *file, const char *cardname)
snd_input_t *in;
snd_output_t *out;
int stdio;
+ char *nfile = NULL;
err = snd_config_top(&config);
if (err < 0) {
@@ -1553,13 +1554,22 @@ int save_state(const char *file, const char *cardname)
return err;
}
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) {
err = snd_config_load(config, in);
snd_input_close(in);
#if 0
if (err < 0) {
error("snd_config_load error: %s", snd_strerror(err));
- return err;
+ goto out;
}
#endif
}
@@ -1575,17 +1585,19 @@ int save_state(const char *file, const char *cardname)
if (card < 0) {
if (first) {
if (ignore_nocards) {
- return 0;
+ err = 0;
+ goto out;
} else {
error("No soundcards found...");
- return -ENODEV;
+ err = -ENODEV;
+ goto out;
}
}
break;
}
first = 0;
if ((err = get_controls(card, config)))
- return err;
+ goto out;
}
} else {
int cardno;
@@ -1593,26 +1605,39 @@ int save_state(const char *file, const char *cardname)
cardno = snd_card_get_index(cardname);
if (cardno < 0) {
error("Cannot find soundcard '%s'...", cardname);
- return cardno;
+ err = cardno;
+ goto out;
}
if ((err = get_controls(cardno, config))) {
- return err;
+ goto out;
}
}
- if (stdio)
+ if (stdio) {
err = snd_output_stdio_attach(&out, stdout, 0);
- else
- err = snd_output_stdio_open(&out, file, "w");
+ } else {
+ err = snd_output_stdio_open(&out, nfile, "w");
+ }
if (err < 0) {
error("Cannot open %s for writing: %s", file, snd_strerror(err));
- return -errno;
+ err = -errno;
+ goto out;
}
err = snd_config_save(config, out);
snd_output_close(out);
- if (err < 0)
+ if (err < 0) {
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,
@@ -1638,7 +1663,7 @@ int load_state(const char *file, const char *initfile, const char *cardname,
snd_input_close(in);
if (err < 0) {
error("snd_config_load error: %s", snd_strerror(err));
- return err;
+ goto out;
}
} else {
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);
if (card < 0) {
error("Cannot find soundcard '%s'...", cardname);
- return -ENODEV;
+ err = -ENODEV;
+ goto out;
}
goto single;
} else {
@@ -1676,7 +1702,8 @@ single:
}
if (first)
finalerr = 0; /* no cards, no error code */
- return finalerr;
+ err = finalerr;
+ goto out;
}
if (!cardname) {
@@ -1691,10 +1718,12 @@ single:
if (card < 0) {
if (first) {
if (ignore_nocards) {
- return 0;
+ err = 0;
+ goto out;
} else {
error("No soundcards found...");
- return -ENODEV;
+ err = -ENODEV;
+ goto out;
}
}
break;
@@ -1721,7 +1750,8 @@ single:
cardno = snd_card_get_index(cardname);
if (cardno < 0) {
error("Cannot find soundcard '%s'...", cardname);
- return -ENODEV;
+ err = -ENODEV;
+ goto out;
}
/* do a check if controls matches state file */
if (do_init && set_controls(cardno, config, 0)) {
@@ -1734,8 +1764,12 @@ single:
if ((err = set_controls(cardno, config, 1))) {
initfailed(cardno, "restore", err);
if (!force_restore)
- return err;
+ goto out;
}
}
- return finalerr;
+ err = finalerr;
+out:
+ snd_config_delete(config);
+ snd_config_update_free_global();
+ return err;
}