summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Huddleston <jeremyhu@freedesktop.org>2008-05-13 10:40:20 -0700
committerJeremy Huddleston <jeremyhu@freedesktop.org>2008-05-14 01:16:01 -0700
commit3b57c59bb08c9a3211f4ae57d9e2fb569d61bf2f (patch)
tree2d542a7adbe0c87fa63b9a9df96ea9bfa0c63958
parente435acc84cb9477455ad005cee658630cbd363a2 (diff)
Xquartz: More work on the new Mach startup
(cherry picked from commit 6237acf75d3310d7d4f262556b677557c2907284)
-rw-r--r--hw/xquartz/mach-startup/bundle-main.c38
-rw-r--r--hw/xquartz/mach-startup/stub.c65
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
}