xserver: Branch 'master' - 13 commits

Keith Packard keithp at kemper.freedesktop.org
Fri May 13 13:57:56 PDT 2011


 configure.ac                          |    3 
 hw/xquartz/Makefile.am                |    6 
 hw/xquartz/X11Application.h           |    3 
 hw/xquartz/applewmExt.h               |    6 
 hw/xquartz/console_redirect.c         |  418 ++++++++++++++++++++++++++++++++++
 hw/xquartz/console_redirect.h         |   44 +++
 hw/xquartz/mach-startup/Makefile.am   |    1 
 hw/xquartz/mach-startup/bundle-main.c |   56 ++++
 hw/xquartz/mach-startup/launchd_fd.c  |   18 -
 hw/xquartz/mach-startup/stub.c        |   69 +++--
 hw/xquartz/man/Xquartz.man            |   63 +++--
 hw/xquartz/quartzKeyboard.c           |    6 
 hw/xquartz/sanitizedCocoa.h           |   39 +++
 hw/xquartz/xpr/xprFrame.c             |   20 -
 manpages.am                           |    2 
 os/log.c                              |    7 
 16 files changed, 668 insertions(+), 93 deletions(-)

New commits:
commit 6347a0b802812bb185ada1bf0951add306935184
Merge: 4d02c53... f144fb7...
Author: Keith Packard <keithp at keithp.com>
Date:   Fri May 13 13:54:29 2011 -0700

    Merge remote-tracking branch 'jeremyhu/master'

commit f144fb771f2e0665677aa88d08778899f666a1d5
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Fri May 13 09:10:42 2011 -0700

    XQuartz: Don't circumvent NDEBUG
    
    If someone wants to turn off asserts with NDEBUG, let them.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/quartzKeyboard.c b/hw/xquartz/quartzKeyboard.c
index c540114..e682f08 100644
--- a/hw/xquartz/quartzKeyboard.c
+++ b/hw/xquartz/quartzKeyboard.c
@@ -56,13 +56,7 @@
 
 #include "X11Application.h"
 
-#ifdef NDEBUG
-#undef NDEBUG
 #include <assert.h>
-#define NDEBUG 1
-#else
-#include <assert.h>
-#endif
 #include <pthread.h>
 
 #include "xkbsrv.h"
commit f46835a09662f71f2cb90540609c34561d8af87f
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Wed May 11 15:23:17 2011 -0700

    XQuartz: Redirect stdout/stderr to asl
    
    In order to improve logging in XQuartz, stdout and stderr should be redirected
    to asl (syslog).
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/Makefile.am b/hw/xquartz/Makefile.am
index 76f624d..a7cc012 100644
--- a/hw/xquartz/Makefile.am
+++ b/hw/xquartz/Makefile.am
@@ -33,7 +33,8 @@ libXquartz_la_SOURCES = \
 	quartzCocoa.m \
 	quartzKeyboard.c \
 	quartzStartup.c \
-	quartzRandR.c
+	quartzRandR.c \
+	console_redirect.c
 
 EXTRA_DIST = \
 	X11Application.h \
@@ -49,4 +50,5 @@ EXTRA_DIST = \
 	quartzKeyboard.h \
 	quartzRandR.h \
 	sanitizedCarbon.h \
