-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add file lock to avoid instance fighting
- Loading branch information
1 parent
e90f081
commit 7cd65d5
Showing
4 changed files
with
116 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#ifndef FSAUTOPROC_FL_H | ||
#define FSAUTOPROC_FL_H | ||
|
||
struct flock_s { | ||
const char* path; /* file path */ | ||
int fd; /* opened file descriptor */ | ||
_Bool open; /* file descriptor open flag */ | ||
}; | ||
|
||
/// @brief Initializes a unlocked, ready-to-use file lock structure with the | ||
/// given target lock file path. The file descriptor is set to -1 and is not | ||
/// opened until the file is locked with `fllock()`. | ||
/// @param fp The file path to lock. | ||
/// @return The initialized file lock structure. | ||
#define flinit(fp) ((struct flock_s){.path = (fp), .fd = -1, .open = 0}) | ||
|
||
/// @brief Locks the file at the given path. If a file descriptor cannot be | ||
/// obtained, or the file cannot be locked, an error code is returned. | ||
/// @note The lock must be initialized with `flinit()` before calling `fllock`. | ||
/// @param fl The file lock structure. | ||
/// @return 0 if successful, otherwise a non-zero error code. | ||
int fllock(struct flock_s* fl); | ||
|
||
/// @brief Unlocks the file at the given path. If the file is not open, or the | ||
/// file cannot be unlocked, an error code is returned. | ||
/// @param fl The file lock structure. | ||
/// @return 0 if successful, otherwise a non-zero error code. | ||
int flunlock(struct flock_s* fl); | ||
|
||
#endif//FSAUTOPROC_FL_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#include "fl.h" | ||
|
||
#include <assert.h> | ||
#include <fcntl.h> | ||
#include <stddef.h> | ||
#include <sys/file.h> | ||
#include <unistd.h> | ||
|
||
/// @brief Opens the file at the given path and updates the file lock structure | ||
/// with the file descriptor. If the file is already open, the file descriptor | ||
/// is not updated and the function will return successfully. If the file cannot | ||
/// be opened, the error code is returned via the file lock structure. | ||
/// @param fl The file lock structure to update. | ||
/// @return 0 if successful, otherwise a non-zero error code. | ||
static int flopen(struct flock_s* fl) { | ||
assert(fl->path != NULL); | ||
if (fl->open) return 0;// file is already open | ||
fl->fd = open(fl->path, O_RDWR | O_CREAT | O_TRUNC, 0644); | ||
fl->open = fl->fd >= 0; | ||
return fl->open ? 0 : -1; | ||
} | ||
|
||
int fllock(struct flock_s* fl) { | ||
assert(fl->path != NULL); | ||
if (flopen(fl)) return -1; // get or open file descriptor | ||
if (flock(fl->fd, LOCK_EX) < 0) return -2;// lock file descriptor | ||
return 0; | ||
} | ||
|
||
int flunlock(struct flock_s* fl) { | ||
assert(fl->path != NULL); | ||
if (!fl->open) return -1; // ensure file is open | ||
if (flock(fl->fd, LOCK_UN) < 0) return -2;// release lock | ||
close(fl->fd); // close file descriptor | ||
unlink(fl->path); // remove unlocked file | ||
fl->fd = -1; | ||
fl->open = 0; | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters