diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/yuzu/startup_checks.cpp | 56 | ||||
| -rw-r--r-- | src/yuzu/startup_checks.h | 4 |
2 files changed, 51 insertions, 9 deletions
diff --git a/src/yuzu/startup_checks.cpp b/src/yuzu/startup_checks.cpp index 6a91212e2..95c9fdecb 100644 --- a/src/yuzu/startup_checks.cpp +++ b/src/yuzu/startup_checks.cpp | |||
| @@ -4,11 +4,14 @@ | |||
| 4 | #include "video_core/vulkan_common/vulkan_wrapper.h" | 4 | #include "video_core/vulkan_common/vulkan_wrapper.h" |
| 5 | 5 | ||
| 6 | #ifdef _WIN32 | 6 | #ifdef _WIN32 |
| 7 | #include <cstring> // for memset, strncpy | 7 | #include <cstring> // for memset, strncpy, strncmp |
| 8 | #include <processthreadsapi.h> | 8 | #include <processthreadsapi.h> |
| 9 | #include <windows.h> | 9 | #include <windows.h> |
| 10 | #elif defined(YUZU_UNIX) | 10 | #elif defined(YUZU_UNIX) |
| 11 | #include <cstring> // for strncmp | ||
| 11 | #include <errno.h> | 12 | #include <errno.h> |
| 13 | #include <spawn.h> | ||
| 14 | #include <sys/types.h> | ||
| 12 | #include <sys/wait.h> | 15 | #include <sys/wait.h> |
| 13 | #include <unistd.h> | 16 | #include <unistd.h> |
| 14 | #endif | 17 | #endif |
| @@ -53,6 +56,13 @@ bool CheckEnvVars(bool* is_child) { | |||
| 53 | IS_CHILD_ENV_VAR, GetLastError()); | 56 | IS_CHILD_ENV_VAR, GetLastError()); |
| 54 | return true; | 57 | return true; |
| 55 | } | 58 | } |
| 59 | #elif defined(YUZU_UNIX) | ||
| 60 | const char* startup_check_var = getenv(STARTUP_CHECK_ENV_VAR); | ||
| 61 | if (startup_check_var != nullptr && | ||
| 62 | std::strncmp(startup_check_var, ENV_VAR_ENABLED_TEXT, 8) == 0) { | ||
| 63 | CheckVulkan(); | ||
| 64 | return true; | ||
| 65 | } | ||
| 56 | #endif | 66 | #endif |
| 57 | return false; | 67 | return false; |
| 58 | } | 68 | } |
| @@ -101,20 +111,22 @@ bool StartupChecks(const char* arg0, bool* has_broken_vulkan, bool perform_vulka | |||
| 101 | } | 111 | } |
| 102 | 112 | ||
| 103 | #elif defined(YUZU_UNIX) | 113 | #elif defined(YUZU_UNIX) |
| 114 | const int env_var_set = setenv(STARTUP_CHECK_ENV_VAR, ENV_VAR_ENABLED_TEXT, 1); | ||
| 115 | if (env_var_set == -1) { | ||
| 116 | const int err = errno; | ||
| 117 | std::fprintf(stderr, "setenv failed to set %s with error %d\n", STARTUP_CHECK_ENV_VAR, err); | ||
| 118 | return false; | ||
| 119 | } | ||
| 120 | |||
| 104 | if (perform_vulkan_check) { | 121 | if (perform_vulkan_check) { |
| 105 | const pid_t pid = fork(); | 122 | const pid_t pid = SpawnChild(arg0); |
| 106 | if (pid == 0) { | 123 | if (pid == -1) { |
| 107 | CheckVulkan(); | ||
| 108 | return true; | ||
| 109 | } else if (pid == -1) { | ||
| 110 | const int err = errno; | ||
| 111 | std::fprintf(stderr, "fork failed with error %d\n", err); | ||
| 112 | return false; | 124 | return false; |
| 113 | } | 125 | } |
| 114 | 126 | ||
| 115 | // Get exit code from child process | 127 | // Get exit code from child process |
| 116 | int status; | 128 | int status; |
| 117 | const int r_val = wait(&status); | 129 | const int r_val = waitpid(pid, &status, 0); |
| 118 | if (r_val == -1) { | 130 | if (r_val == -1) { |
| 119 | const int err = errno; | 131 | const int err = errno; |
| 120 | std::fprintf(stderr, "wait failed with error %d\n", err); | 132 | std::fprintf(stderr, "wait failed with error %d\n", err); |
| @@ -123,6 +135,13 @@ bool StartupChecks(const char* arg0, bool* has_broken_vulkan, bool perform_vulka | |||
| 123 | // Vulkan is broken if the child crashed (return value is not zero) | 135 | // Vulkan is broken if the child crashed (return value is not zero) |
| 124 | *has_broken_vulkan = (status != 0); | 136 | *has_broken_vulkan = (status != 0); |
| 125 | } | 137 | } |
| 138 | |||
| 139 | const int env_var_cleared = unsetenv(STARTUP_CHECK_ENV_VAR); | ||
| 140 | if (env_var_cleared == -1) { | ||
| 141 | const int err = errno; | ||
| 142 | std::fprintf(stderr, "unsetenv failed to clear %s with error %d\n", STARTUP_CHECK_ENV_VAR, | ||
| 143 | err); | ||
| 144 | } | ||
| 126 | #endif | 145 | #endif |
| 127 | return false; | 146 | return false; |
| 128 | } | 147 | } |
| @@ -156,4 +175,23 @@ bool SpawnChild(const char* arg0, PROCESS_INFORMATION* pi, int flags) { | |||
| 156 | 175 | ||
| 157 | return true; | 176 | return true; |
| 158 | } | 177 | } |
| 178 | #elif defined(YUZU_UNIX) | ||
| 179 | pid_t SpawnChild(const char* arg0) { | ||
| 180 | const pid_t pid = fork(); | ||
| 181 | |||
| 182 | if (pid == -1) { | ||
| 183 | // error | ||
| 184 | const int err = errno; | ||
| 185 | std::fprintf(stderr, "fork failed with error %d\n", err); | ||
| 186 | return pid; | ||
| 187 | } else if (pid == 0) { | ||
| 188 | // child | ||
| 189 | execl(arg0, arg0, nullptr); | ||
| 190 | const int err = errno; | ||
| 191 | std::fprintf(stderr, "execl failed with error %d\n", err); | ||
| 192 | return -1; | ||
| 193 | } | ||
| 194 | |||
| 195 | return pid; | ||
| 196 | } | ||
| 159 | #endif | 197 | #endif |
diff --git a/src/yuzu/startup_checks.h b/src/yuzu/startup_checks.h index d8e563be6..2f86fb843 100644 --- a/src/yuzu/startup_checks.h +++ b/src/yuzu/startup_checks.h | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | 5 | ||
| 6 | #ifdef _WIN32 | 6 | #ifdef _WIN32 |
| 7 | #include <windows.h> | 7 | #include <windows.h> |
| 8 | #elif defined(YUZU_UNIX) | ||
| 9 | #include <sys/types.h> | ||
| 8 | #endif | 10 | #endif |
| 9 | 11 | ||
| 10 | constexpr char IS_CHILD_ENV_VAR[] = "YUZU_IS_CHILD"; | 12 | constexpr char IS_CHILD_ENV_VAR[] = "YUZU_IS_CHILD"; |
| @@ -17,4 +19,6 @@ bool StartupChecks(const char* arg0, bool* has_broken_vulkan, bool perform_vulka | |||
| 17 | 19 | ||
| 18 | #ifdef _WIN32 | 20 | #ifdef _WIN32 |
| 19 | bool SpawnChild(const char* arg0, PROCESS_INFORMATION* pi, int flags); | 21 | bool SpawnChild(const char* arg0, PROCESS_INFORMATION* pi, int flags); |
| 22 | #elif defined(YUZU_UNIX) | ||
| 23 | pid_t SpawnChild(const char* arg0); | ||
| 20 | #endif | 24 | #endif |