aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Storage.cpp73
1 files changed, 63 insertions, 10 deletions
diff --git a/src/Storage.cpp b/src/Storage.cpp
index 8ef8e5f..50d1ffd 100644
--- a/src/Storage.cpp
+++ b/src/Storage.cpp
@@ -16,11 +16,57 @@
#include <sys/types.h>
#include <fcntl.h>
+#define EINTR_RETRY(ret, expr) \
+ do { \
+ errno = 0; \
+ while(true) { \
+ ret = (expr); \
+ if(ret != -1 || errno != EINTR) \
+ break; \
+ } \
+ } while(0)
+
static int makedir(const char *path) {
return mkdir(path, S_IRWXU);
}
namespace QuickMedia {
+ static FILE* fopen_eintr(const char *filename, const char *modes) {
+ errno = 0;
+ while(true) {
+ FILE *f = fopen(filename, modes);
+ if(f || errno != EINTR)
+ return f;
+ }
+ }
+
+ static size_t fwrite_eintr(const char *data, size_t size, FILE *f) {
+ errno = 0;
+ while(true) {
+ const size_t r = fwrite(data, 1, size, f);
+ if(r == size || errno != EINTR)
+ return r;
+ }
+ }
+
+ static size_t fread_eintr(char *data, size_t size, FILE *f) {
+ errno = 0;
+ while(true) {
+ const size_t r = fread(data, 1, size, f);
+ if(r == size || errno != EINTR)
+ return r;
+ }
+ }
+
+ static size_t fseek_eintr(FILE *f, long offset, int whence) {
+ errno = 0;
+ while(true) {
+ const int r = fseek(f, offset, whence);
+ if(r == 0 || errno != EINTR)
+ return r;
+ }
+ }
+
Path get_home_dir()
{
const char *homeDir = getenv("HOME");
@@ -81,37 +127,42 @@ namespace QuickMedia {
FileType get_file_type(const Path &path) {
struct stat file_stat;
- if(stat(path.data.c_str(), &file_stat) == 0)
+ int ret;
+ EINTR_RETRY(ret, stat(path.data.c_str(), &file_stat));
+ if(ret == 0)
return S_ISREG(file_stat.st_mode) ? FileType::REGULAR : FileType::DIRECTORY;
return FileType::FILE_NOT_FOUND;
}
int file_get_content(const Path &path, std::string &result) {
- FILE *file = fopen(path.data.c_str(), "rb");
+ FILE *file = fopen_eintr(path.data.c_str(), "rb");
if(!file)
return -errno;
- fseek(file, 0, SEEK_END);
+ fseek_eintr(file, 0, SEEK_END);
long file_size = ftell(file);
if(file_size == -1) {
fprintf(stderr, "Error: attempted to read directory %s as a file\n", path.data.c_str());
fclose(file);
return -1;
}
- fseek(file, 0, SEEK_SET);
+ fseek_eintr(file, 0, SEEK_SET);
result.resize(file_size);
- if(fread(&result[0], 1, file_size, file) != (size_t)file_size) {
+ if(fread_eintr(&result[0], file_size, file) != (size_t)file_size) {
fclose(file);
return -1;
}
- return fclose(file);
+ fclose(file);
+ return 0;
}
int file_get_size(const Path &path, size_t *size) {
struct stat file_stat;
- if(stat(path.data.c_str(), &file_stat) == 0 && S_ISREG(file_stat.st_mode)) {
+ int ret;
+ EINTR_RETRY(ret, stat(path.data.c_str(), &file_stat));
+ if(ret == 0 && S_ISREG(file_stat.st_mode)) {
*size = file_stat.st_size;
return 0;
}
@@ -121,7 +172,9 @@ namespace QuickMedia {
bool file_get_last_modified_time_seconds(const char *path, time_t *result) {
struct stat file_stat;
- if(stat(path, &file_stat) == 0) {
+ int ret;
+ EINTR_RETRY(ret, stat(path, &file_stat));
+ if(ret == 0) {
*result = file_stat.st_mtim.tv_sec;
return true;
}
@@ -129,13 +182,13 @@ namespace QuickMedia {
}
static int file_overwrite(const Path &path, const char *str, size_t size) {
- FILE *file = fopen(path.data.c_str(), "wb");
+ FILE *file = fopen_eintr(path.data.c_str(), "wb");
if(!file) {
perror(path.data.c_str());
return -1;
}
- if(fwrite(str, 1, size, file) != size) {
+ if(fwrite_eintr(str, size, file) != size) {
fclose(file);
return -1;
}