xserver: Branch 'xorg-server-1.5-apple' - 3 commits

Jeremy Huddleston jeremyhu at kemper.freedesktop.org
Mon May 12 10:42:26 PDT 2008


 .gitignore                                   |    4 
 hw/xquartz/bundle/Info.plist                 |    4 
 hw/xquartz/mach-startup/Makefile.am          |   28 ++++
 hw/xquartz/mach-startup/bundle-main.c        |  162 ++++++++++++++++++++++++++-
 hw/xquartz/mach-startup/mach_startup.defs    |   41 ++++++
 hw/xquartz/mach-startup/mach_startup_types.h |    8 +
 hw/xquartz/mach-startup/stub.c               |   44 +++++--
 7 files changed, 274 insertions(+), 17 deletions(-)

New commits:
commit c624964539be2515f493957a1922d8e857736eb4
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Mon May 12 10:36:44 2008 -0700

    XQuartz: Added some version checking protection so we don't trigger an infinite exec loop with new /usr/X11/bin/Xquartz and older X11.app
    (cherry picked from commit 78032815aeb10c22ff45b49702e9c9df82ab471c)

diff --git a/hw/xquartz/bundle/Info.plist b/hw/xquartz/bundle/Info.plist
index 4b0830f..30bb3c8 100644
--- a/hw/xquartz/bundle/Info.plist
+++ b/hw/xquartz/bundle/Info.plist
@@ -20,6 +20,10 @@
 		<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
 		<string>2.3.0</string>
+	<key>CFBundleVersion</key>
+		<string>2.3.0</string>
+	<key>CFBundleVersionString</key>
+		<string>2.3.0</string>
 	<key>CFBundleSignature</key>
 		<string>x11a</string>
 	<key>CSResourcesFileMapped</key>
