diff options
author | Jeremy Huddleston <jeremyhu@freedesktop.org> | 2008-05-13 10:40:20 -0700 |
---|---|---|
committer | Jeremy Huddleston <jeremyhu@freedesktop.org> | 2008-05-14 01:16:01 -0700 |
commit | 3b57c59bb08c9a3211f4ae57d9e2fb569d61bf2f (patch) | |
tree | 2d542a7adbe0c87fa63b9a9df96ea9bfa0c63958 | |
parent | e435acc84cb9477455ad005cee658630cbd363a2 (diff) |
Xquartz: More work on the new Mach startup
(cherry picked from commit 6237acf75d3310d7d4f262556b677557c2907284)
-rw-r--r-- | hw/xquartz/mach-startup/bundle-main.c | 38 | ||||
-rw-r--r-- | hw/xquartz/mach-startup/stub.c | 65 |
2 files changed, 91 insertions, 12 deletions
diff --git a/hw/xquartz/mach-startup/bundle-main.c b/hw/xquartz/mach-startup/bundle-main.c index b0ff9df5b..a66afa805 100644 --- a/hw/xquartz/mach-startup/bundle-main.c +++ b/hw/xquartz/mach-startup/bundle-main.c @@ -34,9 +34,12 @@ #include <string.h> #include <stdlib.h> #include <pthread.h> +#include <stdbool.h> #include <CoreFoundation/CoreFoundation.h> +#include <asl.h> + #include <mach/mach.h> #include <mach/mach_error.h> #include <servers/bootstrap.h> @@ -70,7 +73,7 @@ kern_return_t do_start_x11_server(mach_port_t port, string_array_t argv, mach_msg_type_number_t argvCnt, string_array_t envp, mach_msg_type_number_t envpCnt) { - if(server_main(argvCnt, argv, envp) == 0) + if(server_main(argvCnt - 1, argv, envp) == 0) return KERN_SUCCESS; else return KERN_FAILURE; @@ -137,7 +140,7 @@ static void startup_trigger_thread(void *arg) { } int main(int argc, char **argv, char **envp) { - BOOL listenOnly = FALSE; + Bool listen, listenOnly = FALSE; int i; mach_msg_size_t mxmsgsz = sizeof(union MaxMsgSize) + MAX_TRAILER_SIZE; mach_port_t mp; @@ -151,7 +154,8 @@ int main(int argc, char **argv, char **envp) { } /* TODO: This should be unconditional once we figure out fd passing */ - if((argc > 1 && argv[1][0] == ':') || listenOnly) { + listen = (argc > 1 && argv[1][0] == ':') || listenOnly; + if(listen) { mp = checkin_or_register(SERVER_BOOTSTRAP_NAME); } @@ -160,8 +164,10 @@ int main(int argc, char **argv, char **envp) { */ if(!listenOnly) { struct arg *args = (struct arg*)malloc(sizeof(struct arg)); - if(!args) - FatalError("Could not allocate memory.\n"); + if(!args) { + fprintf(stderr, "Memory allocation error.\n"); + return EXIT_FAILURE; + } args->argc = argc; args->argv = argv; @@ -175,13 +181,13 @@ int main(int argc, char **argv, char **envp) { * file descriptor. For now, we only listen if we are explicitly * told to. */ - if((argc > 1 && argv[1][0] == ':') || listenOnly) { + if(listen) { /* Main event loop */ kr = mach_msg_server(mach_startup_server, mxmsgsz, mp, 0); if (kr != KERN_SUCCESS) { asl_log(NULL, NULL, ASL_LEVEL_ERR, "org.x.X11(mp): %s\n", mach_error_string(kr)); - exit(EXIT_FAILURE); + return EXIT_FAILURE; } } @@ -204,11 +210,27 @@ int main(int argc, char **argv, char **envp) { /* Take care of the case where we're called like a normal DDX */ if(argc > 1 && argv[1][0] == ':') { #ifdef NEW_LAUNCH_METHOD + kern_return_t kr; + mach_port_t mp; + + sleep(2); + /* We need to count envp */ int envpc; for(envpc=0; envp[envpc]; envpc++); - return start_x11_server(argc, argv, envp, envpc); + kr = bootstrap_look_up(bootstrap_port, SERVER_BOOTSTRAP_NAME, &mp); + if (kr != KERN_SUCCESS) { + fprintf(stderr, "bootstrap_look_up(): %s\n", bootstrap_strerror(kr)); + exit(EXIT_FAILURE); + } + + kr = start_x11_server(mp, argv, argc + 1, envp, envpc + 1); + if (kr != KERN_SUCCESS) { + fprintf(stderr, "start_x11_server: %s\n", mach_error_string(kr)); + exit(EXIT_FAILURE); + } + exit(EXIT_SUCCESS); #else return server_main(argc, argv, envp); #endif diff --git a/hw/xquartz/mach-startup/stub.c b/hw/xquartz/mach-startup/stub.c index 3be5f6568..ed917cfcd 100644 --- a/hw/xquartz/mach-startup/stub.c +++ b/hw/xquartz/mach-startup/stub.c @@ -35,10 +35,16 @@ #include <string.h> #include <stdio.h> #include <unistd.h> +#include <errno.h> #define kX11AppBundleId "org.x.X11" #define kX11AppBundlePath "/Contents/MacOS/X11" +#include <mach/mach.h> +#include <mach/mach_error.h> +#include <servers/bootstrap.h> +#include "mach_startup.h" + static char x11_path[PATH_MAX + 1]; static void set_x11_path() { @@ -102,17 +108,68 @@ static void set_x11_path() { #define XSERVER_VERSION "?" #endif -int main(int argc, char **argv) { - +int main(int argc, char **argv, char **envp) { +#ifdef NEW_LAUNCH_METHOD_2 + int envpc; + char *newargv[3]; + kern_return_t kr; + mach_port_t mp; +#endif + if(argc == 2 && !strcmp(argv[1], "-version")) { fprintf(stderr, "X.org Release 7.3\n"); fprintf(stderr, "X.Org X Server %s\n", XSERVER_VERSION); fprintf(stderr, "Build Date: %s\n", BUILD_DATE); - return 0; + return EXIT_SUCCESS; } + +#ifdef NEW_LAUNCH_METHOD_2 + kr = bootstrap_look_up(bootstrap_port, SERVER_BOOTSTRAP_NAME, &mp); + if(kr != KERN_SUCCESS) { + int i; + set_x11_path(); + + /* This forking is ugly and will be cleaned up later */ + pid_t child = fork(); + if(child == -1) { + fprintf(stderr, "Could not fork: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + + if(child == 0) { + newargv[0] = x11_path; + newargv[1] = "--listenonly"; + newargv[2] = NULL; + return execvp(x11_path, newargv); + } + + /* Try connecting for 10 seconds */ + for(i=0; i < 20; i++) { + usleep(500); + kr = bootstrap_look_up(bootstrap_port, SERVER_BOOTSTRAP_NAME, &mp); + if(kr == KERN_SUCCESS) + break; + } + + if(kr != KERN_SUCCESS) { + fprintf(stderr, "bootstrap_look_up(): %s\n", bootstrap_strerror(kr)); + return EXIT_FAILURE; + } + } + + /* Count envp */ + for(envpc=0; envp[envpc]; envpc++); - set_x11_path(); + kr = start_x11_server(mp, argv, argc + 1, envp, envpc + 1); + if (kr != KERN_SUCCESS) { + fprintf(stderr, "start_x11_server: %s\n", mach_error_string(kr)); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +#else + set_x11_path(); argv[0] = x11_path; return execvp(x11_path, argv); +#endif } |