summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar lat9nq2022-11-23 21:35:47 -0500
committerGravatar lat9nq2022-11-23 21:35:47 -0500
commit3e6c835a64e99e36f09e39a2a5a34b19f244d3d4 (patch)
tree82b678bb33cd63416ec2dc18cf2993944fb9945f
parentMerge pull request #9299 from lioncash/cast (diff)
downloadyuzu-3e6c835a64e99e36f09e39a2a5a34b19f244d3d4.tar.gz
yuzu-3e6c835a64e99e36f09e39a2a5a34b19f244d3d4.tar.xz
yuzu-3e6c835a64e99e36f09e39a2a5a34b19f244d3d4.zip
startup_checks: Use Windows flow for *nix
Spawns a child using fork and exec as opposed to fork alone. Workaround for the macos file manager complaining about not supporting fork without exec. Control flow for *nix is now roughly the same as for Windows.
-rw-r--r--src/yuzu/startup_checks.cpp56
-rw-r--r--src/yuzu/startup_checks.h4
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)
179pid_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
10constexpr char IS_CHILD_ENV_VAR[] = "YUZU_IS_CHILD"; 12constexpr 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
19bool SpawnChild(const char* arg0, PROCESS_INFORMATION* pi, int flags); 21bool SpawnChild(const char* arg0, PROCESS_INFORMATION* pi, int flags);
22#elif defined(YUZU_UNIX)
23pid_t SpawnChild(const char* arg0);
20#endif 24#endif