diff --git a/hw/xquartz/mach-startup/stub.c b/hw/xquartz/mach-startup/stub.c
index 70f222c..3be5f65 100644
--- a/hw/xquartz/mach-startup/stub.c
+++ b/hw/xquartz/mach-startup/stub.c
@@ -43,33 +43,55 @@ static char x11_path[PATH_MAX + 1];
 
 static void set_x11_path() {
     CFURLRef appURL = NULL;
+    CFBundleRef bundle = NULL;
     OSStatus osstatus = LSFindApplicationForInfo(kLSUnknownCreator, CFSTR(kX11AppBundleId), nil, nil, &appURL);
-    
+    UInt32 ver;
+
     switch (osstatus) {
         case noErr:
             if (appURL == NULL) {
-                fprintf(stderr, "xinit: Invalid response from LSFindApplicationForInfo(%s)\n", 
+                fprintf(stderr, "Xquartz: Invalid response from LSFindApplicationForInfo(%s)\n", 
                         kX11AppBundleId);
                 exit(1);
             }
-            
+
+            bundle = CFBundleCreate(NULL, appURL);
+            if(!bundle) {
+                fprintf(stderr, "Xquartz: Null value returned from CFBundleCreate().\n");
+                exit(2);                
+            }
+
             if (!CFURLGetFileSystemRepresentation(appURL, true, (unsigned char *)x11_path, sizeof(x11_path))) {
-                fprintf(stderr, "xinit: Error resolving URL for %s\n", kX11AppBundleId);
-                exit(2);
+                fprintf(stderr, "Xquartz: Error resolving URL for %s\n", kX11AppBundleId);
+                exit(3);
             }
-            
+
+            ver = CFBundleGetVersionNumber(bundle);
+            if(ver < 0x02308000) {
+                CFStringRef versionStr = CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleVersionKey);
+                const char * versionCStr = "Unknown";
+
+                if(versionStr) 
+                    versionCStr = CFStringGetCStringPtr(versionStr, kCFStringEncodingMacRoman);
+
+                fprintf(stderr, "Xquartz: Could not find a new enough X11.app LSFindApplicationForInfo() returned\n");
+                fprintf(stderr, "         X11.app = %s\n", x11_path);
+                fprintf(stderr, "         Version = %s (%x), Expected Version > 2.3.0\n", versionCStr, (unsigned)ver);
+                exit(9);
+            }
+
             strlcat(x11_path, kX11AppBundlePath, sizeof(x11_path));
 #ifdef DEBUG
-            fprintf(stderr, "XQuartz: X11.app = %s\n", x11_path);
+            fprintf(stderr, "Xquartz: X11.app = %s\n", x11_path);
 #endif
             break;
         case kLSApplicationNotFoundErr:
-            fprintf(stderr, "XQuartz: Unable to find application for %s\n", kX11AppBundleId);
-            exit(4);
+            fprintf(stderr, "Xquartz: Unable to find application for %s\n", kX11AppBundleId);
+            exit(10);
         default:
-            fprintf(stderr, "XQuartz: Unable to find application for %s, error code = %d\n", 
+            fprintf(stderr, "Xquartz: Unable to find application for %s, error code = %d\n", 
                     kX11AppBundleId, (int)osstatus);
-            exit(5);
+            exit(11);
     }
 }
 
commit 5687d51d7eeb119801e93dbc0d1e91d76ba7b561
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Mon May 12 09:27:27 2008 -0700

    XQuartz: More startup work... listen if we're the actual server
    (cherry picked from commit 3b0afb47c3d8ad922cb2315ed8034f4d77d4a249)

diff --git a/hw/xquartz/mach-startup/bundle-main.c b/hw/xquartz/mach-startup/bundle-main.c
index 24b67d8..b0ff9df 100644
--- a/hw/xquartz/mach-startup/bundle-main.c
+++ b/hw/xquartz/mach-startup/bundle-main.c
@@ -139,6 +139,9 @@ static void startup_trigger_thread(void *arg) {
 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;
 
     for(i=1; i < argc; i++) {
         if(!strcmp(argv[i], "--listenonly")) {
@@ -147,6 +150,11 @@ 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) {
+        mp = checkin_or_register(SERVER_BOOTSTRAP_NAME);
+    }
+
     /* Check if we need to do something other than listen, and make another
      * thread handle it.
      */
@@ -154,23 +162,20 @@ int main(int argc, char **argv, char **envp) {
         struct arg *args = (struct arg*)malloc(sizeof(struct arg));
         if(!args)
             FatalError("Could not allocate memory.\n");
-        
+
         args->argc = argc;
         args->argv = argv;
         args->envp = envp;
 
         create_thread(startup_trigger_thread, args);
-    } else {
-        /* 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.
-         */
-
-        mach_msg_size_t mxmsgsz = sizeof(union MaxMsgSize) + MAX_TRAILER_SIZE;
-        mach_port_t mp = checkin_or_register(SERVER_BOOTSTRAP_NAME);
-        kern_return_t kr;
-        
+    }
+
+    /* 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((argc > 1 && argv[1][0] == ':') || listenOnly) {
         /* Main event loop */
         kr = mach_msg_server(mach_startup_server, mxmsgsz, mp, 0);
         if (kr != KERN_SUCCESS) {
@@ -179,7 +184,7 @@ int main(int argc, char **argv, char **envp) {
             exit(EXIT_FAILURE);
         }
     }
-    
+
     return EXIT_SUCCESS;
 }
 
@@ -208,7 +213,7 @@ int main(int argc, char **argv, char **envp) {
         return server_main(argc, argv, envp);
 #endif
     }
-    
+
     /* If we have a process serial number and it's our only arg, act as if
      * the user double clicked the app bundle: launch app_to_run if possible
      */
@@ -227,7 +232,7 @@ int main(int argc, char **argv, char **envp) {
             return execute(command_from_prefs("app_to_run", DEFAULT_CLIENT));
         }
     }
-    
+
     /* Start the server */
     if((s = getenv("DISPLAY"))) {
         fprintf(stderr, "X11.app: Could not connect to server (DISPLAY=\"%s\", unsetting).  Starting X server.\n", s);
commit 6cb89007361853603e055499814b0dde18074306
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Fri May 9 16:44:31 2008 -0700

    XQuartz: Starting to work on the new Mach IPC startup stuff for better launchd, ApplicationServices, and Dock support
    (cherry picked from commit 9b67fca9b7d3050d3d5582a5210270db7eb2ed05)

diff --git a/.gitignore b/.gitignore
index 00681e7..5b38b1a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -276,6 +276,10 @@ hw/xprint/doc/Xprt.1x
 hw/xprint/doc/Xprt.man
 hw/xprint/dpmsstubs-wrapper.c
 hw/xprint/miinitext-wrapper.c
+hw/xquartz/mach-startup/mach_startup.h
+hw/xquartz/mach-startup/mach_startupServer.c
+hw/xquartz/mach-startup/mach_startupServer.h
+hw/xquartz/mach-startup/mach_startupUser.c
 hw/xquartz/mach-startup/X11
 hw/xquartz/mach-startup/Xquartz
 hw/xquartz/doc/Xquartz.1
diff --git a/hw/xquartz/mach-startup/Makefile.am b/hw/xquartz/mach-startup/Makefile.am
index 9668711..ee2cbfe 100644
--- a/hw/xquartz/mach-startup/Makefile.am
+++ b/hw/xquartz/mach-startup/Makefile.am
@@ -5,9 +5,13 @@ AM_CPPFLAGS = \
 x11appdir = $(APPLE_APPLICATIONS_DIR)/X11.app/Contents/MacOS
 x11app_PROGRAMS = X11
 
-X11_SOURCES = \
+dist_X11_SOURCES = \
 	bundle-main.c
 
+nodist_X11_SOURCES = \
+	mach_startupServer.c \
+	mach_startupUser.c
+
 X11_LDADD = \
 	$(top_builddir)/hw/xquartz/libXquartz.la \
 	$(top_builddir)/hw/xquartz/xpr/libXquartzXpr.la \
@@ -27,8 +31,28 @@ X11_LDFLAGS =  \
 
 bin_PROGRAMS = Xquartz
 
-Xquartz_SOURCES = \
+dist_Xquartz_SOURCES = \
 	stub.c
 
+nodist_Xquartz_SOURCES = \
+	mach_startupUser.c
+
 Xquartz_LDFLAGS =  \
 	-Wl,-framework,CoreServices
+
+BUILT_SOURCES = \
+	mach_startupServer.c \
+	mach_startupUser.c \
+	mach_startupServer.h \
+	mach_startup.h
+
+CLEANFILES = \
+	$(BUILT_SOURCES)
+
+$(BUILT_SOURCES): mach_startup.defs
+	mig -sheader mach_startupServer.h mach_startup.defs
+
+EXTRA_DIST = \
+	mach_startup.defs \
+	mach_startup_types.h
+
diff --git a/hw/xquartz/mach-startup/bundle-main.c b/hw/xquartz/mach-startup/bundle-main.c
index 042fa3a..24b67d8 100644
--- a/hw/xquartz/mach-startup/bundle-main.c
+++ b/hw/xquartz/mach-startup/bundle-main.c
@@ -33,9 +33,16 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <pthread.h>
 
 #include <CoreFoundation/CoreFoundation.h>
 
+#include <mach/mach.h>
+#include <mach/mach_error.h>
+#include <servers/bootstrap.h>
+#include "mach_startup.h"
+#include "mach_startupServer.h"
+
 #define DEFAULT_CLIENT "/usr/X11/bin/xterm"
 #define DEFAULT_STARTX "/usr/X11/bin/startx"
 #define DEFAULT_SHELL  "/bin/sh"
@@ -43,12 +50,146 @@
 static int execute(const char *command);
 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);
 
+struct arg {
+    int argc;
+    char **argv;
+    char **envp;
+};
+
+/*** Mach-O IPC Stuffs ***/
+
+union MaxMsgSize {
+	union __RequestUnion__mach_startup_subsystem req;
+	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) {
+    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;
+
+    /* If we're started by launchd or the old mach_init */
+    kr = bootstrap_check_in(bootstrap_port, bname, &mp);
+    if (kr == KERN_SUCCESS)
+        return mp;
+
+    /* We probably were not started by launchd or the old mach_init */
+    kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp);
+    if (kr != KERN_SUCCESS) {
+        fprintf(stderr, "mach_port_allocate(): %s\n", mach_error_string(kr));
+        exit(EXIT_FAILURE);
+    }
+
+    kr = mach_port_insert_right(mach_task_self(), mp, mp, MACH_MSG_TYPE_MAKE_SEND);
+    if (kr != KERN_SUCCESS) {
+        fprintf(stderr, "mach_port_insert_right(): %s\n", mach_error_string(kr));
+        exit(EXIT_FAILURE);
+    }
+
+    kr = bootstrap_register(bootstrap_port, bname, mp);
+    if (kr != KERN_SUCCESS) {
+        fprintf(stderr, "bootstrap_register(): %s\n", mach_error_string(kr));
+        exit(EXIT_FAILURE);
+    }
+
+    return mp;
+}
+
+/*** Pthread Magics ***/
+static pthread_t create_thread(void *func, void *arg) {
+    pthread_attr_t attr;
+    pthread_t tid;
+	
+    pthread_attr_init (&attr);
+    pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
+    pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+    pthread_create (&tid, &attr, func, arg);
+    pthread_attr_destroy (&attr);
+	
+    return tid;
+}
+
+/*** Main ***/
+static int execute(const char *command);
+static char *command_from_prefs(const char *key, const char *default_value);
+
+#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);
+}
+
 int main(int argc, char **argv, char **envp) {
+    BOOL listenOnly = FALSE;
+    int i;
+
+    for(i=1; i < argc; i++) {
+        if(!strcmp(argv[i], "--listenonly")) {
+            listenOnly = TRUE;
+            break;
+        }
+    }
+
+    /* 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)
+            FatalError("Could not allocate memory.\n");
+        
+        args->argc = argc;
+        args->argv = argv;
+        args->envp = envp;
+
+        create_thread(startup_trigger_thread, args);
+    } else {
+        /* 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.
+         */
+
+        mach_msg_size_t mxmsgsz = sizeof(union MaxMsgSize) + MAX_TRAILER_SIZE;
+        mach_port_t mp = checkin_or_register(SERVER_BOOTSTRAP_NAME);
+        kern_return_t kr;
+        
+        /* 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_SUCCESS;
+}
+
+int startup_trigger(int argc, char **argv, char **envp) {
+#else
+int main(int argc, char **argv, char **envp) {
+#endif
     Display *display;
     const char *s;
-
+    
     size_t i;
     fprintf(stderr, "X11.app: main(): argc=%d\n", argc);
     for(i=0; i < argc; i++) {
@@ -57,7 +198,15 @@ 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] == ':') {
-        exit(server_main(argc, argv, envp));
+#ifdef NEW_LAUNCH_METHOD
+        /* We need to count envp */
+        int envpc;
+        for(envpc=0; envp[envpc]; envpc++);
+
+        return start_x11_server(argc, argv, envp, envpc);
+#else
+        return server_main(argc, argv, envp);
+#endif
     }
     
     /* If we have a process serial number and it's our only arg, act as if
@@ -70,7 +219,7 @@ int main(int argc, char **argv, char **envp) {
             fprintf(stderr, "X11.app: Closing the display and sleeping for 2s to allow the X server to start up.\n");
             /* Could open the display, start the launcher */
             XCloseDisplay(display);
