diff mbox

alsactl: Try to create state file directory

Message ID 1433542402-665-1-git-send-email-nicholson@endlessm.com (mailing list archive)
State Rejected
Delegated to: Takashi Iwai
Headers show

Commit Message

Dan Nicholson June 5, 2015, 10:13 p.m. UTC
Try to create the directory for the state file when saving so we don't
depend on it being created ahead of time. This only checks for failures
on existing directories and doesn't try to create the leading
directories or workaround any other errors. This should catch the common
case where /var/lib exists, but /var/lib/alsa doesn't.

Signed-off-by: Dan Nicholson <nicholson@endlessm.com>
---
v2: I forgot to set err if mkdir failed.

 alsactl/state.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
diff mbox

Patch

diff --git a/alsactl/state.c b/alsactl/state.c
index 3908ec4..faa1579 100644
--- a/alsactl/state.c
+++ b/alsactl/state.c
@@ -27,6 +27,9 @@ 
 #include <stdio.h>
 #include <assert.h>
 #include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 #include <alsa/asoundlib.h>
 #include "alsactl.h"
 
@@ -1544,6 +1547,7 @@  int save_state(const char *file, const char *cardname)
 	snd_output_t *out;
 	int stdio;
 	char *nfile = NULL;
+	char *filedir = NULL;
 	int lock_fd = -EINVAL;
 
 	err = snd_config_top(&config);
@@ -1553,6 +1557,9 @@  int save_state(const char *file, const char *cardname)
 	}
 	stdio = !strcmp(file, "-");
 	if (!stdio) {
+		char *tmp;
+		mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
+
 		nfile = malloc(strlen(file) + 5);
 		if (nfile == NULL) {
 			error("No enough memory...");
@@ -1561,6 +1568,22 @@  int save_state(const char *file, const char *cardname)
 		}
 		strcpy(nfile, file);
 		strcat(nfile, ".new");
+		filedir = strdup(file);
+		if (filedir == NULL) {
+			error("Not enough memory...");
+			err = -ENOMEM;
+			goto out;
+		}
+		tmp = strrchr(filedir, '/');
+		if (tmp && tmp != filedir) {
+			*tmp = '\0';
+			if (mkdir(filedir, mode) != 0 && errno != EEXIST) {
+				error("Could not create directory %s: %s",
+				      filedir, strerror(errno));
+				err = -errno;
+				goto out;
+			}
+		}
 		lock_fd = state_lock(file, 10);
 		if (lock_fd < 0) {
 			err = lock_fd;
@@ -1640,6 +1663,7 @@  out:
 	if (!stdio && lock_fd >= 0)
 		state_unlock(lock_fd, file);
 	free(nfile);
+	free(filedir);
 	snd_config_delete(config);
 	snd_config_update_free_global();
 	return err;