aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-07-15 16:57:37 +0200
committerMax Kellermann <max@duempel.org>2009-07-15 16:57:37 +0200
commitf7cc5b2efddece7cdc4fc5b7fc5324d33b7dfa8f (patch)
treec3b528d0972f857c1d80f0d26eff3491b6929777
parentdf7d7732c61deec0102950cb3d79b9bd114e73a9 (diff)
downloadmpd-f7cc5b2efddece7cdc4fc5b7fc5324d33b7dfa8f.tar.gz
mpd-f7cc5b2efddece7cdc4fc5b7fc5324d33b7dfa8f.tar.xz
mpd-f7cc5b2efddece7cdc4fc5b7fc5324d33b7dfa8f.zip
state_file: don't rewind the stream while reading the state file
Parse the state file line by line, let each subsystem probe a line. Only the playlist_state code gets the FILE pointer to read the following lines.
Diffstat (limited to '')
-rw-r--r--src/output_state.c47
-rw-r--r--src/output_state.h5
-rw-r--r--src/playlist_state.c29
-rw-r--r--src/playlist_state.h5
-rw-r--r--src/state_file.c16
-rw-r--r--src/volume.c26
-rw-r--r--src/volume.h3
7 files changed, 69 insertions, 62 deletions
diff --git a/src/output_state.c b/src/output_state.c
index c7e6c8579..5efae3626 100644
--- a/src/output_state.c
+++ b/src/output_state.c
@@ -49,35 +49,34 @@ saveAudioDevicesState(FILE *fp)
}
}
-void
-readAudioDevicesState(FILE *fp)
+bool
+readAudioDevicesState(const char *line)
{
- char buffer[1024];
-
- while (fgets(buffer, sizeof(buffer), fp)) {
- char *c, *name;
- struct audio_output *ao;
+ long value;
+ char *endptr;
+ const char *name;
+ struct audio_output *ao;
- g_strchomp(buffer);
+ if (!g_str_has_prefix(line, AUDIO_DEVICE_STATE))
+ return false;
- if (!g_str_has_prefix(buffer, AUDIO_DEVICE_STATE))
- continue;
+ line += sizeof(AUDIO_DEVICE_STATE) - 1;
- c = strchr(buffer, ':');
- if (!c || !(++c))
- goto errline;
+ value = strtol(line, &endptr, 10);
+ if (*endptr != ':' || (value != 0 && value != 1))
+ return false;
- name = strchr(c, ':');
- if (!name || !(++name))
- goto errline;
+ if (value != 0)
+ /* state is "enabled": no-op */
+ return true;
- ao = audio_output_find(name);
- if (ao != NULL && atoi(c) == 0)
- ao->enabled = false;
-
- continue;
-errline:
- /* nonfatal */
- g_warning("invalid line in state_file: %s\n", buffer);
+ name = endptr + 1;
+ ao = audio_output_find(name);
+ if (ao == NULL) {
+ g_debug("Ignoring device state for '%s'", name);
+ return true;
}
+
+ ao->enabled = false;
+ return true;
}
diff --git a/src/output_state.h b/src/output_state.h
index 8592574ab..b171fed18 100644
--- a/src/output_state.h
+++ b/src/output_state.h
@@ -25,10 +25,11 @@
#ifndef OUTPUT_STATE_H
#define OUTPUT_STATE_H
+#include <stdbool.h>
#include <stdio.h>
-void
-readAudioDevicesState(FILE *fp);
+bool
+readAudioDevicesState(const char *line);
void
saveAudioDevicesState(FILE *fp);
diff --git a/src/playlist_state.c b/src/playlist_state.c
index c9d3303ac..cbf77813e 100644
--- a/src/playlist_state.c
+++ b/src/playlist_state.c
@@ -115,8 +115,8 @@ playlist_state_load(FILE *fp, struct playlist *playlist, char *buffer)
queue_increment_version(&playlist->queue);
}
-void
-playlist_state_restore(FILE *fp, struct playlist *playlist)
+bool
+playlist_state_restore(const char *line, FILE *fp, struct playlist *playlist)
{
int current = -1;
int seek_time = 0;
@@ -124,21 +124,20 @@ playlist_state_restore(FILE *fp, struct playlist *playlist)
char buffer[PLAYLIST_BUFFER_SIZE];
bool random_mode = false;
+ if (!g_str_has_prefix(line, PLAYLIST_STATE_FILE_STATE))
+ return false;
+
+ line += sizeof(PLAYLIST_STATE_FILE_STATE) - 1;
+
+ if (strcmp(line, PLAYLIST_STATE_FILE_STATE_PLAY) == 0)
+ state = PLAYER_STATE_PLAY;
+ else if (strcmp(line, PLAYLIST_STATE_FILE_STATE_PAUSE) == 0)
+ state = PLAYER_STATE_PAUSE;
+
while (fgets(buffer, sizeof(buffer), fp)) {
g_strchomp(buffer);
- if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_STATE)) {
- if (strcmp(&(buffer[strlen(PLAYLIST_STATE_FILE_STATE)]),
- PLAYLIST_STATE_FILE_STATE_PLAY) == 0) {
- state = PLAYER_STATE_PLAY;
- } else
- if (strcmp
- (&(buffer[strlen(PLAYLIST_STATE_FILE_STATE)]),
- PLAYLIST_STATE_FILE_STATE_PAUSE)
- == 0) {
- state = PLAYER_STATE_PAUSE;
- }
- } else if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_TIME)) {
+ if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_TIME)) {
seek_time =
atoi(&(buffer[strlen(PLAYLIST_STATE_FILE_TIME)]));
} else if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_REPEAT)) {
@@ -198,4 +197,6 @@ playlist_state_restore(FILE *fp, struct playlist *playlist)
if (state == PLAYER_STATE_PAUSE)
playerPause();
}
+
+ return true;
}
diff --git a/src/playlist_state.h b/src/playlist_state.h
index 989430264..7ed7e8c8e 100644
--- a/src/playlist_state.h
+++ b/src/playlist_state.h
@@ -25,6 +25,7 @@
#ifndef PLAYLIST_STATE_H
#define PLAYLIST_STATE_H
+#include <stdbool.h>
#include <stdio.h>
struct playlist;
@@ -32,7 +33,7 @@ struct playlist;
void
playlist_state_save(FILE *fp, const struct playlist *playlist);
-void
-playlist_state_restore(FILE *fp, struct playlist *playlist);
+bool
+playlist_state_restore(const char *line, FILE *fp, struct playlist *playlist);
#endif
diff --git a/src/state_file.c b/src/state_file.c
index 3791c057d..18548d03c 100644
--- a/src/state_file.c
+++ b/src/state_file.c
@@ -63,6 +63,8 @@ static void
state_file_read(void)
{
FILE *fp;
+ char line[1024];
+ bool success;
assert(state_file_path != NULL);
@@ -75,11 +77,15 @@ state_file_read(void)
return;
}
- read_sw_volume_state(fp);
- rewind(fp);
- readAudioDevicesState(fp);
- rewind(fp);
- playlist_state_restore(fp, &g_playlist);
+ while (fgets(line, sizeof(line), fp) != NULL) {
+ g_strchomp(line);
+
+ success = read_sw_volume_state(line) ||
+ readAudioDevicesState(line) ||
+ playlist_state_restore(line, fp, &g_playlist);
+ if (!success)
+ g_warning("Unrecognized line in state file: %s", line);
+ }
while(fclose(fp) && errno == EINTR) /* nothing */;
}
diff --git a/src/volume.c b/src/volume.c
index 3e6079cd6..5f4a66837 100644
--- a/src/volume.c
+++ b/src/volume.c
@@ -100,24 +100,22 @@ bool volume_level_change(unsigned volume)
return hardware_volume_change(volume);
}
-void read_sw_volume_state(FILE *fp)
+bool
+read_sw_volume_state(const char *line)
{
- char buf[sizeof(SW_VOLUME_STATE) + sizeof("100") - 1];
char *end = NULL;
long int sv;
- while (fgets(buf, sizeof(buf), fp)) {
- if (!g_str_has_prefix(buf, SW_VOLUME_STATE))
- continue;
-
- g_strchomp(buf);
- sv = strtol(buf + strlen(SW_VOLUME_STATE), &end, 10);
- if (G_LIKELY(!*end) && sv >= 0 && sv <= 100)
- software_volume_change(sv);
- else
- g_warning("Can't parse software volume: %s\n", buf);
- return;
- }
+ if (!g_str_has_prefix(line, SW_VOLUME_STATE))
+ return false;
+
+ line += sizeof(SW_VOLUME_STATE) - 1;
+ sv = strtol(line, &end, 10);
+ if (*end == 0 && sv >= 0 && sv <= 100)
+ software_volume_change(sv);
+ else
+ g_warning("Can't parse software volume: %s\n", line);
+ return true;
}
void save_sw_volume_state(FILE *fp)
diff --git a/src/volume.h b/src/volume.h
index 352d36168..0db231ef6 100644
--- a/src/volume.h
+++ b/src/volume.h
@@ -31,7 +31,8 @@ int volume_level_get(void);
bool volume_level_change(unsigned volume);
-void read_sw_volume_state(FILE *fp);
+bool
+read_sw_volume_state(const char *line);
void save_sw_volume_state(FILE *fp);