Use File Locking

This commit is contained in:
TheBrokenRail 2022-09-25 19:35:51 -04:00
parent bedd5ea53a
commit 703ced337b
4 changed files with 133 additions and 72 deletions

View File

@ -193,10 +193,24 @@ void run_simple_command(const char *const command[], const char *error) {
ERR("%s", error);
}
}
#define HOME_SUBDIRECTORY_FOR_SDK HOME_SUBDIRECTORY_FOR_GAME_DATA "/sdk"
static void copy_sdk(char *binary_directory) {
// Ensure SDK Directory
{
char *sdk_path = NULL;
safe_asprintf(&sdk_path, "%s" HOME_SUBDIRECTORY_FOR_SDK, getenv("HOME"));
const char *const command[] = {"mkdir", "-p", sdk_path, NULL};
run_simple_command(command, "Unable To Create SDK Directory");
}
// Lock File
char *lock_file_path = NULL;
safe_asprintf(&lock_file_path, "%s" HOME_SUBDIRECTORY_FOR_SDK "/.lock", getenv("HOME"));
int lock_file_fd = lock_file(lock_file_path);
// Output Directory
char *output = NULL;
safe_asprintf(&output, "%s" HOME_SUBDIRECTORY_FOR_GAME_DATA "/sdk/" MCPI_SDK_DIR, getenv("HOME"));
safe_asprintf(&output, "%s" HOME_SUBDIRECTORY_FOR_SDK "/" MCPI_SDK_DIR, getenv("HOME"));
// Source Directory
char *source = NULL;
safe_asprintf(&source, "%s/sdk/.", binary_directory);
@ -222,6 +236,10 @@ static void copy_sdk(char *binary_directory) {
// Free
free(output);
free(source);
// Unlock File
unlock_file(lock_file_path, lock_file_fd);
free(lock_file_path);
}
// Bootstrap

View File

@ -30,30 +30,34 @@ launcher_cache load_cache() {
// Log
DEBUG("Loading Launcher Cache...");
// Lock File
int lock_fd = lock_file(get_cache_path().c_str());
// Return Value
launcher_cache ret = empty_cache;
// Open File
std::ifstream stream(get_cache_path(), std::ios::in | std::ios::binary);
if (!stream) {
// No Warning If File Doesn't Exist
// Fail
struct stat s;
// No Warning If File Doesn't Exist
if (stat(get_cache_path().c_str(), &s) == 0) {
WARN("Unable To Open Launcher Cache For Loading");
}
return empty_cache;
}
} else {
// Check Version
unsigned char cache_version;
stream.read((char *) &cache_version, 1);
if (stream.eof() || cache_version != (unsigned char) CACHE_VERSION) {
// Fail
if (!stream.eof()) {
WARN("Invalid Launcher Cache Version (Expected: %i, Actual: %i)", (int) CACHE_VERSION, (int) cache_version);
} else {
WARN("Unable To Read Launcher Cache Version");
}
stream.close();
return empty_cache;
}
} else {
// Load Username And Render Distance
launcher_cache cache;
std::getline(stream, cache.username, '\0');
@ -73,12 +77,20 @@ launcher_cache load_cache() {
// Finish
stream.close();
if (!stream) {
// Fail
WARN("Failure While Loading Launcher Cache");
return empty_cache;
} else {
// Success
ret = cache;
}
}
}
// Unlock File
unlock_file(get_cache_path().c_str(), lock_fd);
// Return
return cache;
return ret;
}
// Save
@ -94,13 +106,15 @@ void save_cache() {
// Log
DEBUG("Saving Launcher Cache...");
// Lock File
int lock_fd = lock_file(get_cache_path().c_str());
// Open File
std::ofstream stream(get_cache_path(), std::ios::out | std::ios::binary);
if (!stream) {
// Fail
WARN("Unable To Open Launcher Cache For Saving");
return;
}
} else {
// Save Cache Version
unsigned char cache_version = (unsigned char) CACHE_VERSION;
stream.write((const char *) &cache_version, 1);
@ -139,6 +153,10 @@ void save_cache() {
if (!stream.good()) {
WARN("Failure While Saving Launcher Cache");
}
}
// Unlock File
unlock_file(get_cache_path().c_str(), lock_fd);
}
// Wipe Cache

View File

@ -41,6 +41,10 @@ void safe_pipe2(int pipefd[2], int flags);
// Check If Two Percentages Are Different Enough To Be Logged
int is_progress_difference_significant(int32_t new_val, int32_t old_val);
// Lock File
int lock_file(const char *file);
void unlock_file(const char *file, int fd);
#ifdef __cplusplus
}
#endif

View File

@ -1,3 +1,6 @@
#include <fcntl.h>
#include <sys/file.h>
#include <libreborn/util.h>
// Safe Version Of pipe()
@ -22,3 +25,21 @@ int is_progress_difference_significant(int32_t new_val, int32_t old_val) {
return 0;
}
}
// Lock File
int lock_file(const char *file) {
int fd = open(file, O_WRONLY | O_CREAT, S_IWUSR);
if (fd == -1) {
ERR("Unable To Open Lock File: %s: %s", file, strerror(errno));
}
if (flock(fd, LOCK_EX) == -1) {
ERR("Unable To Lock File: %s: %s", file, strerror(errno));
}
return fd;
}
void unlock_file(const char *file, int fd) {
if (flock(fd, LOCK_UN) == -1) {
ERR("Unable To Unlock File: %s: %s", file, strerror(errno));
}
close(fd);
}