-
+            
             /* Give 2 seconds for the server to start... 
              * TODO: *Really* fix this race condition
              */
@@ -78,7 +227,7 @@ int main(int argc, char **argv, char **envp) {
             return execute(command_from_prefs("app_to_run", DEFAULT_CLIENT));
         }
     }
-
+    
     /* Start the server */
     if((s = getenv("DISPLAY"))) {
         fprintf(stderr, "X11.app: Could not connect to server (DISPLAY=\"%s\", unsetting).  Starting X server.\n", s);
diff --git a/hw/xquartz/mach-startup/mach_startup.defs b/hw/xquartz/mach-startup/mach_startup.defs
new file mode 100644
index 0000000..83b31b7
--- /dev/null
+++ b/hw/xquartz/mach-startup/mach_startup.defs
@@ -0,0 +1,41 @@
+/* Copyright (c) 2008 Apple Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
+ * HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name(s) of the above
+ * copyright holders shall not be used in advertising or otherwise to
+ * promote the sale, use or other dealings in this Software without
+ * prior written authorization.
+ */
+
+#include <mach/std_types.defs>
+#include <mach/mach_types.defs>
+import "mach_startup_types.h";
+
+subsystem mach_startup 1000;
+serverprefix do_;
+
+type string_array_t = array[] of c_string[1024];
+
+routine start_x11_server(
+	port  : mach_port_t;
+    argv  : string_array_t;
+    envp  : string_array_t);
diff --git a/hw/xquartz/mach-startup/mach_startup_types.h b/hw/xquartz/mach-startup/mach_startup_types.h
new file mode 100644
index 0000000..03939af
--- /dev/null
+++ b/hw/xquartz/mach-startup/mach_startup_types.h
@@ -0,0 +1,8 @@
+#ifndef _MACH_STARTUP_TYPES_H_
+#define _MACH_STARTUP_TYPES_H_
+
+#define SERVER_BOOTSTRAP_NAME "org.x.X11"
+
+typedef char ** string_array_t;
+
+#endif


More information about the xorg-commit mailing list