diff options
author | Jaroslav Kysela <perex@perex.cz> | 2013-04-03 11:13:41 +0200 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2013-04-03 11:16:46 +0200 |
commit | e3e85a851cef51155bb9c23f5da526a9b9817dcf (patch) | |
tree | 95180baf38ae449bb8844230bd73ab0edce3faff /alsactl/state.c | |
parent | 6de3c709b34c263e93a326e0a025c419ff3dd0f7 (diff) | |
download | alsa-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.c | 74 |
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; } |