Skip to content
Snippets Groups Projects
Commit 6d424f3a authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Add fmutex_close() method to atomically remove the mutex file on Win32

The 'atomic_remove' argument isn't used in non-Windows builds since we can
remove() before close() on non-Windows OSes already.
parent 4119cc5e
No related branches found
No related tags found
No related merge requests found
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
#include "filewrap.h" #include "filewrap.h"
#include "sockwrap.h" #include "sockwrap.h"
#include "nopen.h" #include "nopen.h"
#ifdef _WIN32
#include <io.h>
#endif
/****************************************************************************/ /****************************************************************************/
/* Network open function. Opens all files DENYALL, DENYWRITE, or DENYNONE */ /* Network open function. Opens all files DENYALL, DENYWRITE, or DENYNONE */
...@@ -109,7 +112,8 @@ bool ftouch(const char* fname) ...@@ -109,7 +112,8 @@ bool ftouch(const char* fname)
return true; return true;
} }
int fmutex_open(const char* fname, const char* text, long max_age, time_t* tp) // Opens a mutex file and returns its file descriptor or -1 on failure
int fmutex_open(const char* fname, const char* text, long max_age, time_t* tp, bool atomic_remove)
{ {
int file; int file;
time_t t; time_t t;
...@@ -129,8 +133,28 @@ int fmutex_open(const char* fname, const char* text, long max_age, time_t* tp) ...@@ -129,8 +133,28 @@ int fmutex_open(const char* fname, const char* text, long max_age, time_t* tp)
return -1; return -1;
} }
} }
#ifdef _WIN32
DWORD attributes = FILE_ATTRIBUTE_NORMAL;
if(atomic_remove)
attributes |= FILE_FLAG_DELETE_ON_CLOSE;
HANDLE h = CreateFileA(fname,
GENERIC_WRITE, // dwDesiredAccess
0, // dwShareMode (deny all)
NULL, // lpSecurityAttributes,
CREATE_NEW, // dwCreationDisposition
attributes, // dwFlagsAndAttributes,
NULL // hTemplateFile
);
if(h == INVALID_HANDLE_VALUE)
return -1;
if((file = _open_osfhandle((intptr_t)h, O_WRONLY)) == -1) {
CloseHandle(h);
return -1;
}
#else
if((file=sopen(fname, O_CREAT|O_WRONLY|O_EXCL, SH_DENYRW, DEFFILEMODE))<0) if((file=sopen(fname, O_CREAT|O_WRONLY|O_EXCL, SH_DENYRW, DEFFILEMODE))<0)
return file; return -1;
#endif
if(text!=NULL) { if(text!=NULL) {
len = strlen(text); len = strlen(text);
if(write(file, text, len) != len) { if(write(file, text, len) != len) {
...@@ -141,15 +165,26 @@ int fmutex_open(const char* fname, const char* text, long max_age, time_t* tp) ...@@ -141,15 +165,26 @@ int fmutex_open(const char* fname, const char* text, long max_age, time_t* tp)
return file; return file;
} }
// Opens and immediately closes a mutex file
bool fmutex(const char* fname, const char* text, long max_age, time_t* tp) bool fmutex(const char* fname, const char* text, long max_age, time_t* tp)
{ {
int file = fmutex_open(fname, text, max_age, tp); int file = fmutex_open(fname, text, max_age, tp, false);
if(file < 0) if(file < 0)
return false; return false;
close(file); close(file);
return true; return true;
} }
// Closes and atomically removes a mutex file opened with fmutex_open()
bool fmutex_close(const char* fname, int file)
{
#ifndef _WIN32 // You can't delete an open file on Windows, so we open with the DELETE_ON_CLOSE attribute instead
if(remove(fname) != 0)
return false;
#endif
return close(file) == 0;
}
bool fcompare(const char* fn1, const char* fn2) bool fcompare(const char* fn1, const char* fn2)
{ {
FILE* fp1; FILE* fp1;
......
...@@ -37,7 +37,8 @@ int nopen(const char* str, uint access); ...@@ -37,7 +37,8 @@ int nopen(const char* str, uint access);
FILE * fnopen(int* file, const char* str, uint access); FILE * fnopen(int* file, const char* str, uint access);
bool ftouch(const char* fname); bool ftouch(const char* fname);
bool fmutex(const char* fname, const char* text, long max_age, time_t*); bool fmutex(const char* fname, const char* text, long max_age, time_t*);
int fmutex_open(const char* fname, const char* text, long max_age, time_t*); int fmutex_open(const char* fname, const char* text, long max_age, time_t*, bool atomic_remove);
bool fmutex_close(const char* fname, int file);
bool fcompare(const char* fn1, const char* fn2); bool fcompare(const char* fn1, const char* fn2);
bool backup(const char* org, int backup_level, bool ren); bool backup(const char* org, int backup_level, bool ren);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment