diff options
author | Jeremy Huddleston <jeremyhu@freedesktop.org> | 2008-05-15 12:26:32 -0700 |
---|---|---|
committer | Jeremy Huddleston <jeremyhu@freedesktop.org> | 2008-05-18 22:45:19 -0700 |
commit | 4be2104c801340075e030d06d24ceb4d8a6d6549 (patch) | |
tree | d5700f2ecb5831fcb9361d1cd88dd84169392016 | |
parent | 82c4075d4ba3bea03341c80b754b0f9d2f62a826 (diff) |
XQuartz: More work towards Mach-IPC startup... started working on FD passing
(cherry picked from commit 27fbfeacfa16d620801ac3492b25c1e50aec8588)
-rw-r--r-- | hw/xquartz/Makefile.am | 1 | ||||
-rw-r--r-- | hw/xquartz/X11Application.m | 5 | ||||
-rw-r--r-- | hw/xquartz/darwinEvents.c | 3 | ||||
-rw-r--r-- | hw/xquartz/darwinEvents.h | 1 | ||||
-rw-r--r-- | hw/xquartz/mach-startup/Makefile.am | 14 | ||||
-rw-r--r-- | hw/xquartz/mach-startup/bundle-main.c | 250 | ||||
-rw-r--r-- | hw/xquartz/mach-startup/mach_startup.defs | 7 | ||||
-rw-r--r-- | hw/xquartz/mach-startup/stub.c | 19 |
8 files changed, 194 insertions, 106 deletions
diff --git a/hw/xquartz/Makefile.am b/hw/xquartz/Makefile.am index 77d662f97..cc39c9da1 100644 --- a/hw/xquartz/Makefile.am +++ b/hw/xquartz/Makefile.am @@ -8,6 +8,7 @@ AM_CPPFLAGS = \ -DUSE_NEW_CLUT \ -DXFree86Server \ -I$(top_srcdir)/miext/rootless +# -DNEW_LAUNCH_METHOD SUBDIRS = bundle . GL xpr mach-startup doc diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m index 1a7d55a8c..d687c1f5f 100644 --- a/hw/xquartz/X11Application.m +++ b/hw/xquartz/X11Application.m @@ -787,7 +787,6 @@ environment?", @"Startup xinitrc dialog"); void X11ApplicationMain (int argc, char **argv, char **envp) { NSAutoreleasePool *pool; - int launchd_fd; #ifdef DEBUG while (access ("/tmp/x11-block", F_OK) == 0) sleep (1); @@ -818,9 +817,9 @@ void X11ApplicationMain (int argc, char **argv, char **envp) { #ifndef NEW_LAUNCH_METHOD /* Start listening on the launchd fd */ - launchd_fd = launchd_display_fd(); + int launchd_fd = launchd_display_fd(); if(launchd_fd != -1) { - DarwinSendDDXEvent(kXquartzListenOnOpenFD, 1, launchd_fd); + DarwinListenOnOpenFD(launchd_fd); } #endif diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 06c5df048..9ecebe421 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -551,6 +551,9 @@ void DarwinUpdateModKeys(int flags) { old_flags = flags; } +void DarwinListenOnOpenFD(int fd) { + DarwinSendDDXEvent(kXquartzListenOnOpenFD, 1, fd); +} /* * DarwinSendDDXEvent diff --git a/hw/xquartz/darwinEvents.h b/hw/xquartz/darwinEvents.h index 58817fb01..7a1e8ca5d 100644 --- a/hw/xquartz/darwinEvents.h +++ b/hw/xquartz/darwinEvents.h @@ -39,6 +39,7 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode); void DarwinSendScrollEvents(float count_x, float count_y, int pointer_x, int pointer_y, float pressure, float tilt_x, float tilt_y); void DarwinUpdateModKeys(int flags); +void DarwinListenOnOpenFD(int fd); /* * Special ddx events understood by the X server diff --git a/hw/xquartz/mach-startup/Makefile.am b/hw/xquartz/mach-startup/Makefile.am index 3ed1c1ab3..11f6ba607 100644 --- a/hw/xquartz/mach-startup/Makefile.am +++ b/hw/xquartz/mach-startup/Makefile.am @@ -10,9 +10,9 @@ dist_X11_SOURCES = \ bundle-main.c \ launchd_fd.c -nodist_X11_SOURCES = \ - mach_startupServer.c \ - mach_startupUser.c +#nodist_X11_SOURCES = \ +# mach_startupServer.c \ +# mach_startupUser.c X11_LDADD = \ $(top_builddir)/hw/xquartz/libXquartz.la \ @@ -34,11 +34,11 @@ X11_LDFLAGS = \ bin_PROGRAMS = Xquartz dist_Xquartz_SOURCES = \ - stub.c \ - launchd_fd.c + stub.c +# launchd_fd.c -nodist_Xquartz_SOURCES = \ - mach_startupUser.c +#nodist_Xquartz_SOURCES = \ +# mach_startupUser.c Xquartz_LDFLAGS = \ -Wl,-framework,CoreServices diff --git a/hw/xquartz/mach-startup/bundle-main.c b/hw/xquartz/mach-startup/bundle-main.c index dd75f0267..4ddd82f7b 100644 --- a/hw/xquartz/mach-startup/bundle-main.c +++ b/hw/xquartz/mach-startup/bundle-main.c @@ -28,6 +28,8 @@ promote the sale, use or other dealings in this Software without prior written authorization. */ +#include <CoreFoundation/CoreFoundation.h> + #include <X11/Xlib.h> #include <unistd.h> #include <stdio.h> @@ -35,10 +37,8 @@ #include <stdlib.h> #include <pthread.h> #include <stdbool.h> - -#include <CoreFoundation/CoreFoundation.h> - -#include <asl.h> +#include <sys/socket.h> +#include <sys/un.h> #include <mach/mach.h> #include <mach/mach_error.h> @@ -56,6 +56,11 @@ static char *command_from_prefs(const char *key, const char *default_value); /* This is in quartzStartup.c */ int server_main(int argc, char **argv, char **envp); +static int execute(const char *command); +static char *command_from_prefs(const char *key, const char *default_value); + +#ifdef NEW_LAUNCH_METHOD + struct arg { int argc; char **argv; @@ -69,39 +74,6 @@ union MaxMsgSize { union __ReplyUnion__mach_startup_subsystem rep; }; -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) { - /* And now back to char ** */ - char **_argv = alloca((argvCnt + 1) * sizeof(char *)); - char **_envp = alloca((envpCnt + 1) * sizeof(char *)); - size_t i; - - if(!_argv || !_envp) { - return KERN_FAILURE; - } - - for(i=0; i < argvCnt; i++) { - _argv[i] = argv[i]; - } - _argv[argvCnt] = NULL; - - for(i=0; i < envpCnt; i++) { - _envp[i] = envp[i]; - } - _envp[envpCnt] = NULL; - - if(server_main(argvCnt, _argv, _envp) == 0) - return KERN_SUCCESS; - else - return KERN_FAILURE; -} - -kern_return_t do_exit(mach_port_t port, int value) { - exit(value); -} - static mach_port_t checkin_or_register(char *bname) { kern_return_t kr; mach_port_t mp; @@ -147,71 +119,99 @@ static pthread_t create_thread(void *func, void *arg) { return tid; } -/*** Main ***/ -static int execute(const char *command); -static char *command_from_prefs(const char *key, const char *default_value); +/*** $DISPLAY handoff ***/ +static char display_handoff_socket[PATH_MAX + 1]; -#ifdef NEW_LAUNCH_METHOD -static void startup_trigger_thread(void *arg) { - struct arg args = *((struct arg *)arg); - free(arg); - startup_trigger(args.argc, args.argv, args.envp); +kern_return_t do_get_display_handoff_socket(mach_port_t port, string_t filename) { + strlcpy(filename, display_handoff_socket, STRING_T_SIZE); + fprintf(stderr, "Telling him the filename is %s = %s\n", filename, display_handoff_socket); + return KERN_SUCCESS; } -int main(int argc, char **argv, char **envp) { - Bool listen, listenOnly = FALSE; - int i; - mach_msg_size_t mxmsgsz = sizeof(union MaxMsgSize) + MAX_TRAILER_SIZE; - mach_port_t mp; - kern_return_t kr; +/* From darwinEvents.c ... but don't want to pull in all the server cruft */ +void DarwinListenOnOpenFD(int fd); - fprintf(stderr, "X11.app: main(): argc=%d\n", argc); - for(i=1; i < argc; i++) { - fprintf(stderr, "\targv[%u] = %s\n", (unsigned)i, argv[i]); - if(!strcmp(argv[i], "--listenonly")) { - listenOnly = TRUE; - } - } +static void accept_fd_handoff(int connectedSocket) { + int fd; + return; + DarwinListenOnOpenFD(fd); +} - /* TODO: This should be unconditional once we figure out fd passing */ - listen = (argc > 1 && argv[1][0] == ':') || listenOnly; - if(listen) { - mp = checkin_or_register(SERVER_BOOTSTRAP_NAME); +/* This thread loops accepting incoming connections and handing off the file + * descriptor for the new connection to accept_fd_handoff() + */ +static void socket_handoff_thread(void *arg) { + struct sockaddr_un servaddr_un; + struct sockaddr *servaddr; + int handoff_fd; + int servaddr_len; + + /* Wipe ourselves clean */ + memset (&servaddr_un, 0, sizeof (struct sockaddr_un)); + + servaddr_un.sun_family = AF_UNIX; + strcpy(servaddr_un.sun_path, display_handoff_socket); + servaddr = (struct sockaddr *) &servaddr_un; + servaddr_len = sizeof(struct sockaddr_un) - sizeof(servaddr_un.sun_path) + strlen(display_handoff_socket); + + handoff_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if(handoff_fd == 0) { + fprintf(stderr, "Failed to create socket: %s - %s\n", display_handoff_socket, strerror(errno)); + return; + exit(EXIT_FAILURE); } - - /* Check if we need to do something other than listen, and make another - * thread handle it. - */ - if(!listenOnly) { - struct arg *args = (struct arg*)malloc(sizeof(struct arg)); - if(!args) { - fprintf(stderr, "Memory allocation error.\n"); - return EXIT_FAILURE; - } - - args->argc = argc; - args->argv = argv; - args->envp = envp; - - create_thread(startup_trigger_thread, args); + + if(bind(handoff_fd, servaddr, servaddr_len) != 0) { + fprintf(stderr, "Failed to bind socket: %s - %s\n", display_handoff_socket, strerror(errno)); + return; + exit(EXIT_FAILURE); } - - /* TODO: This should actually fall through rather than be the else - * case once we figure out how to get the stub to pass the - * file descriptor. For now, we only listen if we are explicitly - * told to. - */ - 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)); - return EXIT_FAILURE; + + if(listen(handoff_fd, 10) != 0) { + fprintf(stderr, "Failed to listen to socket: %s - %s\n", display_handoff_socket, strerror(errno)); + return; + exit(EXIT_FAILURE); + } + + while(true) { + int connectedSocket = accept(handoff_fd, NULL, NULL); + + if(connectedSocket == -1) { + fprintf(stderr, "Failed to accept incoming connection on socket: %s - %s\n", display_handoff_socket, strerror(errno)); + continue; } + accept_fd_handoff(connectedSocket); } +} - return EXIT_SUCCESS; +/*** Server Startup ***/ +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) { + /* And now back to char ** */ + char **_argv = alloca((argvCnt + 1) * sizeof(char *)); + char **_envp = alloca((envpCnt + 1) * sizeof(char *)); + size_t i; + + if(!_argv || !_envp) { + return KERN_FAILURE; + } + + for(i=0; i < argvCnt; i++) { + _argv[i] = argv[i]; + } + _argv[argvCnt] = NULL; + + for(i=0; i < envpCnt; i++) { + _envp[i] = envp[i]; + } + _envp[envpCnt] = NULL; + + if(server_main(argvCnt, _argv, _envp) == 0) + return KERN_SUCCESS; + else + return KERN_FAILURE; } int startup_trigger(int argc, char **argv, char **envp) { @@ -305,6 +305,72 @@ int main(int argc, char **argv, char **envp) { return execute(command_from_prefs("startx_script", DEFAULT_STARTX)); } +#ifdef NEW_LAUNCH_METHOD +static void startup_trigger_thread(void *arg) { + struct arg args = *((struct arg *)arg); + free(arg); + startup_trigger(args.argc, args.argv, args.envp); +} + +/*** Main ***/ +int main(int argc, char **argv, char **envp) { + Bool listenOnly = FALSE; + int i; + mach_msg_size_t mxmsgsz = sizeof(union MaxMsgSize) + MAX_TRAILER_SIZE; + mach_port_t mp; + kern_return_t kr; + + fprintf(stderr, "X11.app: main(): argc=%d\n", argc); + for(i=1; i < argc; i++) { + fprintf(stderr, "\targv[%u] = %s\n", (unsigned)i, argv[i]); + if(!strcmp(argv[i], "--listenonly")) { + listenOnly = TRUE; + } + } + + mp = checkin_or_register(SERVER_BOOTSTRAP_NAME); + if(mp == MACH_PORT_NULL) { + fprintf(stderr, "NULL mach service: %s", SERVER_BOOTSTRAP_NAME); + return EXIT_FAILURE; + } + + /* Figure out what our handoff socket will be + * TODO: cleanup on exit. + */ + tmpnam(display_handoff_socket); + create_thread(socket_handoff_thread, NULL); + + fprintf(stderr, "Hi\n"); + + /* Check if we need to do something other than listen, and make another + * thread handle it. + */ + if(!listenOnly) { + struct arg *args = (struct arg*)malloc(sizeof(struct arg)); + if(!args) { + fprintf(stderr, "Memory allocation error.\n"); + return EXIT_FAILURE; + } + + args->argc = argc; + args->argv = argv; + args->envp = envp; + + create_thread(startup_trigger_thread, args); + } + + /* Main event loop */ + fprintf(stderr, "Statrup coming...\n"); + kr = mach_msg_server(mach_startup_server, mxmsgsz, mp, 0); + if (kr != KERN_SUCCESS) { + fprintf(stderr, "org.x.X11(mp): %s\n", mach_error_string(kr)); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} +#endif + static int execute(const char *command) { const char *newargv[7]; const char **s; diff --git a/hw/xquartz/mach-startup/mach_startup.defs b/hw/xquartz/mach-startup/mach_startup.defs index 83b31b7c0..05bdf569f 100644 --- a/hw/xquartz/mach-startup/mach_startup.defs +++ b/hw/xquartz/mach-startup/mach_startup.defs @@ -33,9 +33,14 @@ import "mach_startup_types.h"; subsystem mach_startup 1000; serverprefix do_; -type string_array_t = array[] of c_string[1024]; +type string_t = c_string[1024]; +type string_array_t = array[] of string_t; routine start_x11_server( port : mach_port_t; argv : string_array_t; envp : string_array_t); + +routine get_display_handoff_socket( + port : mach_port_t; + filename : string_t); diff --git a/hw/xquartz/mach-startup/stub.c b/hw/xquartz/mach-startup/stub.c index c53ed5364..5fdbad882 100644 --- a/hw/xquartz/mach-startup/stub.c +++ b/hw/xquartz/mach-startup/stub.c @@ -45,6 +45,8 @@ #include <servers/bootstrap.h> #include "mach_startup.h" +#include "launchd_fd.h" + static char x11_path[PATH_MAX + 1]; static void set_x11_path() { @@ -109,13 +111,15 @@ static void set_x11_path() { #endif int main(int argc, char **argv, char **envp) { -#ifdef NEW_LAUNCH_METHOD_2 +#ifdef NEW_LAUNCH_METHOD int envpc; kern_return_t kr; mach_port_t mp; string_array_t newenvp; string_array_t newargv; size_t i; + int launchd_fd; + string_t handoff_socket; #endif if(argc == 2 && !strcmp(argv[1], "-version")) { @@ -125,7 +129,10 @@ int main(int argc, char **argv, char **envp) { return EXIT_SUCCESS; } -#ifdef NEW_LAUNCH_METHOD_2 +#ifdef NEW_LAUNCH_METHOD + /* Get the $DISPLAY FD */ + launchd_fd = launchd_display_fd(); + kr = bootstrap_look_up(bootstrap_port, SERVER_BOOTSTRAP_NAME, &mp); if(kr != KERN_SUCCESS) { set_x11_path(); @@ -147,7 +154,7 @@ int main(int argc, char **argv, char **envp) { } /* Try connecting for 10 seconds */ - for(i=0; i < 40; i++) { + for(i=0; i < 80; i++) { usleep(250000); kr = bootstrap_look_up(bootstrap_port, SERVER_BOOTSTRAP_NAME, &mp); if(kr == KERN_SUCCESS) @@ -159,6 +166,12 @@ int main(int argc, char **argv, char **envp) { return EXIT_FAILURE; } } + + /* Handoff the $DISPLAY FD */ + if(launchd_fd != -1) { + get_display_handoff_socket(mp, handoff_socket); + fprintf(stderr, "Handoff socket: %s %d\n", handoff_socket, launchd_fd); + } /* Count envp */ for(envpc=0; envp[envpc]; envpc++); |