-	sanitizedCocoa.h
+	sanitizedCocoa.h \
+	console_redirect.h
diff --git a/hw/xquartz/console_redirect.c b/hw/xquartz/console_redirect.c
new file mode 100644
index 0000000..cdd2b89
--- /dev/null
+++ b/hw/xquartz/console_redirect.c
@@ -0,0 +1,418 @@
+/* Copyright (c) 2011 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#else
+#define DEBUG_CONSOLE_REDIRECT 1
+#define HAVE_LIBDISPATCH 1
+#endif
+
+#include <assert.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/event.h>
+#include <asl.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "console_redirect.h"
+
+#define BUF_SIZE 512
+
+#ifdef HAVE_LIBDISPATCH
+#include <dispatch/dispatch.h>
+
+static dispatch_queue_t redirect_serial_q;
+static dispatch_group_t read_source_group;
+#else
+#include <pthread.h>
+
+static pthread_t redirect_pthread;
+static pthread_mutex_t redirect_fds_lock = PTHREAD_MUTEX_INITIALIZER;
+
+static int kq;
+
+/* Notifications to our reader thread */
+#define ASL_REDIRECT_TERMINATE ((void *)(uintptr_t)1)
+#endif
+
+typedef struct {
+    int level;
+    aslclient asl;
+    aslmsg msg;
+
+    /* Buffered reading */
+    char *buf;
+    char *w;
+
+#ifdef HAVE_LIBDISPATCH
+    dispatch_source_t read_source;
+#endif
+} asl_redirect;
+
+static asl_redirect *redirect_fds = NULL;
+static int n_redirect_fds = 0;
+
+/* Read from the FD until there is no more to read and redirect to ASL.
+ * Preconditions:
+ *      1: pthread_mutex_lock lock is held (pthreads) or called
+ *         from the appropriate serial queue for operating on
+ *         redirect_fds
+ *      2: fd corresponds to a valid entry in redirect_fds
+ *
+ * Return values:
+ *      If the pipe is closed, EOF is returned regardless of how many bytes
+ *      were processed.  If the pipe is still open, the number of read bytes
+ *      is returned.
+ */
+static inline int _read_redirect(int fd, int flush) {
+    int total_read = 0;
+    int nbytes;
+    asl_redirect *aslr = &redirect_fds[fd];
+
+    while((nbytes = read(fd, aslr->w, BUF_SIZE - (aslr->w - aslr->buf) - 1)) > 0) {
+        char *s, *p;
+
+        /* Increment our returned number read */
+        total_read += nbytes;
+
+        nbytes += (aslr->w - aslr->buf);
+        aslr->buf[nbytes] = '\0';
+
+        /* One line at a time */
+        for(p=aslr->buf; *p && (p - aslr->buf) < nbytes; p = s + 1) {
+            // Find null or \n
+            for(s=p; *s && *s != '\n'; s++);
+            if(*s == '\n') {
+                *s='\0';
+                asl_log(aslr->asl, aslr->msg, aslr->level, "%s", p);
+            } else if(aslr->buf != p) {
+                memmove(aslr->buf, p, BUF_SIZE);
+                aslr->w = aslr->buf + (s - p);
+                break;
+            } else if(nbytes == BUF_SIZE - 1) {
+                asl_log(aslr->asl, aslr->msg, aslr->level, "%s", p);
+                aslr->w = aslr->buf;
+                break;
+            }
+        }
+    }
+
+    /* Flush if requested or we're at EOF */
+    if(flush || nbytes == 0) {
+        if(aslr->w > aslr->buf) {
+            *aslr->w = '\0';
+            asl_log(aslr->asl, aslr->msg, aslr->level, "%s", aslr->buf);
+        }
+    }
+
+    if(nbytes == 0)
+        return EOF;
+    return total_read;
+}
+
+#ifdef HAVE_LIBDISPATCH
+static void read_from_source(void *_source) {
+    dispatch_source_t source = (dispatch_source_t)_source;
+    int fd = dispatch_source_get_handle(source);
+    if(_read_redirect(fd, 0) == EOF) {
+        dispatch_source_cancel(source);
+    }
+}
+
+static void cancel_source(void *_source) {
+    dispatch_source_t source = (dispatch_source_t)_source;
+    int fd = dispatch_source_get_handle(source);
+    asl_redirect *aslr = &redirect_fds[fd];
+
+    /* Flush the buffer */
+    _read_redirect(fd, 1);
+
+    close(fd);
+    free(aslr->buf);
+    memset(aslr, 0, sizeof(*aslr));
+    dispatch_release(source);
+    dispatch_group_leave(read_source_group);
+}
+
+#else /* !HAVE_LIBDISPATCH */
+static void *redirect_thread(void *ctx __unused) {
+    struct kevent ev;
+    int n;
+
+    while(1) {
+        n = kevent(kq, NULL, 0, &ev, 1, NULL);
+
+        /* Bail on errors */
+        if(n < 0) {
+            asl_log(NULL, NULL, ASL_LEVEL_ERR, "kevent failure: %s", strerror(errno));
+            break;
+        }
+        
+        /* This should not happen */
+        if(n == 0)
+            continue;
+
+        switch(ev.filter) {
+            case EVFILT_READ:
+                pthread_mutex_lock(&redirect_fds_lock);
+                {
+                    int fd = ev.ident;
+                    int close_fd = 0;
+                    asl_redirect *aslr = &redirect_fds[fd];
+
+                    if(fd < 0 || fd >= n_redirect_fds || aslr->buf == NULL) {
+                        asl_log(NULL, NULL, ASL_LEVEL_ERR, "Unexpected file descriptor: %d", fd);
+                        goto next;
+                    }
+
+                    if(ev.flags & EV_EOF) {
+                        close_fd = 1;
+                        if(EOF != _read_redirect(fd, 1)) {
+                            asl_log(NULL, NULL, ASL_LEVEL_ERR, "kevent reported EOF on %d, but read doesn't concur.", fd);
+                        }
+                    } else {
+                        close_fd = (EOF == _read_redirect(fd, 0));
+                    }
+                    
+                    if(close_fd) {
+                        EV_SET(&ev, fd, EVFILT_READ, EV_DELETE, 0, 0, 0);
+                        kevent(kq, &ev, 1, NULL, 0, NULL);
+                        close(fd);
+                        free(aslr->buf);
+                        memset(aslr, 0, sizeof(*aslr));
+                    }
+                }
+                next:
+                pthread_mutex_unlock(&redirect_fds_lock);
+
+            case EVFILT_TIMER:
+                if(ev.udata == ASL_REDIRECT_TERMINATE)
+                    return NULL;
+
+            default:
+                ;;
+        }
+    }
+
+    return NULL;
+}
+#endif
+
+static void redirect_atexit(void) {
+    /* stdout is linebuffered, so flush the buffer */
+    if(redirect_fds[STDOUT_FILENO].buf)
+        fflush(stdout);
+
+#ifdef HAVE_LIBDISPATCH
+    {
+        int i;
+
+        /* Cancel all of our dispatch sources, so they flush to ASL */
+        for(i=0; i < n_redirect_fds; i++)
+            if(redirect_fds[i].read_source)
+                dispatch_source_cancel(redirect_fds[i].read_source);
+
+        /* Wait at least three seconds for our sources to flush to ASL */
+        dispatch_group_wait(read_source_group, dispatch_time(DISPATCH_TIME_NOW, 3LL * NSEC_PER_SEC));
+    }
+#else
+    {
+        struct kevent ev;
+
+        /* Tell our reader thread it is time to pack up and go home */
+        EV_SET(&ev, 0, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 0, ASL_REDIRECT_TERMINATE);
+        kevent(kq, &ev, 1, NULL, 0, NULL);
+    
+        pthread_join(redirect_pthread, NULL);
+    }
+#endif
+}
+
+#ifdef HAVE_LIBDISPATCH
+static void xq_asl_init(void *ctx __unused)
+#else
+static void xq_asl_init(void)
+#endif
+{
+    assert((redirect_fds = calloc(16, sizeof(*redirect_fds))) != NULL);
+    n_redirect_fds = 16;
+
+#ifdef HAVE_LIBDISPATCH
+    redirect_serial_q = dispatch_queue_create("com.apple.asl-redirect", NULL);
+    assert(redirect_serial_q != NULL);
+
+    read_source_group = dispatch_group_create();
+    assert(read_source_group != NULL);
+#else
+    assert((kq = kqueue()) != -1);
+    assert(pthread_create(&redirect_pthread, NULL, redirect_thread, NULL) == 0);
+#endif
+
+    atexit(redirect_atexit);
+}
+
+int xq_asl_log_fd(aslclient asl, aslmsg msg, int level, int fd) {
+#ifdef HAVE_LIBDISPATCH
+    int err __block = 0;
+    static dispatch_once_t once_control;
+    dispatch_once_f(&once_control, NULL, xq_asl_init);
+#else
+    int err = 0;
+    static pthread_once_t once_control = PTHREAD_ONCE_INIT;
+    assert(pthread_once(&once_control, xq_asl_init) == 0);
+#endif
+    
+    if(fd < 0)
+        return EBADF;
+    
+#ifdef HAVE_LIBDISPATCH
+#define BLOCK_DONE return
+    dispatch_sync(redirect_serial_q, ^
+#else
+#define BLOCK_DONE goto done
+    assert(pthread_mutex_lock(&redirect_fds_lock) == 0);
+#endif
+    {
+        /* Reallocate if we need more space */
+        if(fd >= n_redirect_fds) {
+            size_t new_n = 1 << (ffs(fd) + 1);
+            asl_redirect *new_array = realloc(redirect_fds, new_n * sizeof(*redirect_fds));
+            if(!new_array) {
+                err = errno;
+                BLOCK_DONE;
+            }
+            redirect_fds = new_array;
+            memset(redirect_fds + n_redirect_fds, 0, new_n - n_redirect_fds);
+            n_redirect_fds = new_n;
+        }
+        
+        /* If we're already listening on it, return error. */
+        if(redirect_fds[fd].buf != NULL) {
+            err = EBADF;
+            BLOCK_DONE;
+        }
+        
+        /* Initialize our buffer */
+        redirect_fds[fd].buf = (char *)malloc(BUF_SIZE);
+        if(redirect_fds[fd].buf == NULL) {
+            err = errno;
+            BLOCK_DONE;
+        }
+        redirect_fds[fd].w = redirect_fds[fd].buf;
+        
+        /* Store our ASL settings */
+        redirect_fds[fd].level = level;
+        redirect_fds[fd].asl = asl;
+        redirect_fds[fd].msg = msg;
+        
+        /* Don't block on reads from this fd */
+        fcntl(fd, F_SETFL, O_NONBLOCK);
+        
+        /* Start listening */
+#ifdef HAVE_LIBDISPATCH
+        {
+            dispatch_source_t read_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, fd, 0, redirect_serial_q);
+            redirect_fds[fd].read_source = read_source;
+            dispatch_set_context(read_source, read_source);
+            dispatch_source_set_event_handler_f(read_source, read_from_source);
+            dispatch_source_set_cancel_handler_f(read_source, cancel_source);
+            dispatch_group_enter(read_source_group);
+            dispatch_resume(read_source);
+        }
+#else
+        {
+            struct kevent ev;
+            EV_SET(&ev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
+            kevent(kq, &ev, 1, NULL, 0, NULL);
+        }
+#endif
+    }
+#ifdef HAVE_LIBDISPATCH
+    );
+#else
+done:
+    assert(pthread_mutex_unlock(&redirect_fds_lock) == 0);
+#endif
+#undef BLOCK_DONE
+    
+    return err;
+}
+
+int xq_asl_capture_fd(aslclient asl, aslmsg msg, int level, int fd) {
+    int pipepair[2];
+    
+    /* Create pipe */
+    if(pipe(pipepair) == -1)
+        return errno;
+    
+    /* Close the read fd but not the write fd on exec */
+    if(fcntl(pipepair[0], F_SETFD, FD_CLOEXEC) == -1)
+        return errno;
+
+    /* Replace the existing fd */
+    if(dup2(pipepair[1], fd) == -1) {
+        close(pipepair[0]);
+        close(pipepair[1]);
+        return errno;
+    }
+
+    /* If we capture STDOUT_FILENO, make sure we linebuffer stdout */
+    if(fd == STDOUT_FILENO)
+        setlinebuf(stdout);
+    
+    /* Close the duplicate fds since they've been reassigned */
+    close(pipepair[1]);
+
+    /* Hand off the read end of our pipe to xq_asl_log_fd */
+    return xq_asl_log_fd(asl, msg, level, pipepair[0]);
+}
+
+#ifdef DEBUG_CONSOLE_REDIRECT
+int main(int argc __unused, char **argv __unused) {
+    xq_asl_capture_fd(NULL, NULL, ASL_LEVEL_NOTICE, STDOUT_FILENO);
+    xq_asl_capture_fd(NULL, NULL, ASL_LEVEL_ERR, STDERR_FILENO);
+
+    fprintf(stderr, "TEST ERR1\n");
+    fprintf(stdout, "TEST OUT1\n");
+    fprintf(stderr, "TEST ERR2\n");
+    fprintf(stdout, "TEST OUT2\n");
+    system("/bin/echo SYST OUT");
+    system("/bin/echo SYST ERR >&2");
+    fprintf(stdout, "TEST OUT3\n");
+    fprintf(stdout, "TEST OUT4\n");
+    fprintf(stderr, "TEST ERR3\n");
+    fprintf(stderr, "TEST ERR4\n");
+
+    exit(0);
+}
+#endif
diff --git a/hw/xquartz/console_redirect.h b/hw/xquartz/console_redirect.h
new file mode 100644
index 0000000..94520a3
--- /dev/null
+++ b/hw/xquartz/console_redirect.h
@@ -0,0 +1,44 @@
+/* Copyright (c) 2011 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.
+ */
+
+#ifndef _XQUARTZ_CONSOLE_REDIRECT_H_
+#define _XQUARTZ_CONSOLE_REDIRECT_H_
+
+#include <asl.h>
+
+/* The given fd is replaced with a pipe.  Anything written to it will will be
+ * logged to ASL.
+ */
+int xq_asl_capture_fd(aslclient asl, aslmsg msg, int level, int fd);
+
+/* The given fd is read from and passed along to ASL until all write ends of the
+ * pipe are closed. Once the last writer has closed the pipe, we close our end.
+ */
+int xq_asl_log_fd(aslclient asl, aslmsg msg, int level, int fd);
+
+#endif
diff --git a/hw/xquartz/mach-startup/Makefile.am b/hw/xquartz/mach-startup/Makefile.am
index 4dff45a..1ce54ad 100644
--- a/hw/xquartz/mach-startup/Makefile.am
+++ b/hw/xquartz/mach-startup/Makefile.am
@@ -1,4 +1,5 @@
 AM_CPPFLAGS = \
