]> git.alsa-project.org Git - alsa-utils.git/commitdiff
alsactl: safe state store and memory allocation cleanups
authorJaroslav Kysela <perex@perex.cz>
Wed, 3 Apr 2013 09:13:41 +0000 (11:13 +0200)
committerJaroslav Kysela <perex@perex.cz>
Wed, 3 Apr 2013 09:16:46 +0000 (11:16 +0200)
- 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>
alsactl/alsactl.c
alsactl/state.c

index 17927471550a30a3b679516c3bc4c05372b1770b..5e15f708b102d628a545119f15d1e44bcdd4e93f 100644 (file)
@@ -176,6 +176,7 @@ int main(int argc, char *argv[])
 
        if (!strcmp(argv[optind], "init")) {
                res = init(initfile, cardname);
+               snd_config_update_free_global();
        } else if (!strcmp(argv[optind], "store")) {
                res = save_state(cfgfile, cardname);
        } else if (!strcmp(argv[optind], "restore")) {
index fec000dd2f032b621f6be32e326734f815d90a9b..1eab02e2c6fe836e38874b85a01503ab32c09a86 100644 (file)
@@ -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;
 }