summaryrefslogtreecommitdiff
path: root/conf.c
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2012-05-22 22:17:11 +0200
committerGravatar waker <wakeroid@gmail.com>2012-05-22 22:17:11 +0200
commit8e34cdbf453a70e720913c6346ece19598c3ba54 (patch)
tree3cce4257f9734d389b896323e223112a4c2ae3ef /conf.c
parent7753660402c8d3442269af7c10ab49bc3eaafa88 (diff)
atomic config writing
Diffstat (limited to 'conf.c')
-rw-r--r--conf.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/conf.c b/conf.c
index d4e0ee28..eff15de5 100644
--- a/conf.c
+++ b/conf.c
@@ -15,11 +15,19 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
+#include <errno.h>
+#include <unistd.h>
+#if HAVE_SYS_SYSLIMITS_H
+#include <sys/syslimits.h>
+#endif
#include "conf.h"
#include "threading.h"
@@ -107,19 +115,33 @@ conf_load (void) {
int
conf_save (void) {
extern char dbconfdir[1024]; // $HOME/.config/deadbeef
- char str[1024];
- snprintf (str, 1024, "%s/config", dbconfdir);
- FILE *fp = fopen (str, "w+t");
+
+ char tempfile[PATH_MAX];
+ snprintf (tempfile, sizeof (tempfile), "%s/config.tmp", dbconfdir);
+
+ char str[PATH_MAX];
+ snprintf (str, sizeof (str), "%s/config", dbconfdir);
+
+ FILE *fp = fopen (tempfile, "w+t");
if (!fp) {
fprintf (stderr, "failed to open config file for writing\n");
return -1;
}
conf_lock ();
for (DB_conf_item_t *it = conf_items; it; it = it->next) {
- fprintf (fp, "%s %s\n", it->key, it->value);
+ if (fprintf (fp, "%s %s\n", it->key, it->value) < 0) {
+ fprintf (stderr, "failed to write to file %s (%s)\n", tempfile, strerror (errno));
+ fclose (fp);
+ conf_unlock ();
+ return -1;
+ }
}
fclose (fp);
conf_unlock ();
+ int err = rename (tempfile, str);
+ if (err != 0) {
+ fprintf (stderr, "config rename %s -> %s failed: %s\n", tempfile, str, strerror (errno));
+ }
return 0;
}