+	-I$(srcdir)/.. \
 	-DBUILD_DATE=\"$(BUILD_DATE)\" \
 	-DXSERVER_VERSION=\"$(VERSION)\" \
 	-DX11BINDIR=\"$(bindir)\"
diff --git a/hw/xquartz/mach-startup/bundle-main.c b/hw/xquartz/mach-startup/bundle-main.c
index c54affb..8e34376 100644
--- a/hw/xquartz/mach-startup/bundle-main.c
+++ b/hw/xquartz/mach-startup/bundle-main.c
@@ -61,7 +61,8 @@
 #include "mach_startup.h"
 #include "mach_startupServer.h"
 
-#include "launchd_fd.h"
+#include "console_redirect.h"
+
 /* From darwinEvents.c ... but don't want to pull in all the server cruft */
 void DarwinListenOnOpenFD(int fd);
 
@@ -481,6 +482,28 @@ static void ensure_path(const char *dir) {
     }
 }
 
+static void setup_console_redirect(const char *bundle_id) {
+    char *asl_sender;
+    char *asl_facility;
+    aslclient aslc;
+
+    asprintf(&asl_sender, "%s.server", bundle_id);
+    assert(asl_sender);
+
+    asl_facility = strdup(bundle_id);
+    assert(asl_facility);
+    if(strcmp(asl_facility + strlen(asl_facility) - 4, ".X11") == 0)
+        asl_facility[strlen(asl_facility) - 4] = '\0';
+
+    assert(aslc = asl_open(asl_sender, asl_facility, ASL_OPT_NO_DELAY));
+    free(asl_sender);
+    free(asl_facility);
+
+    asl_set_filter(aslc, ASL_FILTER_MASK_UPTO(ASL_LEVEL_WARNING));
+    xq_asl_capture_fd(aslc, NULL, ASL_LEVEL_INFO, STDOUT_FILENO);
+    xq_asl_capture_fd(aslc, NULL, ASL_LEVEL_NOTICE, STDERR_FILENO);
+}
+
 static void setup_env(void) {
     char *temp;
     const char *pds = NULL;
@@ -503,6 +526,8 @@ static void setup_env(void) {
         pds = BUNDLE_ID_PREFIX".X11";
     }
 
+    setup_console_redirect(pds);
+
     server_bootstrap_name = strdup(pds);
     if(!server_bootstrap_name) {
         ErrorF("X11.app: Memory allocation error.\n");
commit 5bc05d96f883add324bab338ffb9b9409cf45b2c
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Thu May 12 15:45:29 2011 -0700

    XQuartz: Add a LOGGING section to our man page
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/man/Xquartz.man b/hw/xquartz/man/Xquartz.man
index ad5ce28..19e8efb 100644
--- a/hw/xquartz/man/Xquartz.man
+++ b/hw/xquartz/man/Xquartz.man
@@ -102,9 +102,32 @@ Same as fake_button3 above.
 .TP 8
 .B "\-depth \fIdepth\fP"
 Same as depth above.
+.SH LOGGING
+XQuartz stores a server log at ~/Library/Logs/X11.__bundle_id_prefix__.log which
+is analogous to /var/log/Xorg.#.log on systems that use the XFree86 DDX such as
+Linux, BSD, and Solaris.
+.PP
+In addition to this server log, XQuartz sends messages to syslogd(8) using
+asl(3).  These logs are sent to the __bundle_id_prefix__ facility, and you can
+watch these logs using the following syslog(1) command:
+.TP 8
+.B $ syslog -w -k Facility __bundle_id_prefix__
+.PP
+By default, XQaurtz sets an ASL mask which prevents it from logging messages
+below the ASL_LEVEL_WARNING level (meaning almost all logging is done strictly
+to the file referenced above).  To force XQuartz to send all log messages to
+syslogd(8), you can adjust this mask using the following syslog(1) command:
+.TP 8
+.B $ syslog -c X11.bin -d
+.PP
+The stdout and stderr messages printed by any process launched by XQuartz will
+be redirected to this syslog facility with a priority level of ASL_LEVEL_INFO
+and ASL_LEVEL_NOTICE respectively.  In order to see these messages in syslog,
+you will need to adjust XQuartz's asl mask as above but using -i or -n
+instead of -d.
 .SH "SEE ALSO"
 .PP
-X(__miscmansuffix__), Xserver(1), xdm(1), xinit(1)
+X(__miscmansuffix__), Xserver(1), xdm(1), xinit(1), syslog(1), syslogd(8)
 .PP
 http://xquartz.macosforge.org
 .PP
commit c18b7165f971cbf6b634ccf670eb4aa9840eb9e4
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Thu May 12 18:29:23 2011 -0700

    XQuartz: stub: Log directly to ASL rather than stdout/stderr
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/mach-startup/launchd_fd.c b/hw/xquartz/mach-startup/launchd_fd.c
index 5c7e03c..8003dd1 100644
--- a/hw/xquartz/mach-startup/launchd_fd.c
+++ b/hw/xquartz/mach-startup/launchd_fd.c
@@ -31,41 +31,43 @@
 #endif
 
 #include <launch.h>
-#include <stdio.h>
+#include <asl.h>
 #include <errno.h>
 
 #include "launchd_fd.h"
 
+extern aslclient aslc;
+
 int launchd_display_fd(void) {
     launch_data_t sockets_dict, checkin_request, checkin_response;
     launch_data_t listening_fd_array, listening_fd;
 
     /* Get launchd fd */
     if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == NULL) {
-        fprintf(stderr,"launch_data_new_string(\"" LAUNCH_KEY_CHECKIN "\") Unable to create string.\n");
+        asl_log(aslc, NULL, ASL_LEVEL_ERR, "launch_data_new_string(\"" LAUNCH_KEY_CHECKIN "\") Unable to create string.\n");
         return ERROR_FD;
     }
     
     if ((checkin_response = launch_msg(checkin_request)) == NULL) {
-        fprintf(stderr,"launch_msg(\"" LAUNCH_KEY_CHECKIN "\") IPC failure: %s\n",strerror(errno));
+        asl_log(aslc, NULL, ASL_LEVEL_WARNING, "launch_msg(\"" LAUNCH_KEY_CHECKIN "\") IPC failure: %s\n",strerror(errno));
         return ERROR_FD;
     }
     
     if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) {
         // ignore EACCES, which is common if we weren't started by launchd
         if (launch_data_get_errno(checkin_response) != EACCES)
-            fprintf(stderr,"launchd check-in failed: %s\n", strerror(launch_data_get_errno(checkin_response)));
+            asl_log(aslc, NULL, ASL_LEVEL_ERR, "launchd check-in failed: %s\n", strerror(launch_data_get_errno(checkin_response)));
         return ERROR_FD;
     } 
     
     sockets_dict = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_SOCKETS);
     if (NULL == sockets_dict) {
-        fprintf(stderr,"launchd check-in: no sockets found to answer requests on!\n");
+        asl_log(aslc, NULL, ASL_LEVEL_ERR, "launchd check-in: no sockets found to answer requests on!\n");
         return ERROR_FD;
     }
     
     if (launch_data_dict_get_count(sockets_dict) > 1) {
-        fprintf(stderr,"launchd check-in: some sockets will be ignored!\n");
+        asl_log(aslc, NULL, ASL_LEVEL_ERR, "launchd check-in: some sockets will be ignored!\n");
         return ERROR_FD;
     }
     
