diff --git a/.gitignore b/.gitignore index e4166e7..db17f57 100644 --- a/.gitignore +++ b/.gitignore @@ -67,3 +67,4 @@ squashfs-root/ # build products src/runtime/runtime +_codeql_detected_source_root diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index 2ebb3c8..e3ba402 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -1846,11 +1846,52 @@ int main(int argc, char* argv[]) { strcpy(filename, mount_dir); strcat(filename, "/AppRun"); - /* TODO: Find a way to get the exit status and/or output of this */ - execv(filename, real_argv); - /* Error if we continue here */ - perror("execv error"); - exit(EXIT_EXECERROR); + /* Fork before exec to ensure we can close the keepalive pipe after AppRun exits */ + pid_t apprun_pid = fork(); + if (apprun_pid == -1) { + perror("fork error"); + exit(EXIT_EXECERROR); + } + + if (apprun_pid == 0) { + /* Child process - close keepalive pipe before exec */ + close(keepalive_pipe[0]); + + /* exec AppRun */ + execv(filename, real_argv); + /* Error if we continue here */ + perror("execv error"); + exit(EXIT_EXECERROR); + } else { + /* Parent process - wait for AppRun to finish, then close pipe */ + int status; + pid_t waited_pid; + do { + waited_pid = waitpid(apprun_pid, &status, 0); + } while (waited_pid == -1 && errno == EINTR); + if (waited_pid == -1) { + perror("waitpid error"); + close(keepalive_pipe[0]); + free(real_argv); + exit(EXIT_EXECERROR); + } + + /* Close the keepalive pipe after AppRun exits to terminate FUSE daemon */ + close(keepalive_pipe[0]); + + /* Free allocated memory before exit */ + free(real_argv); + + /* Exit with the same status as AppRun */ + if (WIFEXITED(status)) { + exit(WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + /* Child was killed by a signal, exit with 128 + signal number */ + exit(128 + WTERMSIG(status)); + } else { + exit(EXIT_EXECERROR); + } + } } return 0;