@@ -134,7 +134,17 @@ int main(int argc, char* argv[]) { | |||||
if (!settings::devMode) { | if (!settings::devMode) { | ||||
logger::logPath = asset::user("log.txt"); | logger::logPath = asset::user("log.txt"); | ||||
} | } | ||||
logger::init(); | |||||
if (!logger::init()) { | |||||
std::string msg = "Cannot access Rack's user folder " + asset::userDir; | |||||
#if defined ARCH_MAC | |||||
// The user likely clicked "Don't Allow" on the Documents Folder permissions dialog, so tell them how to allow it. | |||||
msg += "\n\nMake sure Rack has permission by opening Apple's System Settings and enabling Privacy & Security > Files and Folders > " + APP_NAME + " " + APP_VERSION_MAJOR + " " + APP_EDITION_NAME + " > Documents Folder."; | |||||
// Launch Apple's Privacy & Security settings | |||||
std::system("open x-apple.systempreferences:com.apple.preference.security"); | |||||
#endif | |||||
osdialog_message(OSDIALOG_ERROR, OSDIALOG_OK, msg.c_str()); | |||||
exit(1); | |||||
} | |||||
random::init(); | random::init(); | ||||
// Test code | // Test code | ||||
@@ -31,7 +31,8 @@ enum Level { | |||||
FATAL_LEVEL | FATAL_LEVEL | ||||
}; | }; | ||||
PRIVATE void init(); | |||||
/** Returns whether logger was successfully initialized. */ | |||||
PRIVATE bool init(); | |||||
PRIVATE void destroy(); | PRIVATE void destroy(); | ||||
/** Do not use this function directly. Use the macros above. | /** Do not use this function directly. Use the macros above. | ||||
Thread-safe, meaning messages cannot overlap each other in the log. | Thread-safe, meaning messages cannot overlap each other in the log. | ||||
@@ -46,8 +46,10 @@ static bool isTruncated() { | |||||
} | } | ||||
void init() { | |||||
assert(!outputFile); | |||||
bool init() { | |||||
if (outputFile) | |||||
return true; | |||||
std::lock_guard<std::mutex> lock(mutex); | std::lock_guard<std::mutex> lock(mutex); | ||||
truncated = false; | truncated = false; | ||||
@@ -61,13 +63,11 @@ void init() { | |||||
outputFile = std::fopen(logPath.c_str(), "w"); | outputFile = std::fopen(logPath.c_str(), "w"); | ||||
if (!outputFile) { | if (!outputFile) { | ||||
std::fprintf(stderr, "Could not open log at %s\n", logPath.c_str()); | std::fprintf(stderr, "Could not open log at %s\n", logPath.c_str()); | ||||
return false; | |||||
} | } | ||||
} | } | ||||
// Redirect stdout and stderr to the file | |||||
// Actually, disable this because we don't want to steal stdout/stderr from the DAW in Rack for DAWs. | |||||
// dup2(fileno(outputFile), fileno(stdout)); | |||||
// dup2(fileno(outputFile), fileno(stderr)); | |||||
return true; | |||||
} | } | ||||
void destroy() { | void destroy() { | ||||