From b0a531b5230cc6275de254a47763346ba5e8bbe3 Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Tue, 5 Jan 2016 11:20:52 +0100 Subject: [PATCH 1/7] Implement file copy on POSIX systems. Autosave should work now on Mac OS X and Linux. Fix tabs randomly inserted by vim Concerns in file copy --- src/platform/posix.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/platform/posix.c b/src/platform/posix.c index d820f78caf..86f1792cce 100644 --- a/src/platform/posix.c +++ b/src/platform/posix.c @@ -41,6 +41,8 @@ // The name of the mutex used to prevent multiple instances of the game from running #define SINGLE_INSTANCE_MUTEX_NAME "RollerCoaster Tycoon 2_GSKMUTEX" +#define FILE_BUFFER_SIZE 4096 + utf8 _userDataDirectoryPath[MAX_PATH] = { 0 }; utf8 _openrctDataDirectoryPath[MAX_PATH] = { 0 }; @@ -492,7 +494,45 @@ int platform_get_drives(){ bool platform_file_copy(const utf8 *srcPath, const utf8 *dstPath, bool overwrite) { - STUB(); + log_verbose("Copying %s to %s", srcPath, dstPath); + + FILE *dstFile; + + if (overwrite) { + dstFile = fopen(dstPath, "wb"); + } else { + dstFile = fopen(dstPath, "wbx"); + } + + if (dstFile != NULL) { + if (errno == EEXIST) { + log_warning("platform_file_copy: Not overwriting %s, because overwrite flag == false", dstPath); + return 0; + } + + log_error("Could not open destination file %s for copying", dstPath); + return 0; + } + + // Open both files and check whether they are opened correctly + FILE *srcFile = fopen(srcPath, "rb"); + if (!srcFile) { + fclose(dstFile); + log_error("Could not open source file %s for copying", srcPath); + return 0; + } + + size_t amount_read = 0; + + char* buffer = (char*) malloc(FILE_BUFFER_SIZE); + while ((amount_read = fread(buffer, FILE_BUFFER_SIZE, 1, srcFile))) { + fwrite(buffer, amount_read, 1, dstFile); + } + + fclose(srcFile); + fclose(dstFile); + free(buffer); + return 0; } From 012ff3adbca5c3ef1f613a295eea552b45ad4ea1 Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Tue, 5 Jan 2016 17:36:58 +0100 Subject: [PATCH 2/7] Add platform_directory_delete implementation for posix. --- src/platform/posix.c | 55 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/src/platform/posix.c b/src/platform/posix.c index 86f1792cce..692f995a81 100644 --- a/src/platform/posix.c +++ b/src/platform/posix.c @@ -37,6 +37,12 @@ #include "../openrct2.h" #include "../util/util.h" #include "platform.h" +#include +#include +#include +#include +#include +#include // The name of the mutex used to prevent multiple instances of the game from running #define SINGLE_INSTANCE_MUTEX_NAME "RollerCoaster Tycoon 2_GSKMUTEX" @@ -167,8 +173,53 @@ bool platform_ensure_directory_exists(const utf8 *path) bool platform_directory_delete(const utf8 *path) { - STUB(); - return true; + log_verbose("Recursively deleting directory %s", path); + + FTS *ftsp; + FTSENT *p, *chp; + + // fts_open only accepts non const paths, so we have to take a copy + char* ourPath = (char*)malloc(strlen(path) + 1); + strcpy(ourPath, path); + + utf8* const patharray[2] = {ourPath, NULL}; + if ((ftsp = fts_open(patharray, FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR, NULL)) == NULL) { + log_error("fts_open returned NULL"); + return 0; + } + + chp = fts_children(ftsp, 0); + if (chp == NULL) { + log_verbose("No files to traverse, deleting directory %s", path); + remove(path); + return 1; // No files to traverse + } + + while ((p = fts_read(ftsp)) != NULL) { + switch (p->fts_info) { + case FTS_DP: // Directory postorder, which means + // the directory is empty + + case FTS_F: // File + if(remove(p->fts_path)) { + log_error("Could not remove %s", p->fts_path); + fts_close(ftsp); + free(ourPath); + return 0; + } + break; + case FTS_ERR: + log_error("Error traversing %s", path); + fts_close(ftsp); + free(ourPath); + return 0; + } + } + + free(ourPath); + fts_close(ftsp); + + return 1; } bool platform_lock_single_instance() From e035c7984a798f5053d843f35bc5bb8f0fd4477b Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Mon, 11 Jan 2016 14:28:24 +0100 Subject: [PATCH 3/7] Fix concerns in platform_directory_delete.\n\n Not sure about fts_close when passing NULL yet. Leaving this commit as a marker --- src/platform/posix.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/platform/posix.c b/src/platform/posix.c index 692f995a81..e11e8a6900 100644 --- a/src/platform/posix.c +++ b/src/platform/posix.c @@ -185,14 +185,16 @@ bool platform_directory_delete(const utf8 *path) utf8* const patharray[2] = {ourPath, NULL}; if ((ftsp = fts_open(patharray, FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR, NULL)) == NULL) { log_error("fts_open returned NULL"); - return 0; + free(ourPath); + return false; } chp = fts_children(ftsp, 0); if (chp == NULL) { log_verbose("No files to traverse, deleting directory %s", path); remove(path); - return 1; // No files to traverse + free(ourPath); + return true; // No files to traverse } while ((p = fts_read(ftsp)) != NULL) { @@ -205,21 +207,21 @@ bool platform_directory_delete(const utf8 *path) log_error("Could not remove %s", p->fts_path); fts_close(ftsp); free(ourPath); - return 0; + return false; } break; case FTS_ERR: log_error("Error traversing %s", path); fts_close(ftsp); free(ourPath); - return 0; + return false; } } free(ourPath); fts_close(ftsp); - return 1; + return true; } bool platform_lock_single_instance() From cd72f282dc6ead0e862c66040449358aa5041bd1 Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Tue, 5 Jan 2016 19:10:28 +0100 Subject: [PATCH 4/7] POSIX: implement move file method --- src/platform/posix.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/platform/posix.c b/src/platform/posix.c index e11e8a6900..39673ab99b 100644 --- a/src/platform/posix.c +++ b/src/platform/posix.c @@ -591,8 +591,7 @@ bool platform_file_copy(const utf8 *srcPath, const utf8 *dstPath, bool overwrite bool platform_file_move(const utf8 *srcPath, const utf8 *dstPath) { - STUB(); - return 0; + return rename(srcPath, dstPath) == 0; } bool platform_file_delete(const utf8 *path) From afc89195aaca5e7bef2ba9aca578884b3416ce2c Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Tue, 5 Jan 2016 19:19:09 +0100 Subject: [PATCH 5/7] Remove stub from posix.c:platform_get_drives --- src/platform/posix.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/platform/posix.c b/src/platform/posix.c index 39673ab99b..4ce5116756 100644 --- a/src/platform/posix.c +++ b/src/platform/posix.c @@ -538,10 +538,7 @@ void platform_enumerate_directories_end(int handle) } int platform_get_drives(){ - /* - return GetLogicalDrives(); - */ - STUB(); + // POSIX systems do not know drives. Return 0. return 0; } From e9ed44438737a4c41180e51ba36bc921992ad05b Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Wed, 6 Jan 2016 11:56:57 +0100 Subject: [PATCH 6/7] Implement singleton locking for POSIX. --- src/platform/posix.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/platform/posix.c b/src/platform/posix.c index 4ce5116756..a6c091590c 100644 --- a/src/platform/posix.c +++ b/src/platform/posix.c @@ -43,9 +43,10 @@ #include #include #include +#include // The name of the mutex used to prevent multiple instances of the game from running -#define SINGLE_INSTANCE_MUTEX_NAME "RollerCoaster Tycoon 2_GSKMUTEX" +#define SINGLE_INSTANCE_MUTEX_NAME "openrct2.lock" #define FILE_BUFFER_SIZE 4096 @@ -226,7 +227,32 @@ bool platform_directory_delete(const utf8 *path) bool platform_lock_single_instance() { - STUB(); + char pidFilePath[MAX_PATH]; + char separator = platform_get_path_separator(); + + strncpy(pidFilePath, _userDataDirectoryPath, MAX_PATH); + strncat(pidFilePath, &separator, 1); + strncat(pidFilePath, SINGLE_INSTANCE_MUTEX_NAME, + MAX_PATH - strnlen(pidFilePath, MAX_PATH) - 1); + + // We will never close this file manually. The operating system will + // take care of that, because flock keeps the lock as long as the + // file is open and closes it automatically on file close. + // This is intentional. + int pidFile = open(pidFilePath, O_CREAT | O_RDWR, 0666); + + if (pidFile == -1) { + log_warning("Cannot open lock file for writing."); + return false; + } + if (flock(pidFile, LOCK_EX | LOCK_NB) == -1) { + if (errno == EWOULDBLOCK) { + log_warning("Another OpenRCT2 session has been found running."); + return false; + } + log_error("flock returned an uncatched errno: %d", errno); + return false; + } return true; } From 44fdffd7e2040aec0b000ef770eff8401b17843b Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Wed, 6 Jan 2016 14:37:08 +0100 Subject: [PATCH 7/7] Added posix changes to changelog. --- distribution/changelog.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 057768d4a2..272cd5ce07 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -7,6 +7,8 @@ - Feature: Allow enabling / disabling of different notifications. - Feature: Improved tile inspector. - Feature: Integrate RCT1 style scenario select with optional unlock progression. +- Fix: Dated autosave files are not created on OSX and Linux. +- Fix: Title sequence directories are not deleted when title sequence is deleted on OSX and Linux. - Fix: [#1333] Rides never become safe again after a crash. - Fix: [#2126] Ferris Wheels set to "backward rotation" stop working (original bug) - Fix: [#2449] Turning off Day/Night Circle while it is night doesn't reset back to day