@@ -73,13 +75,13 @@ int launchd_display_fd(void) {
     if (NULL == listening_fd_array) {
         listening_fd_array = launch_data_dict_lookup(sockets_dict, ":0");
         if (NULL == listening_fd_array) {
-            fprintf(stderr,"launchd check-in: No known sockets found to answer requests on! \"%s:0\" and \":0\" failed.\n", BUNDLE_ID_PREFIX);
+            asl_log(aslc, NULL, ASL_LEVEL_ERR, "launchd check-in: No known sockets found to answer requests on! \"%s:0\" and \":0\" failed.\n", BUNDLE_ID_PREFIX);
             return ERROR_FD;
         }
     }
     
     if (launch_data_array_get_count(listening_fd_array)!=1) {
-        fprintf(stderr,"launchd check-in: Expected 1 socket from launchd, got %u)\n",
+        asl_log(aslc, NULL, ASL_LEVEL_ERR, "launchd check-in: Expected 1 socket from launchd, got %u)\n",
                 (unsigned)launch_data_array_get_count(listening_fd_array));
         return ERROR_FD;
     }
diff --git a/hw/xquartz/mach-startup/stub.c b/hw/xquartz/mach-startup/stub.c
index c8a6283..8319dd0 100644
--- a/hw/xquartz/mach-startup/stub.c
+++ b/hw/xquartz/mach-startup/stub.c
@@ -33,9 +33,9 @@
 #endif
 
 #include <string.h>
-#include <stdio.h>
 #include <unistd.h>
 #include <errno.h>
+#include <asl.h>
 
 #include <sys/socket.h>
 #include <sys/un.h>
@@ -43,8 +43,6 @@
 #define kX11AppBundleId BUNDLE_ID_PREFIX".X11"
 #define kX11AppBundlePath "/Contents/MacOS/X11"
 
-static char *server_bootstrap_name = kX11AppBundleId;
-
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 #include <servers/bootstrap.h>
@@ -57,8 +55,8 @@ static char *server_bootstrap_name = kX11AppBundleId;
 #include "launchd_fd.h"
 
 static char x11_path[PATH_MAX + 1];
-
 static pid_t x11app_pid = 0;
+aslclient aslc;
 
 static void set_x11_path(void) {
 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
@@ -69,26 +67,24 @@ static void set_x11_path(void) {
     switch (osstatus) {
         case noErr:
             if (appURL == NULL) {
-                fprintf(stderr, "Xquartz: Invalid response from LSFindApplicationForInfo(%s)\n", 
+                asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: Invalid response from LSFindApplicationForInfo(%s)", 
                         kX11AppBundleId);
                 exit(1);
             }
 
             if (!CFURLGetFileSystemRepresentation(appURL, true, (unsigned char *)x11_path, sizeof(x11_path))) {
-                fprintf(stderr, "Xquartz: Error resolving URL for %s\n", kX11AppBundleId);
+                asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: Error resolving URL for %s", kX11AppBundleId);
                 exit(3);
             }
 
             strlcat(x11_path, kX11AppBundlePath, sizeof(x11_path));
-#ifdef DEBUG
-            fprintf(stderr, "Xquartz: X11.app = %s\n", x11_path);
-#endif
+            asl_log(aslc, NULL, ASL_LEVEL_INFO, "Xquartz: X11.app = %s", x11_path);
             break;
         case kLSApplicationNotFoundErr:
-            fprintf(stderr, "Xquartz: Unable to find application for %s\n", kX11AppBundleId);
+            asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: Unable to find application for %s", kX11AppBundleId);
             exit(10);
         default:
-            fprintf(stderr, "Xquartz: Unable to find application for %s, error code = %d\n", 
+            asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: Unable to find application for %s, error code = %d", 
                     kX11AppBundleId, (int)osstatus);
             exit(11);
     }
@@ -114,12 +110,12 @@ static int connect_to_socket(const char *filename) {
     
     ret_fd = socket(PF_UNIX, SOCK_STREAM, 0);
     if(ret_fd == -1) {
-        fprintf(stderr, "Xquartz: Failed to create socket: %s - %s\n", filename, strerror(errno));
+        asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: Failed to create socket: %s - %s", filename, strerror(errno));
         return -1;
     }
 
     if(connect(ret_fd, servaddr, servaddr_len) < 0) {
-        fprintf(stderr, "Xquartz: Failed to connect to socket: %s - %d - %s\n", filename, errno, strerror(errno));
+        asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: Failed to connect to socket: %s - %d - %s", filename, errno, strerror(errno));
         close(ret_fd);
         return -1;
     }
@@ -160,14 +156,11 @@ static void send_fd_handoff(int connected_fd, int launchd_fd) {
     *((int*)CMSG_DATA(cmsg)) = launchd_fd;
     
     if(sendmsg(connected_fd, &msg, 0) < 0) {
-        fprintf(stderr, "Xquartz: Error sending $DISPLAY file descriptor over fd %d: %d -- %s\n", connected_fd, errno, strerror(errno));
+        asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: Error sending $DISPLAY file descriptor over fd %d: %d -- %s", connected_fd, errno, strerror(errno));
         return;
     }
 
-#ifdef DEBUG
-    fprintf(stderr, "Xquartz: Message sent.  Closing handoff fd.\n");
-#endif
-
+    asl_log(aslc, NULL, ASL_LEVEL_DEBUG, "Xquartz: Message sent.  Closing handoff fd.");
     close(connected_fd);
 }
 
@@ -187,10 +180,25 @@ int main(int argc, char **argv, char **envp) {
     int launchd_fd;
     string_t handoff_socket_filename;
     sig_t handler;
+    char *asl_sender;
+    char *asl_facility;
+    char *server_bootstrap_name = kX11AppBundleId;
 
     if(getenv("X11_PREFS_DOMAIN"))
         server_bootstrap_name = getenv("X11_PREFS_DOMAIN");
-    
+
+    asprintf(&asl_sender, "%s.stub", server_bootstrap_name);
+    assert(asl_sender);
+
+    asl_facility = strdup(server_bootstrap_name);
+    assert(asl_facility);
+    if(strcmp(asl_facility + strlen(asl_facility) - 4, ".X11") == 0)
+        asl_facility[strlen(asl_facility) - 4] = '\0';    
+
+    assert(aslc = asl_open(asl_sender, asl_facility, ASL_OPT_NO_DELAY));
+    free(asl_sender);
+    free(asl_facility);
+
     /* We don't have a mechanism in place to handle this interrupt driven
      * server-start notification, so just send the signal now, so xinit doesn't
      * time out waiting for it and will just poll for the server.
@@ -211,13 +219,13 @@ int main(int argc, char **argv, char **envp) {
     if(kr != KERN_SUCCESS) {
         pid_t child;
 
-        fprintf(stderr, "Xquartz: Unable to locate waiting server: %s\n", server_bootstrap_name);
+        asl_log(aslc, NULL, ASL_LEVEL_WARNING, "Xquartz: Unable to locate waiting server: %s", server_bootstrap_name);
         set_x11_path();
 
         /* This forking is ugly and will be cleaned up later */
         child = fork();
         if(child == -1) {
-            fprintf(stderr, "Xquartz: Could not fork: %s\n", strerror(errno));
+            asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: Could not fork: %s", strerror(errno));
             return EXIT_FAILURE;
         }
 
@@ -226,7 +234,7 @@ int main(int argc, char **argv, char **envp) {
             _argv[0] = x11_path;
             _argv[1] = "--listenonly";
             _argv[2] = NULL;
-            fprintf(stderr, "Xquartz: Starting X server: %s --listenonly\n", x11_path);
+            asl_log(aslc, NULL, ASL_LEVEL_NOTICE, "Xquartz: Starting X server: %s --listenonly", x11_path);
             return execvp(x11_path, _argv);
         }
 
@@ -240,9 +248,9 @@ int main(int argc, char **argv, char **envp) {
 
         if(kr != KERN_SUCCESS) {
 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
-            fprintf(stderr, "Xquartz: bootstrap_look_up(): %s\n", bootstrap_strerror(kr));
+            asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: bootstrap_look_up(): %s", bootstrap_strerror(kr));
 #else
-            fprintf(stderr, "Xquartz: bootstrap_look_up(): %ul\n", (unsigned long)kr);
+            asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: bootstrap_look_up(): %ul", (unsigned long)kr);
 #endif
             return EXIT_FAILURE;
         }
@@ -258,20 +266,17 @@ int main(int argc, char **argv, char **envp) {
 
         for(try=0, try_max=5; try < try_max; try++) {
             if(request_fd_handoff_socket(mp, handoff_socket_filename) != KERN_SUCCESS) {
-                fprintf(stderr, "Xquartz: Failed to request a socket from the server to send the $DISPLAY fd over (try %d of %d)\n", (int)try+1, (int)try_max);
+                asl_log(aslc, NULL, ASL_LEVEL_INFO, "Xquartz: Failed to request a socket from the server to send the $DISPLAY fd over (try %d of %d)", (int)try+1, (int)try_max);
                 continue;
             }
 
             handoff_fd = connect_to_socket(handoff_socket_filename);
             if(handoff_fd == -1) {
-                fprintf(stderr, "Xquartz: Failed to connect to socket (try %d of %d)\n", (int)try+1, (int)try_max);
+                asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: Failed to connect to socket (try %d of %d)", (int)try+1, (int)try_max);
                 continue;
             }
 
-#ifdef DEBUG
-            fprintf(stderr, "Xquartz: Handoff connection established (try %d of %d) on fd %d, \"%s\".  Sending message.\n", (int)try+1, (int)try_max, handoff_fd, handoff_socket_filename);
-#endif
-
+            asl_log(aslc, NULL, ASL_LEVEL_INFO, "Xquartz: Handoff connection established (try %d of %d) on fd %d, \"%s\".  Sending message.", (int)try+1, (int)try_max, handoff_fd, handoff_socket_filename);
             send_fd_handoff(handoff_fd, launchd_fd);            
             close(handoff_fd);
             break;
@@ -288,7 +293,7 @@ int main(int argc, char **argv, char **envp) {
     newenvp = (string_array_t)calloc((1 + envpc), sizeof(string_t));
 
     if(!newargv || !newenvp) {
-        fprintf(stderr, "Xquartz: Memory allocation failure\n");
+        asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: Memory allocation failure");
         return EXIT_FAILURE;
     }
     
@@ -305,7 +310,7 @@ int main(int argc, char **argv, char **envp) {
     free(newenvp);
 
     if (kr != KERN_SUCCESS) {
-        fprintf(stderr, "Xquartz: start_x11_server: %s\n", mach_error_string(kr));
+        asl_log(aslc, NULL, ASL_LEVEL_ERR, "Xquartz: start_x11_server: %s", mach_error_string(kr));
         return EXIT_FAILURE;
     }
     return EXIT_SUCCESS;
commit d694601591d2a86a437c5150015d9889e2fe16fc
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Thu May 12 15:15:40 2011 -0700

    Fix a typo: laucnd instead of launchd
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/man/Xquartz.man b/hw/xquartz/man/Xquartz.man
index 4471947..ad5ce28 100644
--- a/hw/xquartz/man/Xquartz.man
+++ b/hw/xquartz/man/Xquartz.man
@@ -16,72 +16,72 @@ OS X handles the desktop background.
 .SH CUSTOMIZATION
 \fIXquartz\fP can be customized using the defaults(1) command. The available options are:
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 enable_fake_buttons -boolean true
+.B defaults write __bundle_id_prefix__.X11 enable_fake_buttons -boolean true
 Emulates a 3 button mouse using modifier keys. By default, the Command modifier
 is used to emulate button 2 and Option is used for button 3. Thus, clicking the
 first mouse button while holding down Command will act like clicking
 button 2. Holding down Option will simulate button 3.
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 fake_button2 \fImodifiers\fP
+.B defaults write __bundle_id_prefix__.X11 fake_button2 \fImodifiers\fP
 Change the modifier keys used to emulate the second mouse button. By default,
 Command is used to emulate the second button. Any combination of the following
 modifier names may be used: {l,r,}shift, {l,r,}option, {l,r,}control, {l,r,}command, fn
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 fake_button3 \fImodifiers\fP
+.B defaults write __bundle_id_prefix__.X11 fake_button3 \fImodifiers\fP
 Change the modifier keys used to emulate the second mouse button. By default,
 Command is used to emulate the second button. Any combination of the following
 modifier names may be used: {l,r,}shift, {l,r,}option, {l,r,}control, {l,r,}command, fn
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 fullscreen_hotkeys -boolean true
+.B defaults write __bundle_id_prefix__.X11 fullscreen_hotkeys -boolean true
 Enable OSX hotkeys while in fullscreen
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 fullscreen_menu -boolean true
+.B defaults write __bundle_id_prefix__.X11 fullscreen_menu -boolean true
 Show the OSX menu while in fullscreen
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 no_quit_alert -boolean true
+.B defaults write __bundle_id_prefix__.X11 no_quit_alert -boolean true
 Disables the alert dialog displayed when attempting to quit X11.
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 no_auth -boolean true
+.B defaults write __bundle_id_prefix__.X11 no_auth -boolean true
 Stops the X server requiring that clients authenticate themselves when
 connecting.  See Xsecurity(__miscmansuffix__).
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 nolisten_tcp -boolean false
+.B defaults write __bundle_id_prefix__.X11 nolisten_tcp -boolean false
 This will tell the server to listen and accept TCP connections.  Doing this without enabling
 xauth is a possible security concern.  See Xsecurity(__miscmansuffix__).
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 enable_system_beep -boolean false
+.B defaults write __bundle_id_prefix__.X11 enable_system_beep -boolean false
 Don't use the standard system beep effect for X11 alerts.
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 enable_key_equivalents -boolean false
+.B defaults write __bundle_id_prefix__.X11 enable_key_equivalents -boolean false
 Disable menu keyboard equivalents while X11 windows are focused.
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 depth \fIdepth\fP
+.B defaults write __bundle_id_prefix__.X11 depth \fIdepth\fP
 Specifies the color bit depth to use. Currently only 15, and 24 color
 bits per pixel are supported. If not specified, or a value of -1 is specified,
 defaults to the depth of the main display.
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 sync_keymap -boolean true
+.B defaults write __bundle_id_prefix__.X11 sync_keymap -boolean true
 Keep the X11 keymap up to date with the OSX system keymap.
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 option_sends_alt -boolean true
+.B defaults write __bundle_id_prefix__.X11 option_sends_alt -boolean true
 The Option key will send Alt_L and Alt_R instead of Mode_switch.
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 sync_pasteboard -boolean true
+.B defaults write __bundle_id_prefix__.X11 sync_pasteboard -boolean true
 Enable syncing between the OSX pasteboard and clipboard/primary selection buffers in X11.  This option needs to be true for any of the other pasteboard sync options to have an effect.
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 sync_pasteboard_to_clipboard -boolean true
+.B defaults write __bundle_id_prefix__.X11 sync_pasteboard_to_clipboard -boolean true
 Update the X11 CLIPBOARD when the OSX NSPasteboard is updated.
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 sync_pasteboard_to_primary -boolean true
+.B defaults write __bundle_id_prefix__.X11 sync_pasteboard_to_primary -boolean true
 Update the the X11 PRIMARY buffer when the OSX NSPasteboard is updated.
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 sync_clipboard_to_pasteboard -boolean true
+.B defaults write __bundle_id_prefix__.X11 sync_clipboard_to_pasteboard -boolean true
 Update the the OSX NSPasteboard when the X11 CLIPBOARD is updated.  Note that enabling this option causes the clipboard synchronization to act as a clipboard manager in X11.  This makes it impossible to use xclipboard, klipper, or any other such clipboard managers.  If you want to use any of these programs, you must disable this option.
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 sync_primary_on_select -boolean true
+.B defaults write __bundle_id_prefix__.X11 sync_primary_on_select -boolean true
 This option defaults to false and is provided only "for experts."  It updates the NSPasteboard whenever a new X11 selection is made (rather than requiring you to hit cmd-c to copy the selection to the NSPasteboard).  Since the X11 protocol does not require applications to send notification when they change selection, this might not work in all cases (if you run into this problem, try selecting text in another application first, then selecting the text you want).
 .TP 8
-.B defaults write __laucnd_id_prefix__.X11 enable_test_extensions -boolean true
+.B defaults write __bundle_id_prefix__.X11 enable_test_extensions -boolean true
 This option defaults to false and is only accessible through the command line.  Enable this option to turn on the DEC-XTRAP, RECORD, and XTEST extensions in the server.
 .SH OPTIONS
 .PP
diff --git a/manpages.am b/manpages.am
index 03089e3..ea969cc 100644
--- a/manpages.am
+++ b/manpages.am
@@ -24,7 +24,7 @@ MAN_SUBSTS += 	-e 's|__logdir__|$(logdir)|g' \
 		-e 's|__sysconfdir__|$(sysconfdir)|g' \
 		-e 's|__xconfigdir__|$(__XCONFIGDIR__)|g' \
 		-e 's|__xkbdir__|$(XKB_BASE_DIRECTORY)|g' \
-		-e 's|__laucnd_id_prefix__|$(BUNDLE_ID_PREFIX)|g' \
+		-e 's|__bundle_id_prefix__|$(BUNDLE_ID_PREFIX)|g' \
 		-e 's|__modulepath__|$(DEFAULT_MODULE_PATH)|g' \
 		-e 's|__default_font_path__|$(COMPILEDDEFAULTFONTPATH)|g' \
 		-e '\|$(COMPILEDDEFAULTFONTPATH)| s|/,|/, |g'
commit a558a66d249cd51d3d675b20cc3a76651fd87930
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Wed May 11 17:27:52 2011 -0700

    configure.ac: XQuartz: Fix support for the deprecated --with-launchd-id-prefix
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/configure.ac b/configure.ac
index 61caaed..a474073 100644
--- a/configure.ac
+++ b/configure.ac
@@ -566,8 +566,7 @@ AC_ARG_WITH(launchd-id-prefix,  AS_HELP_STRING([--with-launchd-id-prefix=PATH],
                                 [ BUNDLE_ID_PREFIX="${withval}" ],
                                 [ BUNDLE_ID_PREFIX="org.x" ])
 AC_ARG_WITH(bundle-id-prefix,  AS_HELP_STRING([--with-bundle-id-prefix=PATH], [Prefix to use for bundle identifiers (default: org.x)]),
-                               [ BUNDLE_ID_PREFIX="${withval}" ],
-                               [ BUNDLE_ID_PREFIX="org.x" ])
+                               [ BUNDLE_ID_PREFIX="${withval}" ])
 AC_SUBST([BUNDLE_ID_PREFIX])
 AC_DEFINE_UNQUOTED(BUNDLE_ID_PREFIX, "$BUNDLE_ID_PREFIX", [Prefix to use for bundle identifiers])
 AC_ARG_ENABLE(sparkle,AS_HELP_STRING([--enable-sparkle], [Enable updating of X11.app using the Sparkle Framework (default: disabled)]),
commit c89a6f824eaf647d2b182f79fbd78f5bd1c3a27f
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Tue May 10 23:42:46 2011 -0700

    XQuartz: Don't call into CoreFoundation after fork() and before exec()
    
    After fork()ing, we should just limit ourselves to setting up
    the environment, file descriptors, and exec()ing.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/mach-startup/bundle-main.c b/hw/xquartz/mach-startup/bundle-main.c
index 846025b..c54affb 100644
--- a/hw/xquartz/mach-startup/bundle-main.c
+++ b/hw/xquartz/mach-startup/bundle-main.c
@@ -36,6 +36,7 @@
 #endif
 
 #include <X11/Xlib.h>
+#include <assert.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <string.h>
@@ -66,6 +67,7 @@ void DarwinListenOnOpenFD(int fd);
 
 /* Ditto, from os/log.c */
 extern void ErrorF(const char *f, ...) _X_ATTRIBUTE_PRINTF(1,2);
+extern void FatalError(const char *f, ...) _X_ATTRIBUTE_PRINTF(1,2) _X_NORETURN;
 
 extern int noPanoramiXExtension;
 
@@ -102,6 +104,10 @@ 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);
 
+static char *pref_app_to_run;
+static char *pref_login_shell;
+static char *pref_startx_script;
+
 #ifndef HAVE_LIBDISPATCH
 /*** Pthread Magics ***/
 static pthread_t create_thread(void *(*func)(void *), void *arg) {
@@ -446,7 +452,7 @@ static int startup_trigger(int argc, char **argv, char **envp) {
             /* Could open the display, start the launcher */
             XCloseDisplay(display);
 
-            return execute(command_from_prefs("app_to_run", DEFAULT_CLIENT));
+            return execute(pref_app_to_run);
         }
     }
 
@@ -457,7 +463,7 @@ static int startup_trigger(int argc, char **argv, char **envp) {
     } else {
         ErrorF("X11.app: Could not connect to server (DISPLAY is not set).  Starting X server.\n");
     }
-    return execute(command_from_prefs("startx_script", DEFAULT_STARTX));
+    return execute(pref_startx_script);
 }
 
 /** Setup the environment we want our child processes to inherit */
@@ -594,11 +600,20 @@ int main(int argc, char **argv, char **envp) {
         pid_t child1, child2;
         int status;
 
+        pref_app_to_run = command_from_prefs("app_to_run", DEFAULT_CLIENT);
+        assert(pref_app_to_run);
+
+        pref_login_shell = command_from_prefs("login_shell", DEFAULT_SHELL);
+        assert(pref_login_shell);
+
+        pref_startx_script = command_from_prefs("startx_script", DEFAULT_STARTX);
+        assert(pref_startx_script);
+
         /* Do the fork-twice trick to avoid having to reap zombies */
         child1 = fork();
         switch (child1) {
             case -1:                                /* error */
-                break;
+                FatalError("fork() failed: %s\n", strerror(errno));
 
             case 0:                                 /* child1 */
                 child2 = fork();
@@ -607,7 +622,7 @@ int main(int argc, char **argv, char **envp) {
                     int max_files, i;
 
                     case -1:                            /* error */
-                        break;
+                        FatalError("fork() failed: %s\n", strerror(errno));
 
                     case 0:                             /* child2 */
                         /* close all open files except for standard streams */
@@ -629,6 +644,10 @@ int main(int argc, char **argv, char **envp) {
             default:                                /* parent */
               waitpid(child1, &status, 0);
         }
+
+        free(pref_app_to_run);
+        free(pref_login_shell);
+        free(pref_startx_script);
     }
     
     /* Main event loop */
@@ -646,7 +665,7 @@ static int execute(const char *command) {
     const char *newargv[4];
     const char **p;
     
-    newargv[0] = command_from_prefs("login_shell", DEFAULT_SHELL);
+    newargv[0] = pref_login_shell;
     newargv[1] = "-c";
     newargv[2] = command;
     newargv[3] = NULL;
commit b47d2e43eb2cb3817c995d1f7e58500fb40efa2b
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Thu May 5 09:04:41 2011 -0700

    XQuartz: Make a copy of args for our crash reporter vsnprintf
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/os/log.c b/os/log.c
index 9579e58..4a310e6 100644
--- a/os/log.c
+++ b/os/log.c
@@ -528,7 +528,12 @@ FatalError(const char *f, ...)
 
     va_start(args, f);
 #ifdef __APPLE__
-    (void)vsnprintf(__crashreporter_info_buff__, sizeof(__crashreporter_info_buff__), f, args);
+    {
+        va_list args2;
+        va_copy(args2, args);
+        (void)vsnprintf(__crashreporter_info_buff__, sizeof(__crashreporter_info_buff__), f, args2);
+        va_end(args2);
+    }
 #endif
     VErrorF(f, args);
     va_end(args);
commit 3ac220d6cc386c9ab9995e5b83463c40330e18c2
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Tue May 3 10:54:09 2011 -0700

    XQuartz: prefs_copy_url and prefs_get_copy return retained objects
    
    No functional change.  This just annotates the return policy.
    
    Found-by: clang static analyzer
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/X11Application.h b/hw/xquartz/X11Application.h
index 256ff18..619f32f 100644
--- a/hw/xquartz/X11Application.h
+++ b/hw/xquartz/X11Application.h
@@ -43,11 +43,12 @@
 - (void) set_controller:controller;
 - (void) set_window_menu:(NSArray *)list;
 
+- (CFPropertyListRef) prefs_get_copy:(NSString *)key CF_RETURNS_RETAINED;
 - (int) prefs_get_integer:(NSString *)key default:(int)def;
 - (const char *) prefs_get_string:(NSString *)key default:(const char *)def;
 - (float) prefs_get_float:(NSString *)key default:(float)def;
 - (int) prefs_get_boolean:(NSString *)key default:(int)def;
-- (NSURL *) prefs_copy_url:(NSString *)key default:(NSURL *)def;
+- (NSURL *) prefs_copy_url:(NSString *)key default:(NSURL *)def NS_RETURNS_RETAINED;
 - (NSArray *) prefs_get_array:(NSString *)key;
 - (void) prefs_set_integer:(NSString *)key value:(int)value;
 - (void) prefs_set_float:(NSString *)key value:(float)value;
commit bac8d12555dd44b2139be0696629910cd4d8c782
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Tue May 3 10:36:19 2011 -0700

    XQuartz: Ensure that {CF,NS}_RETURNS{,_NOT}_RETAINED are defined
    
    These will be used in subsequent patches to denote proper retain counts in XQuartz
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/sanitizedCocoa.h b/hw/xquartz/sanitizedCocoa.h
index 58de64c..5a2a282 100644
--- a/hw/xquartz/sanitizedCocoa.h
+++ b/hw/xquartz/sanitizedCocoa.h
@@ -16,7 +16,8 @@
 #define BOOL         OSX_BOOL
 #define EventType    HIT_EventType
 
-#include <Cocoa/Cocoa.h>
+#import <Cocoa/Cocoa.h>
+#import <Foundation/Foundation.h>
 
 #undef Cursor
 #undef WindowPtr
@@ -24,4 +25,40 @@
 #undef BOOL
 #undef EventType
 
+#ifndef __has_feature
+#define __has_feature(x) 0 // Compatibility with non-clang compilers.
+#endif
+
+#ifndef NS_RETURNS_RETAINED
+#if __has_feature(attribute_ns_returns_retained)
+#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
+#else
+#define NS_RETURNS_RETAINED
+#endif
+#endif
+
+#ifndef NS_RETURNS_NOT_RETAINED
+#if __has_feature(attribute_ns_returns_not_retained)
+#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
+#else
+#define NS_RETURNS_NOT_RETAINED
+#endif
+#endif
+
+#ifndef CF_RETURNS_RETAINED
+#if __has_feature(attribute_cf_returns_retained)
+#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
+#else
+#define CF_RETURNS_RETAINED
+#endif
+#endif
+
+#ifndef CF_RETURNS_NOT_RETAINED
+#if __has_feature(attribute_cf_returns_not_retained)
+#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
+#else
+#define CF_RETURNS_NOT_RETAINED
+#endif
+#endif
+
 #endif  /* _XQ_SANITIZED_COCOA_H_ */
commit 0fc7ec6dd504aa03e1a1b18c60942c0c8c8b701b
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Fri Apr 29 11:06:18 2011 -0700

    XQuartz: Fix incorrect typedefs with XPLUGIN_VERSION < 4
    
    Ok, this time for sure... how many brown bags can I fit over my face?
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/applewmExt.h b/hw/xquartz/applewmExt.h
index 35c8f8f..c46a7bd 100644
--- a/hw/xquartz/applewmExt.h
+++ b/hw/xquartz/applewmExt.h
@@ -35,9 +35,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <Xplugin.h>
 
 #if XPLUGIN_VERSION < 4
-typedef xp_frame_attr int;
-typedef xp_frame_class int;
-typedef xp_frame_rect int;
+typedef int xp_frame_attr;
+typedef int xp_frame_class;
+typedef int xp_frame_rect;
 #endif
 
 typedef int (*DisableUpdateProc)(void);
commit 29d471663e4414a3cdf154fd032d74381a921ae0
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Sat Apr 23 18:09:11 2011 -0700

    XQuartz: Use a rwlock instead of a mutex to protect window_hash in the pthread case
    
    Concurrent reads are acceptable, so using an rwlock should be better.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/xpr/xprFrame.c b/hw/xquartz/xpr/xprFrame.c
index 5f6b1cb..4818653 100644
--- a/hw/xquartz/xpr/xprFrame.c
+++ b/hw/xquartz/xpr/xprFrame.c
@@ -69,7 +69,7 @@ static x_hash_table *window_hash;
 #ifdef HAVE_LIBDISPATCH
 static dispatch_queue_t window_hash_serial_q;
 #else
-static pthread_mutex_t window_hash_mutex;
+static pthread_rwlock_t window_hash_rwlock;
 #endif
 
 /* Prototypes for static functions */
@@ -192,9 +192,9 @@ xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
         x_hash_table_insert(window_hash, pFrame->wid, pFrame);
     });
 #else
-    pthread_mutex_lock(&window_hash_mutex);
+    pthread_rwlock_wrlock(&window_hash_rwlock);
     x_hash_table_insert(window_hash, pFrame->wid, pFrame);
-    pthread_mutex_unlock(&window_hash_mutex);
+    pthread_rwlock_wrlock(&window_hash_rwlock);
 #endif
 
     xprSetNativeProperty(pFrame);
@@ -216,9 +216,9 @@ xprDestroyFrame(RootlessFrameID wid)
         x_hash_table_remove(window_hash, wid);
     });
 #else
-    pthread_mutex_lock(&window_hash_mutex);
+    pthread_rwlock_wrlock(&window_hash_rwlock);
     x_hash_table_remove(window_hash, wid);
-    pthread_mutex_unlock(&window_hash_mutex);
+    pthread_rwlock_unlock(&window_hash_rwlock);
 #endif
 
     err = xp_destroy_window(x_cvt_vptr_to_uint(wid));
@@ -292,9 +292,9 @@ static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) {
         winRec = x_hash_table_lookup(window_hash, wid, NULL);
     });
 #else
-    pthread_mutex_lock(&window_hash_mutex);
+    pthread_rwlock_rdlock(&window_hash_rwlock);
     winRec = x_hash_table_lookup(window_hash, wid, NULL);
-    pthread_mutex_unlock(&window_hash_mutex);
+    pthread_rwlock_unlock(&window_hash_rwlock);
 #endif
     
     if(winRec) {
@@ -479,7 +479,7 @@ xprInit(ScreenPtr pScreen)
 #ifdef HAVE_LIBDISPATCH
     assert((window_hash_serial_q = dispatch_queue_create(BUNDLE_ID_PREFIX".X11.xpr_window_hash", NULL)));
 #else
-    assert(0 == pthread_mutex_init(&window_hash_mutex, NULL));
+    assert(0 == pthread_rwlock_init(&window_hash_rwlock, NULL));
 #endif
     
     return TRUE;
@@ -500,9 +500,9 @@ xprGetXWindow(xp_window_id wid)
     });
 #else
     RootlessWindowRec *winRec;
-    pthread_mutex_lock(&window_hash_mutex);
+    pthread_rwlock_rdlock(&window_hash_rwlock);
     winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL);
-    pthread_mutex_unlock(&window_hash_mutex);
+    pthread_rwlock_unlock(&window_hash_rwlock);
 #endif
 
     return winRec != NULL ? winRec->win : NULL;


More information about the xorg-commit mailing list