diff --git a/hw/xquartz/Makefile.am b/hw/xquartz/Makefile.am index cc39c9da1..69778c129 100644 --- a/hw/xquartz/Makefile.am +++ b/hw/xquartz/Makefile.am @@ -7,8 +7,8 @@ AM_CPPFLAGS = \ -DINXQUARTZ \ -DUSE_NEW_CLUT \ -DXFree86Server \ - -I$(top_srcdir)/miext/rootless -# -DNEW_LAUNCH_METHOD + -I$(top_srcdir)/miext/rootless \ + -DNEW_LAUNCH_METHOD SUBDIRS = bundle . GL xpr mach-startup doc diff --git a/hw/xquartz/mach-startup/Makefile.am b/hw/xquartz/mach-startup/Makefile.am index 11f6ba607..59018a977 100644 --- a/hw/xquartz/mach-startup/Makefile.am +++ b/hw/xquartz/mach-startup/Makefile.am @@ -1,18 +1,18 @@ AM_CPPFLAGS = \ -DBUILD_DATE=\"$(BUILD_DATE)\" \ - -DXSERVER_VERSION=\"$(VERSION)\" -# -DNEW_LAUNCH_METHOD -DNEW_LAUNCH_METHOD_2 + -DXSERVER_VERSION=\"$(VERSION)\" \ + -DNEW_LAUNCH_METHOD -DNEW_LAUNCH_METHOD_2 x11appdir = $(APPLE_APPLICATIONS_DIR)/X11.app/Contents/MacOS x11app_PROGRAMS = X11 dist_X11_SOURCES = \ - bundle-main.c \ - launchd_fd.c + 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 0068e02cb..943ec5454 100644 --- a/hw/xquartz/mach-startup/bundle-main.c +++ b/hw/xquartz/mach-startup/bundle-main.c @@ -48,9 +48,9 @@ #include "mach_startupServer.h" #include "launchd_fd.h" +/* From darwinEvents.c ... but don't want to pull in all the server cruft */ void DarwinListenOnOpenFD(int fd); - #define DEFAULT_CLIENT "/usr/X11/bin/xterm" #define DEFAULT_STARTX "/usr/X11/bin/startx" #define DEFAULT_SHELL "/bin/sh" @@ -124,9 +124,6 @@ static mach_port_t checkin_or_register(char *bname) { } /*** $DISPLAY handoff ***/ -/* From darwinEvents.c ... but don't want to pull in all the server cruft */ -void DarwinListenOnOpenFD(int fd); - static void accept_fd_handoff(int connected_fd) { int launchd_fd; @@ -169,7 +166,9 @@ static void accept_fd_handoff(int connected_fd) { if(launchd_fd == -1) fprintf(stderr, "Error receiving $DISPLAY file descriptor, no descriptor received? %d\n", launchd_fd); - fprintf(stderr, "Received new DISPLAY fd: %d\n", launchd_fd); + fprintf(stderr, "Received new DISPLAY fd (1): %d\n", launchd_fd); + sleep(10); + fprintf(stderr, "Received new DISPLAY fd (2): %d\n", launchd_fd); DarwinListenOnOpenFD(launchd_fd); } @@ -189,7 +188,7 @@ static void socket_handoff_thread(void *arg) { struct sockaddr_un servaddr_un; struct sockaddr *servaddr; socklen_t servaddr_len; - int handoff_fd, connected_fd; + int handoff_fd; /* We need to save it since data dies after we pthread_cond_broadcast */ strlcpy(filename, data->socket_filename, STRING_T_SIZE); @@ -208,40 +207,27 @@ static void socket_handoff_thread(void *arg) { handoff_fd = socket(AF_UNIX, SOCK_STREAM, 0); if(handoff_fd == 0) { fprintf(stderr, "Failed to create socket: %s - %s\n", filename, strerror(errno)); + data->retval = EXIT_FAILURE; - return; - } - - if(bind(handoff_fd, servaddr, servaddr_len) != 0) { - fprintf(stderr, "Failed to bind socket: %s - %s\n", filename, strerror(errno)); - data->retval = EXIT_FAILURE; - return; - } - - if(listen(handoff_fd, 10) != 0) { - fprintf(stderr, "Failed to listen to socket: %s - %s\n", filename, strerror(errno)); - data->retval = EXIT_FAILURE; + pthread_mutex_unlock(&data->lock); + pthread_cond_broadcast(&data->cond); return; } - /* Let the dispatch thread now tell the caller that we're listening */ + /* Let the dispatch thread now tell the caller that we're ready */ data->retval = EXIT_SUCCESS; pthread_mutex_unlock(&data->lock); pthread_cond_broadcast(&data->cond); - connected_fd = accept(handoff_fd, NULL, NULL); - - if(connected_fd == -1) { - fprintf(stderr, "Failed to accept incoming connection on socket: %s - %s\n", filename, strerror(errno)); + if(connect(handoff_fd, servaddr, servaddr_len) < 0) { + fprintf(stderr, "Failed to connect to socket: %s - %s\n", filename, strerror(errno)); return; } /* Now actually get the passed file descriptor from this connection */ - accept_fd_handoff(connected_fd); + accept_fd_handoff(handoff_fd); - close(connected_fd); close(handoff_fd); - unlink(filename); } kern_return_t do_prep_fd_handoff(mach_port_t port, string_t socket_filename) { @@ -273,9 +259,11 @@ kern_return_t do_start_x11_server(mach_port_t port, string_array_t argv, if(!_argv || !_envp) { return KERN_FAILURE; } - + + fprintf(stderr, "X11.app: do_start_x11_server(): argc=%d\n", argvCnt); for(i=0; i < argvCnt; i++) { _argv[i] = argv[i]; + fprintf(stderr, "\targv[%u] = %s\n", (unsigned)i, argv[i]); } _argv[argvCnt] = NULL; diff --git a/hw/xquartz/mach-startup/stub.c b/hw/xquartz/mach-startup/stub.c index 854b71cbe..d48ae7477 100644 --- a/hw/xquartz/mach-startup/stub.c +++ b/hw/xquartz/mach-startup/stub.c @@ -113,9 +113,53 @@ static void set_x11_path() { } } +#ifdef NEW_LAUNCH_METHOD +static int create_socket(char *filename_out) { + struct sockaddr_un servaddr_un; + struct sockaddr *servaddr; + socklen_t servaddr_len; + int ret_fd; + size_t try, try_max; + + for(try=0, try_max=5; try < try_max; try++) { + tmpnam(filename_out); + + /* Setup servaddr_un */ + memset (&servaddr_un, 0, sizeof (struct sockaddr_un)); + servaddr_un.sun_family = AF_UNIX; + strlcpy(servaddr_un.sun_path, filename_out, sizeof(servaddr_un.sun_path)); + + servaddr = (struct sockaddr *) &servaddr_un; + servaddr_len = sizeof(struct sockaddr_un) - sizeof(servaddr_un.sun_path) + strlen(filename_out); + + ret_fd = socket(PF_UNIX, SOCK_STREAM, 0); + if(ret_fd == 0) { + fprintf(stderr, "Failed to create socket (try %d / %d): %s - %s\n", (int)try+1, (int)try_max, filename_out, strerror(errno)); + continue; + } + + if(bind(ret_fd, servaddr, servaddr_len) != 0) { + fprintf(stderr, "Failed to bind socket: %s - %s\n", filename_out, strerror(errno)); + close(ret_fd); + return 0; + } + + if(listen(ret_fd, 10) != 0) { + fprintf(stderr, "Failed to listen to socket: %s - %s\n", filename_out, strerror(errno)); + close(ret_fd); + return 0; + } + + return ret_fd; + } + + return 0; +} + static void send_fd_handoff(int handoff_fd, int launchd_fd) { char databuf[] = "display"; struct iovec iov[1]; + int connected_fd; iov[0].iov_base = databuf; iov[0].iov_len = sizeof(databuf); @@ -143,44 +187,21 @@ static void send_fd_handoff(int handoff_fd, int launchd_fd) { *((int*)CMSG_DATA(cmsg)) = launchd_fd; - if (sendmsg(handoff_fd, &msg, 0) < 0) { + connected_fd = accept(handoff_fd, NULL, NULL); + if(connected_fd == -1) { + fprintf(stderr, "Failed to accept incoming connection on socket: %s\n", strerror(errno)); + return; + } + + if(sendmsg(connected_fd, &msg, 0) < 0) { fprintf(stderr, "Error sending $DISPLAY file descriptor: %s\n", strerror(errno)); return; } + close(connected_fd); fprintf(stderr, "send %d %d %d %s\n", handoff_fd, launchd_fd, errno, strerror(errno)); } - -static void handoff_fd(const char *filename, int launchd_fd) { - struct sockaddr_un servaddr_un; - struct sockaddr *servaddr; - socklen_t servaddr_len; - int handoff_fd; - - /* Setup servaddr_un */ - memset (&servaddr_un, 0, sizeof (struct sockaddr_un)); - servaddr_un.sun_family = AF_UNIX; - strlcpy(servaddr_un.sun_path, filename, sizeof(servaddr_un.sun_path)); - - servaddr = (struct sockaddr *) &servaddr_un; - servaddr_len = sizeof(struct sockaddr_un) - sizeof(servaddr_un.sun_path) + strlen(filename); - - handoff_fd = socket(PF_UNIX, SOCK_STREAM, 0); - if(handoff_fd == 0) { - fprintf(stderr, "Failed to create socket: %s - %s\n", filename, strerror(errno)); - return; - } - - if(connect(handoff_fd, servaddr, servaddr_len) < 0) { - fprintf(stderr, "Failed to establish connection on socket: %s - %s\n", filename, strerror(errno)); - return; - } - - fprintf(stderr, "Socket: %s\n", filename); - - send_fd_handoff(handoff_fd, launchd_fd); - close(handoff_fd); -} +#endif int main(int argc, char **argv, char **envp) { #ifdef NEW_LAUNCH_METHOD @@ -191,7 +212,7 @@ int main(int argc, char **argv, char **envp) { string_array_t newargv; size_t i; int launchd_fd; - string_t handoff_socket; + string_t handoff_socket_filename; #endif if(argc == 2 && !strcmp(argv[1], "-version")) { @@ -241,9 +262,15 @@ int main(int argc, char **argv, char **envp) { /* Handoff the $DISPLAY FD */ if(launchd_fd != -1) { - tmpnam(handoff_socket); - if(prep_fd_handoff(mp, handoff_socket) == KERN_SUCCESS) { - handoff_fd(handoff_socket, launchd_fd); + int handoff_fd = create_socket(handoff_socket_filename); + + if((handoff_fd != 0) && + (prep_fd_handoff(mp, handoff_socket_filename) == KERN_SUCCESS)) { + send_fd_handoff(handoff_fd, launchd_fd); + + // Cleanup + close(handoff_fd); + unlink(handoff_socket_filename); } else { fprintf(stderr, "Unable to hand of $DISPLAY file descriptor\n"); }