From 71ac281579c8b8b384cfc09d8627b549b1854fcd Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 18 Sep 2008 04:29:53 -0700 Subject: Move away from fprintf() when writing DB/state_file I have serious trust issues when using stdio to write to the FS. So it's best to clean this code out so I can start figuring out what's wrong with Rasi's box not updating... None of these writes take place in a performance-critical setting anyways... --- src/audio.c | 4 ++-- src/audio.h | 2 +- src/directory.c | 37 +++++++++++++++++++++---------------- src/playlist.c | 34 +++++++++++++++++----------------- src/playlist.h | 2 +- src/song.c | 13 ++++++------- src/song.h | 2 +- src/state_file.c | 14 +++++++------- src/volume.c | 5 +++-- src/volume.h | 2 +- 10 files changed, 60 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index d4447bc7e..5eacf7422 100644 --- a/src/audio.c +++ b/src/audio.c @@ -461,13 +461,13 @@ void printAudioDevices(int fd) } } -void saveAudioDevicesState(FILE *fp) +void saveAudioDevicesState(int fd) { unsigned int i; assert(audioOutputArraySize != 0); for (i = 0; i < audioOutputArraySize; i++) { - fprintf(fp, AUDIO_DEVICE_STATE "%d:%s\n", + fdprintf(fd, AUDIO_DEVICE_STATE "%d:%s\n", audioDeviceStates[i] & 0x01, audioOutputArray[i].name); } diff --git a/src/audio.h b/src/audio.h index 7ff0d5d4a..a926b39e4 100644 --- a/src/audio.h +++ b/src/audio.h @@ -67,7 +67,7 @@ void printAudioDevices(int fd); void readAudioDevicesState(FILE *fp); -void saveAudioDevicesState(FILE *fp); +void saveAudioDevicesState(int fd); void loadAudioDrivers(void); #endif diff --git a/src/directory.c b/src/directory.c index c8c3c9372..06a39d7bf 100644 --- a/src/directory.c +++ b/src/directory.c @@ -845,14 +845,14 @@ int printDirectoryInfo(int fd, const char *name) return 0; } -static void writeDirectoryInfo(FILE * fp, Directory * directory) +static void writeDirectoryInfo(int fd, Directory * directory) { ListNode *node = (directory->subDirectories)->firstNode; Directory *subDirectory; int retv; if (directory->path) { - retv = fprintf(fp, "%s%s\n", DIRECTORY_BEGIN, + retv = fdprintf(fd, DIRECTORY_BEGIN "%s\n", getDirectoryPath(directory)); if (retv < 0) { ERROR("Failed to write data to database file: %s\n",strerror(errno)); @@ -862,19 +862,19 @@ static void writeDirectoryInfo(FILE * fp, Directory * directory) while (node != NULL) { subDirectory = (Directory *) node->data; - retv = fprintf(fp, "%s%s\n", DIRECTORY_DIR, node->key); + retv = fdprintf(fd, DIRECTORY_DIR "%s\n", node->key); if (retv < 0) { ERROR("Failed to write data to database file: %s\n",strerror(errno)); return; } - writeDirectoryInfo(fp, subDirectory); + writeDirectoryInfo(fd, subDirectory); node = node->nextNode; } - writeSongInfoFromList(fp, directory->songs); + writeSongInfoFromList(fd, directory->songs); if (directory->path) { - retv = fprintf(fp, "%s%s\n", DIRECTORY_END, + retv = fdprintf(fd, DIRECTORY_END "%s\n", getDirectoryPath(directory)); if (retv < 0) { ERROR("Failed to write data to database file: %s\n",strerror(errno)); @@ -1029,7 +1029,7 @@ int checkDirectoryDB(void) int writeDirectoryDB(void) { - FILE *fp; + int fd; char *dbFile = getDbFile(); struct stat st; @@ -1042,22 +1042,27 @@ int writeDirectoryDB(void) DEBUG("writing DB\n"); - while (!(fp = fopen(dbFile, "w")) && errno == EINTR); - if (!fp) { + while (((fd = open(dbFile, O_WRONLY|O_TRUNC|O_CREAT)) < 0) && + errno == EINTR); + if (fd < 0) { ERROR("unable to write to db file \"%s\": %s\n", dbFile, strerror(errno)); return -1; } - /* block signals when writing the db so we don't get a corrupted db */ - fprintf(fp, "%s\n", DIRECTORY_INFO_BEGIN); - fprintf(fp, "%s%s\n", DIRECTORY_MPD_VERSION, VERSION); - fprintf(fp, "%s%s\n", DIRECTORY_FS_CHARSET, getFsCharset()); - fprintf(fp, "%s\n", DIRECTORY_INFO_END); + /* + * TODO: block signals when writing the db so we don't get a corrupted + * db (or unexpected failures). fdprintf() needs better error handling + */ + fdprintf(fd, + DIRECTORY_INFO_BEGIN "\n" + DIRECTORY_MPD_VERSION VERSION "\n" + DIRECTORY_FS_CHARSET "%s\n" + DIRECTORY_INFO_END "\n", getFsCharset()); - writeDirectoryInfo(fp, mp3rootDirectory); + writeDirectoryInfo(fd, mp3rootDirectory); - while (fclose(fp) && errno == EINTR); + xclose(fd); if (stat(dbFile, &st) == 0) directory_dbModTime = st.st_mtime; diff --git a/src/playlist.c b/src/playlist.c index ca79393b0..e62e71583 100644 --- a/src/playlist.c +++ b/src/playlist.c @@ -254,35 +254,35 @@ void showPlaylist(int fd) } } -void savePlaylistState(FILE *fp) +void savePlaylistState(int fd) { - fprintf(fp, "%s", PLAYLIST_STATE_FILE_STATE); + fdprintf(fd, PLAYLIST_STATE_FILE_STATE); switch (playlist_state) { case PLAYLIST_STATE_PLAY: switch (ob_get_state()) { case OB_STATE_PAUSE: - fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_STATE_PAUSE); + fdprintf(fd, PLAYLIST_STATE_FILE_STATE_PAUSE "\n"); break; default: - fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_STATE_PLAY); + fdprintf(fd, PLAYLIST_STATE_FILE_STATE_PLAY "\n"); } - fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_CURRENT, - playlist.order[playlist.current]); - fprintf(fp, "%s%lu\n", PLAYLIST_STATE_FILE_TIME, - ob_get_elapsed_time()); + fdprintf(fd, PLAYLIST_STATE_FILE_CURRENT "%i\n" + PLAYLIST_STATE_FILE_TIME "%lu\n", + playlist.order[playlist.current], + ob_get_elapsed_time()); break; default: - fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_STATE_STOP); + fdprintf(fd, PLAYLIST_STATE_FILE_STATE_STOP "\n"); break; } - fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_RANDOM, playlist.random); - fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_REPEAT, playlist.repeat); - fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_CROSSFADE, - (int)(ob_get_xfade())); - fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_PLAYLIST_BEGIN); - fflush(fp); - showPlaylist(fileno(fp)); - fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_PLAYLIST_END); + fdprintf(fd, + PLAYLIST_STATE_FILE_RANDOM "%i\n" + PLAYLIST_STATE_FILE_REPEAT "%i\n" + PLAYLIST_STATE_FILE_CROSSFADE "%i\n" + PLAYLIST_STATE_FILE_PLAYLIST_BEGIN "\n", + playlist.random, playlist.repeat, (int)(ob_get_xfade())); + showPlaylist(fd); + fdprintf(fd, PLAYLIST_STATE_FILE_PLAYLIST_END "\n"); } static void loadPlaylistFromStateFile(FILE *fp, char *buffer, diff --git a/src/playlist.h b/src/playlist.h index 2d8d43ec6..560a4d1e2 100644 --- a/src/playlist.h +++ b/src/playlist.h @@ -46,7 +46,7 @@ void finishPlaylist(void); void readPlaylistState(FILE *); -void savePlaylistState(FILE *); +void savePlaylistState(int fd); void clearPlaylist(void); diff --git a/src/song.c b/src/song.c index 9b8b7d4db..ab900a6b4 100644 --- a/src/song.c +++ b/src/song.c @@ -164,22 +164,21 @@ int printSongInfoFromList(int fd, SongList * list) return 0; } -void writeSongInfoFromList(FILE * fp, SongList * list) +void writeSongInfoFromList(int fd, SongList * list) { ListNode *tempNode = list->firstNode; - fprintf(fp, "%s\n", SONG_BEGIN); + fdprintf(fd, SONG_BEGIN "\n"); while (tempNode != NULL) { - fprintf(fp, "%s%s\n", SONG_KEY, tempNode->key); - fflush(fp); - printSongInfo(fileno(fp), (Song *) tempNode->data); - fprintf(fp, "%s%li\n", SONG_MTIME, + fdprintf(fd, SONG_KEY "%s\n", tempNode->key); + printSongInfo(fd, (Song *) tempNode->data); + fdprintf(fd, SONG_MTIME "%li\n", (long)((Song *) tempNode->data)->mtime); tempNode = tempNode->nextNode; } - fprintf(fp, "%s\n", SONG_END); + fdprintf(fd, SONG_END "\n"); } static void insertSongIntoList(SongList * list, ListNode ** nextSongNode, diff --git a/src/song.h b/src/song.h index b7dc6c90b..d27596abd 100644 --- a/src/song.h +++ b/src/song.h @@ -60,7 +60,7 @@ int printSongInfo(int fd, Song * song); int printSongInfoFromList(int fd, SongList * list); -void writeSongInfoFromList(FILE * fp, SongList * list); +void writeSongInfoFromList(int fd, SongList * list); void readSongInfoIntoList(FILE * fp, SongList * list, struct _Directory *parent); diff --git a/src/state_file.c b/src/state_file.c index 3bc4f8f0c..b7f28e538 100644 --- a/src/state_file.c +++ b/src/state_file.c @@ -29,7 +29,7 @@ static struct _sf_cb { void (*reader)(FILE *); - void (*writer)(FILE *); + void (*writer)(int); } sf_callbacks [] = { { read_sw_volume_state, save_sw_volume_state }, { readAudioDevicesState, saveAudioDevicesState }, @@ -51,22 +51,22 @@ static void get_state_file_path(void) void write_state_file(void) { unsigned int i; - FILE *fp; + int fd; if (!sfpath) return; - while (!(fp = fopen(sfpath, "w")) && errno == EINTR); - - if (mpd_unlikely(!fp)) { + while (((fd = open(sfpath, O_WRONLY|O_TRUNC|O_CREAT)) < 0) && + errno == EINTR); + if (fd < 0) { ERROR("problems opening state file \"%s\" for writing: %s\n", sfpath, strerror(errno)); return; } for (i = 0; i < ARRAY_SIZE(sf_callbacks); i++) - sf_callbacks[i].writer(fp); + sf_callbacks[i].writer(fd); - while(fclose(fp) && errno == EINTR) /* nothing */; + xclose(fd); } void read_state_file(void) diff --git a/src/volume.c b/src/volume.c index 428c3b8a1..6d8411165 100644 --- a/src/volume.c +++ b/src/volume.c @@ -23,6 +23,7 @@ #include "utils.h" #include "os_compat.h" #include "outputBuffer.h" +#include "myfprintf.h" #include "../config.h" @@ -532,9 +533,9 @@ void read_sw_volume_state(FILE *fp) #undef bufsize } -void save_sw_volume_state(FILE *fp) +void save_sw_volume_state(int fd) { if (volume_mixerType == VOLUME_MIXER_TYPE_SOFTWARE) - fprintf(fp, SW_VOLUME_STATE "%d\n", volume_softwareSet); + fdprintf(fd, SW_VOLUME_STATE "%d\n", volume_softwareSet); } diff --git a/src/volume.h b/src/volume.h index a92cdd8bb..b7289b34f 100644 --- a/src/volume.h +++ b/src/volume.h @@ -37,6 +37,6 @@ int changeVolumeLevel(int change, int rel); void read_sw_volume_state(FILE *fp); -void save_sw_volume_state(FILE *fp); +void save_sw_volume_state(int fd); #endif -- cgit v1.2.3