X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fwrite.c;h=773de0b7b6553e61ead5ef8b726e00f218b54f6a;hp=b143f16d7dc4de001a0e3e2b2cd01b248ffcd593;hb=7c83ef53090441de11cc78d8d26dc337cd7ac475;hpb=d5c2c580d35447207e1e8c0d62c9e55b77ba20d1 diff --git a/src/write.c b/src/write.c index b143f16d..773de0b7 100644 --- a/src/write.c +++ b/src/write.c @@ -55,6 +55,11 @@ #include #endif +#if defined(HAVE_SYS_FILE_H) && defined(HAVE_FLOCK) +#include +#endif + + static int do_fflush(FILE *fp) { int ret = fflush(fp); @@ -1487,6 +1492,49 @@ out: return ret; } +static int open_wim_writable(WIMStruct *w, const char *path, + bool trunc, bool readable) +{ + const char *mode; + int ret = 0; + if (trunc) + if (readable) + mode = "w+b"; + else + mode = "wb"; + else + mode = "r+b"; + + DEBUG("Opening `%s' read-write", path); + wimlib_assert(w->out_fp == NULL); + wimlib_assert(path != NULL); + w->out_fp = fopen(path, mode); + if (!w->out_fp) { + ERROR_WITH_ERRNO("Failed to open `%s' for writing", path); + return WIMLIB_ERR_OPEN; + } +#if defined(HAVE_SYS_FILE_H) && defined(HAVE_FLOCK) + if (!trunc) { + ret = flock(fileno(w->out_fp), LOCK_EX | LOCK_NB); + if (ret != 0) { + if (errno == EWOULDBLOCK) { + ERROR("`%s' is already being modified " + "by another process", path); + ret = WIMLIB_ERR_ALREADY_LOCKED; + fclose(w->out_fp); + w->out_fp = NULL; + } else { + WARNING("Failed to lock `%s': %s", + path, strerror(errno)); + ret = 0; + } + } + } +#endif + return ret; +} + + static void close_wim_writable(WIMStruct *w) { if (w->out_fp) {