summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Byer <bbyer@bbyer.apple.com>2007-09-05 18:29:44 -0700
committerBen Byer <bbyer@bbyer.apple.com>2007-09-05 18:29:44 -0700
commit6217f34977bfa17b66b89df5d45420774abedcb3 (patch)
tree68953bb7bd2cd277add031d48c17312642d5dadf
parent4d0cfe491046df26027db291530b247b7f24df5b (diff)
changes to support launchd on OS X
-rw-r--r--Xtrans.c74
-rw-r--r--Xtranssock.c42
2 files changed, 113 insertions, 3 deletions
diff --git a/Xtrans.c b/Xtrans.c
index 00391a0..4de9161 100644
--- a/Xtrans.c
+++ b/Xtrans.c
@@ -53,6 +53,9 @@ from The Open Group.
*/
#include <ctype.h>
+#ifdef HAVE_LAUNCHD
+#include <launch.h>
+#endif
/*
* The transport table contains a definition for every transport (protocol)
@@ -360,6 +363,15 @@ TRANS(ParseAddress) (char *address, char **protocol, char **host, char **port)
*/
#endif
+#ifdef HAVE_LAUNCHD
+ /* launchd sockets will look like 'local//tmp/launch-XgkNns/:0' */
+ if(address != NULL && strlen(address)>8 && (!strncmp(address,"local//",7))) {
+ _protocol="local";
+ _host="";
+ _port=address+6;
+ }
+#endif
+
/*
* Now that we have all of the components, allocate new
* string space for them.
@@ -858,6 +870,10 @@ TRANS(Connect) (XtransConnInfo ciptr, char *address)
return -1;
}
+#ifdef HAVE_LAUNCHD
+ if (!host || !*host) host=strdup("");
+#endif
+
if (!port || !*port)
{
PRMSG (1,"Connect: Missing port specification in %s\n",
@@ -1053,15 +1069,71 @@ TRANS(MakeAllCOTSServerListeners) (char *port, int *partial, int *count_ret,
char buffer[256]; /* ??? What size ?? */
XtransConnInfo ciptr, temp_ciptrs[NUMTRANS];
int status, i, j;
+#ifdef HAVE_LAUNCHD
+ int launchd_fd;
+ launch_data_t sockets_dict, checkin_request, checkin_response;
+ launch_data_t listening_fd_array, listening_fd;
+#endif
+
#if defined(IPv6) && defined(AF_INET6)
int ipv6_succ = 0;
#endif
-
PRMSG (2,"MakeAllCOTSServerListeners(%s,%p)\n",
port ? port : "NULL", ciptrs_ret, 0);
*count_ret = 0;
+#ifdef HAVE_LAUNCHD
+ /* 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");
+ goto not_launchd;
+ }
+
+ if ((checkin_response = launch_msg(checkin_request)) == NULL) {
+ fprintf(stderr,"launch_msg(\"" LAUNCH_KEY_CHECKIN "\") IPC failure: %s\n",strerror(errno));
+ goto not_launchd;
+ }
+
+ if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) {
+ fprintf(stderr,"Check-in failed: %s\n",strerror(launch_data_get_errno(checkin_response)));
+ goto not_launchd;
+ }
+
+ sockets_dict = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_SOCKETS);
+ if (NULL == sockets_dict) {
+ fprintf(stderr,"No sockets found to answer requests on!\n");
+ goto not_launchd;
+ }
+
+ if (launch_data_dict_get_count(sockets_dict) > 1) {
+ fprintf(stderr,"Some sockets will be ignored!\n");
+ goto not_launchd;
+ }
+
+ listening_fd_array = launch_data_dict_lookup(sockets_dict, ":0");
+ if (NULL == listening_fd_array) {
+ fprintf(stderr,"No known sockets found to answer requests on!\n");
+ goto not_launchd;
+ }
+
+ if (launch_data_array_get_count(listening_fd_array)!=1) {
+ fprintf(stderr,"Expected 1 socket from launchd, got %d)\n",
+ launch_data_array_get_count(listening_fd_array));
+ goto not_launchd;
+ }
+
+ listening_fd=launch_data_array_get_index(listening_fd_array, 0);
+ launchd_fd=launch_data_get_fd(listening_fd);
+ fprintf(stderr,"Xquartz: run by launchd for fd %d\n",launchd_fd);
+ if((ciptr = TRANS(ReopenCOTSServer(TRANS_SOCKET_LOCAL_INDEX,
+ launchd_fd, getenv("DISPLAY"))))==NULL)
+ fprintf(stderr,"Got NULL while trying to Reopen launchd port\n");
+ else temp_ciptrs[(*count_ret)++] = ciptr;
+
+not_launchd:
+#endif
+
for (i = 0; i < NUMTRANS; i++)
{
Xtransport *trans = Xtransports[i].transport;
diff --git a/Xtranssock.c b/Xtranssock.c
index 65d4beb..e989b42 100644
--- a/Xtranssock.c
+++ b/Xtranssock.c
@@ -529,18 +529,55 @@ TRANS(SocketReopen) (int i, int type, int fd, char *port)
{
XtransConnInfo ciptr;
+ int portlen;
+ struct sockaddr *addr;
PRMSG (3,"SocketReopen(%d,%d,%s)\n", type, fd, port);
+ if (port == NULL) {
+ PRMSG (1, "SocketReopen: port was null!\n", 0, 0, 0);
+ return NULL;
+ }
+
+ portlen = strlen(port);
+ if (portlen < 0 || portlen > (SOCK_MAXADDRLEN + 2)) {
+ PRMSG (1, "SocketReopen: invalid portlen %d\n", portlen, 0, 0);
+ return NULL;
+ }
+
+ if (portlen < 14) portlen = 14;
+
if ((ciptr = (XtransConnInfo) xcalloc (
1, sizeof(struct _XtransConnInfo))) == NULL)
{
- PRMSG (1, "SocketReopen: malloc failed\n", 0, 0, 0);
+ PRMSG (1, "SocketReopen: malloc(ciptr) failed\n", 0, 0, 0);
return NULL;
}
ciptr->fd = fd;
+ if ((addr = (struct sockaddr *) xcalloc (1, portlen + 2)) == NULL) {
+ PRMSG (1, "SocketReopen: malloc(addr) failed\n", 0, 0, 0);
+ return NULL;
+ }
+ ciptr->addr = addr;
+ ciptr->addrlen = portlen + 2;
+
+ if ((ciptr->peeraddr = (struct sockaddr *) xcalloc (1, portlen + 2)) == NULL) {
+ PRMSG (1, "SocketReopen: malloc(portaddr) failed\n", 0, 0, 0);
+ return NULL;
+ }
+ ciptr->peeraddrlen = portlen + 2;
+
+ /* Initialize ciptr structure as if it were a normally-opened unix socket */
+ ciptr->flags = TRANS_LOCAL;
+ addr->sa_len = portlen + 1;
+ addr->sa_family = AF_UNIX;
+ strlcpy(addr->sa_data, port, portlen);
+ ciptr->family = AF_UNIX;
+ memcpy(ciptr->peeraddr, ciptr->addr, sizeof(struct sockaddr));
+ ciptr->port = rindex(addr->sa_data, ':');
+ if (ciptr->port[0] == ':') ciptr->port++; /* port should now point to portnum or NULL */
return ciptr;
}
@@ -1345,6 +1382,7 @@ TRANS(SocketUNIXAccept) (XtransConnInfo ciptr, int *status)
return NULL;
}
+ ciptr->addrlen = namelen;
/*
* Get the socket name and the peer name from the listener socket,
* since this is unix domain.
@@ -1970,7 +2008,7 @@ TRANS(SocketUNIXConnect) (XtransConnInfo ciptr, char *host, char *port)
* we know for sure it will fail.
*/
- if (strcmp (host, "unix") != 0 && !UnixHostReallyLocal (host))
+ if (host && *host && host[0]!='/' && strcmp (host, "unix") != 0 && !UnixHostReallyLocal (host))
{
PRMSG (1,
"SocketUNIXConnect: Cannot connect to non-local host %s\n",