cutils: first pass at cleaning up legacy/obsolete code in cutils

Removed unused code and moved libraries with single clients
near their respective users.

Change-Id: I65f90f8659f27bd0f44ca5ddf33da2bce14674c1
Signed-off-by: Dima Zavin <dima@android.com>
diff --git a/include/cutils/abort_socket.h b/include/cutils/abort_socket.h
deleted file mode 100644
index fbb1112..0000000
--- a/include/cutils/abort_socket.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2009, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* Helper to perform abortable blocking operations on a socket:
- *   asocket_connect()
- *   asocket_accept()
- *   asocket_read()
- *   asocket_write()
- * These calls are similar to the regular syscalls, but can be aborted with:
- *   asocket_abort()
- *
- * Calling close() on a regular POSIX socket does not abort blocked syscalls on
- * that socket in other threads.
- *
- * After calling asocket_abort() the socket cannot be reused.
- *
- * Call asocket_destory() *after* all threads have finished with the socket to
- * finish closing the socket and free the asocket structure.
- *
- * The helper is implemented by setting the socket non-blocking to initiate
- * syscalls connect(), accept(), read(), write(), then using a blocking poll()
- * on both the primary socket and a local pipe. This makes the poll() abortable
- * by writing a byte to the local pipe in asocket_abort().
- *
- * asocket_create() sets the fd to non-blocking mode. It must not be changed to
- * blocking mode.
- *
- * Using asocket will triple the number of file descriptors required per
- * socket, due to the local pipe. It may be possible to use a global pipe per
- * process rather than per socket, but we have not been able to come up with a
- * race-free implementation yet.
- *
- * All functions except asocket_init() and asocket_destroy() are thread safe.
- */
-
-#include <stdlib.h>
-#include <sys/socket.h>
-
-#ifndef __CUTILS_ABORT_SOCKET_H__
-#define __CUTILS_ABORT_SOCKET_H__
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct asocket {
-    int fd;           /* primary socket fd */
-    int abort_fd[2];  /* pipe used to abort */
-};
-
-/* Create an asocket from fd.
- * Sets the socket to non-blocking mode.
- * Returns NULL on error with errno set.
- */
-struct asocket *asocket_init(int fd);
-
-/* Blocking socket I/O with timeout.
- * Calling asocket_abort() from another thread will cause each of these
- * functions to immediately return with value -1 and errno ECANCELED.
- * timeout is in ms, use -1 to indicate no timeout. On timeout -1 is returned
- * with errno ETIMEDOUT.
- * EINTR is handled in-call.
- * Other semantics are identical to the regular syscalls.
- */
-int asocket_connect(struct asocket *s, const struct sockaddr *addr,
-        socklen_t addrlen, int timeout);
-
-int asocket_accept(struct asocket *s, struct sockaddr *addr,
-        socklen_t *addrlen, int timeout);
-
-int asocket_read(struct asocket *s, void *buf, size_t count, int timeout);
-
-int asocket_write(struct asocket *s, const void *buf, size_t count,
-        int timeout);
-
-/* Abort above calls and shutdown socket.
- * Further I/O operations on this socket will immediately fail after this call.
- * asocket_destroy() should be used to release resources once all threads
- * have returned from blocking calls on the socket.
- */
-void asocket_abort(struct asocket *s);
-
-/* Close socket and free asocket structure.
- * Must not be called until all calls on this structure have completed.
- */
-void asocket_destroy(struct asocket *s);
-
-#ifdef __cplusplus
-}
-#endif
-#endif //__CUTILS_ABORT_SOCKET__H__
diff --git a/include/cutils/array.h b/include/cutils/array.h
deleted file mode 100644
index c97ff34..0000000
--- a/include/cutils/array.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * A pointer array which intelligently expands its capacity ad needed.
- */
-
-#ifndef __ARRAY_H
-#define __ARRAY_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdlib.h>
-
-/** An array. */
-typedef struct Array Array;
-
-/** Constructs a new array. Returns NULL if we ran out of memory. */
-Array* arrayCreate();
-
-/** Frees an array. Does not free elements themselves. */
-void arrayFree(Array* array);
-
-/** Adds a pointer. Returns 0 is successful, < 0 otherwise. */
-int arrayAdd(Array* array, void* pointer);
-
-/** Gets the pointer at the specified index. */
-void* arrayGet(Array* array, int index);
-
-/** Removes the pointer at the given index and returns it. */
-void* arrayRemove(Array* array, int index);
-
-/** Sets pointer at the given index. Returns old pointer. */
-void* arraySet(Array* array, int index, void* pointer);
-
-/** Sets the array size. Sets new pointers to NULL. Returns 0 if successful, < 0 otherwise . */
-int arraySetSize(Array* array, int size);
-
-/** Returns the size of the given array. */
-int arraySize(Array* array);
-
-/** 
- * Returns a pointer to a C-style array which will be valid until this array 
- * changes.
- */
-const void** arrayUnwrap(Array* array);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __ARRAY_H */ 
diff --git a/include/cutils/mq.h b/include/cutils/mq.h
deleted file mode 100644
index b27456d..0000000
--- a/include/cutils/mq.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * IPC messaging library.
- */
-
-#ifndef __MQ_H
-#define __MQ_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** A message. */
-typedef struct MqMessage MqMessage;
-
-/** A destination to which messages can be sent. */
-typedef struct MqDestination MqDestination;
-
-/* Array of bytes. */
-typedef struct MqBytes MqBytes;
-
-/** 
- * Hears messages. 
- * 
- * @param destination to which the message was sent
- * @param message the message to hear
- */
-typedef void MqMessageListener(MqDestination* destination, MqMessage* message);
-
-/** 
- * Hears a destination close.
- * 
- * @param destination that closed
- */
-typedef void MqCloseListener(MqDestination* destination);
-
-/** Message functions. */
-
-/** 
- * Creates a new Message.
- * 
- * @param header as defined by user
- * @param body as defined by user
- * @param replyTo destination to which replies should be sent, NULL if none
- */
-MqMessage* mqCreateMessage(MqBytes header, MqBytes body, 
-        MqDestination* replyTo);
-
-/** Sends a message to a destination. */
-void mqSendMessage(MqMessage* message, MqDestination* destination);
-
-/** Destination functions. */
-
-/** 
- * Creates a new destination. Acquires a reference implicitly.
- *
- * @param messageListener function to call when a message is recieved
- * @param closeListener function to call when the destination closes
- * @param userData user-specific data to associate with the destination.
- *  Retrieve using mqGetDestinationUserData().
- */
-MqDestination* mqCreateDestination(MqMessageListener* messageListener, 
-        MqCloseListener* closeListener, void* userData);
-
-/**
- * Gets user data which was associated with the given destination at 
- * construction time. 
- * 
- * It is only valid to call this function in the same process that the 
- * given destination was created in.
- * This function returns a null pointer if you call it on a destination
- * created in a remote process.
- */
-void* mqGetUserData(MqDestination* destination);
-
-/**
- * Returns 1 if the destination was created in this process, or 0 if
- * the destination was created in a different process, in which case you have
- * a remote stub.
- */
-int mqIsDestinationLocal(MqDestination* destination);
-
-/**
- * Increments the destination's reference count.
- */
-void mqKeepDestination(MqDesintation* destination);
-
-/**
- * Decrements the destination's reference count. 
- */
-void mqFreeDestination(MqDestination* desintation);
-
-/** Registry API. */
-
-/**
- * Gets the destination bound to a name.
- */
-MqDestination* mqGetDestination(char* name);
-
-/**
- * Binds a destination to a name.
- */
-void mqPutDestination(char* name, MqDestination* desintation);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __MQ_H */ 
diff --git a/include/cutils/qsort_r_compat.h b/include/cutils/qsort_r_compat.h
deleted file mode 100644
index 479a1ab..0000000
--- a/include/cutils/qsort_r_compat.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Provides a portable version of qsort_r, called qsort_r_compat, which is a
- * reentrant variant of qsort that passes a user data pointer to its comparator.
- * This implementation follows the BSD parameter convention.
- */
-
-#ifndef _LIBS_CUTILS_QSORT_R_COMPAT_H
-#define _LIBS_CUTILS_QSORT_R_COMPAT_H
-
-#include <stdlib.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
-        int (*compar)(void*, const void* , const void* ));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _LIBS_CUTILS_QSORT_R_COMPAT_H
diff --git a/include/cutils/record_stream.h b/include/cutils/record_stream.h
deleted file mode 100644
index bfac87a..0000000
--- a/include/cutils/record_stream.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * A simple utility for reading fixed records out of a stream fd
- */
-
-#ifndef _CUTILS_RECORD_STREAM_H
-#define _CUTILS_RECORD_STREAM_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-typedef struct RecordStream RecordStream;
-
-extern RecordStream *record_stream_new(int fd, size_t maxRecordLen);
-extern void record_stream_free(RecordStream *p_rs);
-
-extern int record_stream_get_next (RecordStream *p_rs, void ** p_outRecord, 
-                                    size_t *p_outRecordLen);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /*_CUTILS_RECORD_STREAM_H*/
-
diff --git a/include/cutils/selector.h b/include/cutils/selector.h
deleted file mode 100644
index dfc2a9d..0000000
--- a/include/cutils/selector.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Framework for multiplexing I/O. A selector manages a set of file
- * descriptors and calls out to user-provided callback functions to read and
- * write data and handle errors.
- */
-
-#ifndef __SELECTOR_H
-#define __SELECTOR_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdbool.h>
-    
-/** 
- * Manages SelectableFds and invokes their callbacks at appropriate times. 
- */
-typedef struct Selector Selector;
-
-/** 
- * A selectable descriptor. Contains callbacks which the selector can invoke
- * before calling select(), when the descriptor is readable or writable, and 
- * when the descriptor contains out-of-band data. Simply set a callback to 
- * NULL if you're not interested in that particular event.
- *
- * A selectable descriptor can indicate that it needs to be removed from the
- * selector by setting the 'remove' flag. The selector will remove the
- * descriptor at a later time and invoke the onRemove() callback.
- * 
- * SelectableFd fields should only be modified from the selector loop.
- */
-typedef struct SelectableFd SelectableFd;
-struct SelectableFd {
-
-    /** The file descriptor itself. */
-    int fd;
-    
-    /** Pointer to user-specific data. Can be NULL. */
-    void* data;
-    
-    /** 
-     * Set this flag when you no longer wish to be selected. The selector
-     * will invoke onRemove() when the descriptor is actually removed.
-     */
-    bool remove;
-
-    /** 
-     * Invoked by the selector before calling select. You can set up other
-     * callbacks from here as necessary.
-     */
-    void (*beforeSelect)(SelectableFd* self);
-
-    /** 
-     * Invoked by the selector when the descriptor has data available. Set to
-     * NULL to indicate that you're not interested in reading.
-     */
-    void (*onReadable)(SelectableFd* self);
-
-    /** 
-     * Invoked by the selector when the descriptor can accept data. Set to
-     * NULL to indicate that you're not interested in writing.
-     */
-    void (*onWritable)(SelectableFd* self);
-
-    /** 
-     * Invoked by the selector when out-of-band (OOB) data is available. Set to
-     * NULL to indicate that you're not interested in OOB data.
-     */
-    void (*onExcept)(SelectableFd* self);
-
-    /**
-     * Invoked by the selector after the descriptor is removed from the
-     * selector but before the selector frees the SelectableFd memory.
-     */
-    void (*onRemove)(SelectableFd* self);
-
-    /**
-     * The selector which selected this fd. Set by the selector itself.
-     */
-    Selector* selector;
-};
-
-/** 
- * Creates a new selector. 
- */
-Selector* selectorCreate(void);
-
-/** 
- * Creates a new selectable fd, adds it to the given selector and returns a 
- * pointer. Outside of 'selector' and 'fd', all fields are set to 0 or NULL 
- * by default.
- * 
- * The selectable fd should only be modified from the selector loop thread.
- */
-SelectableFd* selectorAdd(Selector* selector, int fd);
-
-/**
- * Wakes up the selector even though no I/O events occurred. Use this
- * to indicate that you're ready to write to a descriptor.
- */
-void selectorWakeUp(Selector* selector);
-    
-/** 
- * Loops continuously selecting file descriptors and firing events. 
- * Does not return. 
- */
-void selectorLoop(Selector* selector);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __SELECTOR_H */ 
diff --git a/include/cutils/zygote.h b/include/cutils/zygote.h
deleted file mode 100644
index a7480d3..0000000
--- a/include/cutils/zygote.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __CUTILS_ZYGOTE_H
-#define __CUTILS_ZYGOTE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int zygote_run_oneshot(int sendStdio, int argc, const char **argv);
-int zygote_run(int argc, const char **argv);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __CUTILS_ZYGOTE_H */
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 5037705..afbc758 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -24,11 +24,9 @@
 hostSmpFlag := -DANDROID_SMP=0
 
 commonSources := \
-	array.c \
 	hashmap.c \
 	atomic.c.arm \
 	native_handle.c \
-	buffer.c \
 	socket_inaddr_any_server.c \
 	socket_local_client.c \
 	socket_local_server.c \
@@ -43,10 +41,8 @@
 	open_memstream.c \
 	strdup16to8.c \
 	strdup8to16.c \
-	record_stream.c \
 	process_name.c \
 	properties.c \
-	qsort_r_compat.c \
 	threads.c \
 	sched_policy.c \
 	iosched_policy.c \
@@ -74,11 +70,8 @@
         uio.c
 else
     commonSources += \
-        abort_socket.c \
         fs.c \
-        selector.c \
-        multiuser.c \
-        zygote.c
+        multiuser.c
 endif
 
 
@@ -118,7 +111,6 @@
         ashmem-dev.c \
         debugger.c \
         klog.c \
-        mq.c \
         partition_utils.c \
         qtaguid.c \
         trace.c \
diff --git a/libcutils/abort_socket.c b/libcutils/abort_socket.c
deleted file mode 100644
index 6a5e5e4..0000000
--- a/libcutils/abort_socket.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright 2009, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/poll.h>
-
-#include "cutils/abort_socket.h"
-
-struct asocket *asocket_init(int fd) {
-    int abort_fd[2];
-    int flags;
-    struct asocket *s;
-
-    /* set primary socket to non-blocking */
-    flags = fcntl(fd, F_GETFL);
-    if (flags == -1)
-        return NULL;
-    if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
-        return NULL;
-
-    /* create pipe with non-blocking write, so that asocket_close() cannot
-       block */
-    if (pipe(abort_fd))
-        return NULL;
-    flags = fcntl(abort_fd[1], F_GETFL);
-    if (flags == -1)
-        return NULL;
-    if (fcntl(abort_fd[1], F_SETFL, flags | O_NONBLOCK))
-        return NULL;
-
-    s = malloc(sizeof(struct asocket));
-    if (!s)
-        return NULL;
-
-    s->fd = fd;
-    s->abort_fd[0] = abort_fd[0];
-    s->abort_fd[1] = abort_fd[1];
-
-    return s;
-}
-
-int asocket_connect(struct asocket *s, const struct sockaddr *addr,
-        socklen_t addrlen, int timeout) {
-
-    int ret;
-
-    do {
-        ret = connect(s->fd, addr, addrlen);
-    } while (ret && errno == EINTR);
-
-    if (ret && errno == EINPROGRESS) {
-        /* ready to poll() */
-        socklen_t retlen;
-        struct pollfd pfd[2];
-
-        pfd[0].fd = s->fd;
-        pfd[0].events = POLLOUT;
-        pfd[0].revents = 0;
-        pfd[1].fd = s->abort_fd[0];
-        pfd[1].events = POLLIN;
-        pfd[1].revents = 0;
-
-        do {
-            ret = poll(pfd, 2, timeout);
-        } while (ret < 0 && errno == EINTR);
-
-        if (ret < 0)
-            return -1;
-        else if (ret == 0) {
-            /* timeout */
-            errno = ETIMEDOUT;
-            return -1;
-        }
-
-        if (pfd[1].revents) {
-            /* abort due to asocket_abort() */
-            errno = ECANCELED;
-            return -1;
-        }
-
-        if (pfd[0].revents) {
-            if (pfd[0].revents & POLLOUT) {
-                /* connect call complete, read return code */
-                retlen = sizeof(ret);
-                if (getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &ret, &retlen))
-                    return -1;
-                /* got connect() return code */
-                if (ret) {
-                    errno = ret;
-                }
-            } else {
-                /* some error event on this fd */
-                errno = ECONNABORTED;
-                return -1;
-            }
-        }
-    }
-
-    return ret;
-}
-
-int asocket_accept(struct asocket *s, struct sockaddr *addr,
-        socklen_t *addrlen, int timeout) {
-
-    int ret;
-    struct pollfd pfd[2];
-
-    pfd[0].fd = s->fd;
-    pfd[0].events = POLLIN;
-    pfd[0].revents = 0;
-    pfd[1].fd = s->abort_fd[0];
-    pfd[1].events = POLLIN;
-    pfd[1].revents = 0;
-
-    do {
-        ret = poll(pfd, 2, timeout);
-    } while (ret < 0 && errno == EINTR);
-
-    if (ret < 0)
-        return -1;
-    else if (ret == 0) {
-        /* timeout */
-        errno = ETIMEDOUT;
-        return -1;
-    }
-
-    if (pfd[1].revents) {
-        /* abort due to asocket_abort() */
-        errno = ECANCELED;
-        return -1;
-    }
-
-    if (pfd[0].revents) {
-        if (pfd[0].revents & POLLIN) {
-            /* ready to accept() without blocking */
-            do {
-                ret = accept(s->fd, addr, addrlen);
-            } while (ret < 0 && errno == EINTR);
-        } else {
-            /* some error event on this fd */
-            errno = ECONNABORTED;
-            return -1;
-        }
-    }
-
-    return ret;
-}
-
-int asocket_read(struct asocket *s, void *buf, size_t count, int timeout) {
-    int ret;
-    struct pollfd pfd[2];
-
-    pfd[0].fd = s->fd;
-    pfd[0].events = POLLIN;
-    pfd[0].revents = 0;
-    pfd[1].fd = s->abort_fd[0];
-    pfd[1].events = POLLIN;
-    pfd[1].revents = 0;
-
-    do {
-        ret = poll(pfd, 2, timeout);
-    } while (ret < 0 && errno == EINTR);
-
-    if (ret < 0)
-        return -1;
-    else if (ret == 0) {
-        /* timeout */
-        errno = ETIMEDOUT;
-        return -1;
-    }
-
-    if (pfd[1].revents) {
-        /* abort due to asocket_abort() */
-        errno = ECANCELED;
-        return -1;
-    }
-
-    if (pfd[0].revents) {
-        if (pfd[0].revents & POLLIN) {
-            /* ready to read() without blocking */
-            do {
-                ret = read(s->fd, buf, count);
-            } while (ret < 0 && errno == EINTR);
-        } else {
-            /* some error event on this fd */
-            errno = ECONNABORTED;
-            return -1;
-        }
-    }
-
-    return ret;
-}
-
-int asocket_write(struct asocket *s, const void *buf, size_t count,
-        int timeout) {
-    int ret;
-    struct pollfd pfd[2];
-
-    pfd[0].fd = s->fd;
-    pfd[0].events = POLLOUT;
-    pfd[0].revents = 0;
-    pfd[1].fd = s->abort_fd[0];
-    pfd[1].events = POLLIN;
-    pfd[1].revents = 0;
-
-    do {
-        ret = poll(pfd, 2, timeout);
-    } while (ret < 0 && errno == EINTR);
-
-    if (ret < 0)
-        return -1;
-    else if (ret == 0) {
-        /* timeout */
-        errno = ETIMEDOUT;
-        return -1;
-    }
-
-    if (pfd[1].revents) {
-        /* abort due to asocket_abort() */
-        errno = ECANCELED;
-        return -1;
-    }
-
-    if (pfd[0].revents) {
-        if (pfd[0].revents & POLLOUT) {
-            /* ready to write() without blocking */
-            do {
-                ret = write(s->fd, buf, count);
-            } while (ret < 0 && errno == EINTR);
-        } else {
-            /* some error event on this fd */
-            errno = ECONNABORTED;
-            return -1;
-        }
-    }
-
-    return ret;
-}
-
-void asocket_abort(struct asocket *s) {
-    int ret;
-    char buf = 0;
-
-    /* Prevent further use of fd, without yet releasing the fd */
-    shutdown(s->fd, SHUT_RDWR);
-
-    /* wake up calls blocked at poll() */
-    do {
-        ret = write(s->abort_fd[1], &buf, 1);
-    } while (ret < 0 && errno == EINTR);
-}
-
-void asocket_destroy(struct asocket *s) {
-    struct asocket s_copy = *s;
-
-    /* Clients should *not* be using these fd's after calling
-       asocket_destroy(), but in case they do, set to -1 so they cannot use a
-       stale fd */
-    s->fd = -1;
-    s->abort_fd[0] = -1;
-    s->abort_fd[1] = -1;
-
-    /* Call asocket_abort() in case there are still threads blocked on this
-       socket. Clients should not rely on this behavior - it is racy because we
-       are about to close() these sockets - clients should instead make sure
-       all threads are done with the socket before calling asocket_destory().
-     */
-    asocket_abort(&s_copy);
-
-    /* enough safety checks, close and release memory */
-    close(s_copy.abort_fd[1]);
-    close(s_copy.abort_fd[0]);
-    close(s_copy.fd);
-
-    free(s);
-}
diff --git a/libcutils/array.c b/libcutils/array.c
deleted file mode 100644
index 55ec055..0000000
--- a/libcutils/array.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <cutils/array.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-
-#define INITIAL_CAPACITY (4)
-#define MAX_CAPACITY     ((int)(UINT_MAX/sizeof(void*)))
-
-struct Array {
-    void** contents;
-    int size;
-    int capacity;
-};
-
-Array* arrayCreate() {
-    return calloc(1, sizeof(struct Array));
-}
-
-void arrayFree(Array* array) {
-    assert(array != NULL);
-
-    // Free internal array.
-    free(array->contents);
-
-    // Free the Array itself.
-    free(array);
-}
-
-/** Returns 0 if successful, < 0 otherwise.. */
-static int ensureCapacity(Array* array, int capacity) {
-    int oldCapacity = array->capacity;
-    if (capacity > oldCapacity) {
-        int newCapacity = (oldCapacity == 0) ? INITIAL_CAPACITY : oldCapacity;
-
-        // Ensure we're not doing something nasty
-        if (capacity > MAX_CAPACITY)
-            return -1;
-
-        // Keep doubling capacity until we surpass necessary capacity.
-        while (newCapacity < capacity) {
-            int  newCap = newCapacity*2;
-            // Handle integer overflows
-            if (newCap < newCapacity || newCap > MAX_CAPACITY) {
-                newCap = MAX_CAPACITY;
-            }
-            newCapacity = newCap;
-        }
-
-        // Should not happen, but better be safe than sorry
-        if (newCapacity < 0 || newCapacity > MAX_CAPACITY)
-            return -1;
-
-        void** newContents;
-        if (array->contents == NULL) {
-            // Allocate new array.
-            newContents = malloc(newCapacity * sizeof(void*));
-            if (newContents == NULL) {
-                return -1;
-            }
-        } else {
-            // Expand existing array.
-            newContents = realloc(array->contents, sizeof(void*) * newCapacity);
-            if (newContents == NULL) {
-                return -1;
-            }
-        }
-
-        array->capacity = newCapacity;
-        array->contents = newContents;
-    }
-
-    return 0;
-}
-
-int arrayAdd(Array* array, void* pointer) {
-    assert(array != NULL);
-    int size = array->size;
-    int result = ensureCapacity(array, size + 1);
-    if (result < 0) {
-        return result;
-    }
-    array->contents[size] = pointer;
-    array->size++;
-    return 0;
-}
-
-static inline void checkBounds(Array* array, int index) {
-    assert(array != NULL);
-    assert(index < array->size);
-    assert(index >= 0);
-}
-
-void* arrayGet(Array* array, int index) {
-    checkBounds(array, index);
-    return array->contents[index];
-}
-
-void* arrayRemove(Array* array, int index) {
-    checkBounds(array, index);
-
-    void* pointer = array->contents[index];
-    
-    int newSize = array->size - 1;
-    
-    // Shift entries left.
-    if (index != newSize) {
-        memmove(array->contents + index, array->contents + index + 1, 
-                (sizeof(void*)) * (newSize - index));
-    }
-
-    array->size = newSize;
-
-    return pointer;
-}
-
-void* arraySet(Array* array, int index, void* pointer) {
-    checkBounds(array, index);
-    void* old = array->contents[index];
-    array->contents[index] = pointer;
-    return old;
-}
-
-int arraySetSize(Array* array, int newSize) {
-    assert(array != NULL);
-    assert(newSize >= 0);
-   
-    int oldSize = array->size;
-    
-    if (newSize > oldSize) {
-        // Expand.
-        int result = ensureCapacity(array, newSize);
-        if (result < 0) {
-            return result;
-        }
-
-        // Zero out new entries.
-        memset(array->contents + sizeof(void*) * oldSize, 0,
-                sizeof(void*) * (newSize - oldSize));
-    }
-
-    array->size = newSize;
-
-    return 0;
-}
-
-int arraySize(Array* array) {
-    assert(array != NULL);
-    return array->size;
-}
-
-const void** arrayUnwrap(Array* array) {
-    return (const void**)array->contents;
-}
diff --git a/libcutils/buffer.c b/libcutils/buffer.c
deleted file mode 100644
index af99bd7..0000000
--- a/libcutils/buffer.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "buffer"
-
-#include <assert.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "buffer.h"
-#include "loghack.h"
-
-Buffer* bufferCreate(size_t capacity) {
-    Buffer* buffer = malloc(sizeof(Buffer));
-    if (buffer == NULL) {
-        return NULL;
-    }
-    buffer->capacity = capacity;
-    buffer->expected = 0;
-    buffer->data = malloc(capacity);
-    if (buffer->data == NULL) {
-        free(buffer);
-        return NULL;
-    }
-    return buffer;
-}
-
-void bufferFree(Buffer* buffer) {
-    free(buffer->data);
-    free(buffer);
-}
-
-Buffer* bufferWrap(char* data, size_t capacity, size_t size) {
-    Buffer* buffer = malloc(sizeof(Buffer));
-    if (buffer == NULL) {
-        return NULL;
-    }
-
-    buffer->data = data;
-    buffer->capacity = capacity;
-    buffer->size = size;
-    buffer->expected = 0;
-    return buffer;
-}
-
-int bufferPrepareForRead(Buffer* buffer, size_t expected) {
-    if (expected > buffer->capacity) {
-        // Expand buffer.
-        char* expanded = realloc(buffer->data, expected);
-        if (expanded == NULL) {
-            errno = ENOMEM;
-            return -1;
-        }
-        buffer->capacity = expected;
-        buffer->data = expanded;
-    }
-
-    buffer->size = 0;
-    buffer->expected = expected;
-    return 0;
-}
-
-ssize_t bufferRead(Buffer* buffer, int fd) {
-    assert(buffer->size < buffer->expected);
-    
-    ssize_t bytesRead = read(fd, 
-            buffer->data + buffer->size, 
-            buffer->expected - buffer->size);
-
-    if (bytesRead > 0) {
-        buffer->size += bytesRead;
-        return buffer->size;        
-    }
-
-    return bytesRead;
-}
-
-void bufferPrepareForWrite(Buffer* buffer) {
-    buffer->remaining = buffer->size;
-}
-
-ssize_t bufferWrite(Buffer* buffer, int fd) {
-    assert(buffer->remaining > 0);
-    assert(buffer->remaining <= buffer->size);
-
-    ssize_t bytesWritten = write(fd, 
-            buffer->data + buffer->size - buffer->remaining,
-            buffer->remaining);
-
-    if (bytesWritten >= 0) {
-        buffer->remaining -= bytesWritten;
-
-        ALOGD("Buffer bytes written: %d", (int) bytesWritten);
-        ALOGD("Buffer size: %d", (int) buffer->size);
-        ALOGD("Buffer remaining: %d", (int) buffer->remaining);
-
-        return buffer->remaining;
-    }
-
-    return bytesWritten;
-}
-
diff --git a/libcutils/buffer.h b/libcutils/buffer.h
deleted file mode 100644
index d8bc108..0000000
--- a/libcutils/buffer.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Byte buffer utilities.
- */
-
-#ifndef __BUFFER_H
-#define __BUFFER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdlib.h>
-
-/** 
- * Byte buffer of known size. Keeps track of how much data has been read
- * into or written out of the buffer.
- */
-typedef struct {
-    /** Buffered data. */
-    char* data;
-
-    union {
-        /** For reading. # of bytes we expect. */
-        size_t expected;
-
-        /** For writing. # of bytes to write. */
-        size_t remaining;
-    };
-
-    /** Actual # of bytes in the buffer. */
-    size_t size;
-
-    /** Amount of memory allocated for this buffer. */
-    size_t capacity;
-} Buffer;
-
-/**
- * Returns true if all data has been read into the buffer.
- */
-#define bufferReadComplete(buffer) (buffer->expected == buffer->size)
-
-/**
- * Returns true if the buffer has been completely written.
- */
-#define bufferWriteComplete(buffer) (buffer->remaining == 0)
-
-/**
- * Creates a new buffer with the given initial capacity.
- */
-Buffer* bufferCreate(size_t initialCapacity);
-
-/**
- * Wraps an existing byte array.
- */
-Buffer* bufferWrap(char* data, size_t capacity, size_t size);
-
-/**
- * Frees and its data.
- */
-void bufferFree(Buffer* buffer);
-
-/**
- * Prepares buffer to read 'expected' number of bytes. Expands capacity if
- * necessary. Returns 0 if successful or -1 if an error occurs allocating
- * memory.
- */
-int bufferPrepareForRead(Buffer* buffer, size_t expected);
-
-/**
- * Reads some data into a buffer. Returns -1 in case of an error and sets 
- * errno (see read()). Returns 0 for EOF. Updates buffer->size and returns
- * the new size after a succesful read. 
- *
- * Precondition: buffer->size < buffer->expected
- */
-ssize_t bufferRead(Buffer* buffer, int fd);
-
-/**
- * Prepares a buffer to be written out.
- */
-void bufferPrepareForWrite(Buffer* buffer);
-
-/**
- * Writes data from buffer to the given fd. Returns -1 and sets errno in case
- * of an error. Updates buffer->remaining and returns the number of remaining
- * bytes to be written after a successful write. 
- *
- * Precondition: buffer->remaining > 0
- */
-ssize_t bufferWrite(Buffer* buffer, int fd);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __BUFFER_H */ 
diff --git a/libcutils/mq.c b/libcutils/mq.c
deleted file mode 100644
index 6f6740e..0000000
--- a/libcutils/mq.c
+++ /dev/null
@@ -1,1357 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "mq"
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <sys/uio.h>
-
-#include <cutils/array.h>
-#include <cutils/hashmap.h>
-#include <cutils/selector.h>
-
-#include "loghack.h"
-#include "buffer.h"
-
-/** Number of dead peers to remember. */
-#define PEER_HISTORY (16)
-
-typedef struct sockaddr SocketAddress;
-typedef struct sockaddr_un UnixAddress;
-
-/** 
- * Process/user/group ID. We don't use ucred directly because it's only 
- * available on Linux.
- */
-typedef struct {
-    pid_t pid;
-    uid_t uid;
-    gid_t gid;
-} Credentials;
-
-/** Listens for bytes coming from remote peers. */
-typedef void BytesListener(Credentials credentials, char* bytes, size_t size);
-
-/** Listens for the deaths of remote peers. */
-typedef void DeathListener(pid_t pid);
-
-/** Types of packets. */
-typedef enum {
-    /** Request for a connection to another peer. */
-    CONNECTION_REQUEST, 
-
-    /** A connection to another peer. */
-    CONNECTION, 
-
-    /** Reports a failed connection attempt. */
-    CONNECTION_ERROR, 
-
-    /** A generic packet of bytes. */
-    BYTES,
-} PacketType;
-
-typedef enum {
-    /** Reading a packet header. */
-    READING_HEADER,
-
-    /** Waiting for a connection from the master. */
-    ACCEPTING_CONNECTION,
-
-    /** Reading bytes. */
-    READING_BYTES,
-} InputState;
-
-/** A packet header. */
-// TODO: Use custom headers for master->peer, peer->master, peer->peer.
-typedef struct {
-    PacketType type;
-    union {
-        /** Packet size. Used for BYTES. */
-        size_t size;
-
-        /** Credentials. Used for CONNECTION and CONNECTION_REQUEST. */
-        Credentials credentials; 
-    };
-} Header;
-
-/** A packet which will be sent to a peer. */
-typedef struct OutgoingPacket OutgoingPacket;
-struct OutgoingPacket {
-    /** Packet header. */
-    Header header; 
-    
-    union {
-        /** Connection to peer. Used with CONNECTION. */
-        int socket;
-        
-        /** Buffer of bytes. Used with BYTES. */
-        Buffer* bytes;
-    };
-
-    /** Frees all resources associated with this packet. */
-    void (*free)(OutgoingPacket* packet);
-   
-    /** Optional context. */
-    void* context;
-    
-    /** Next packet in the queue. */
-    OutgoingPacket* nextPacket;
-};
-
-/** Represents a remote peer. */
-typedef struct PeerProxy PeerProxy;
-
-/** Local peer state. You typically have one peer per process. */
-typedef struct {
-    /** This peer's PID. */
-    pid_t pid;
-    
-    /** 
-     * Map from pid to peer proxy. The peer has a peer proxy for each remote
-     * peer it's connected to. 
-     *
-     * Acquire mutex before use.
-     */
-    Hashmap* peerProxies;
-
-    /** Manages I/O. */
-    Selector* selector;
-   
-    /** Used to synchronize operations with the selector thread. */
-    pthread_mutex_t mutex; 
-
-    /** Is this peer the master? */
-    bool master;
-
-    /** Peer proxy for the master. */
-    PeerProxy* masterProxy;
-    
-    /** Listens for packets from remote peers. */
-    BytesListener* onBytes;
-    
-    /** Listens for deaths of remote peers. */
-    DeathListener* onDeath;
-    
-    /** Keeps track of recently dead peers. Requires mutex. */
-    pid_t deadPeers[PEER_HISTORY];
-    size_t deadPeerCursor;
-} Peer;
-
-struct PeerProxy {
-    /** Credentials of the remote process. */
-    Credentials credentials;
-
-    /** Keeps track of data coming in from the remote peer. */
-    InputState inputState;
-    Buffer* inputBuffer;
-    PeerProxy* connecting;
-
-    /** File descriptor for this peer. */
-    SelectableFd* fd;
-
-    /** 
-     * Queue of packets to be written out to the remote peer.
-     *
-     * Requires mutex.
-     */
-    // TODO: Limit queue length.
-    OutgoingPacket* currentPacket;
-    OutgoingPacket* lastPacket;
-    
-    /** Used to write outgoing header. */
-    Buffer outgoingHeader;
-    
-    /** True if this is the master's proxy. */
-    bool master;
-
-    /** Reference back to the local peer. */
-    Peer* peer;
-
-    /**
-     * Used in master only. Maps this peer proxy to other peer proxies to
-     * which the peer has been connected to. Maps pid to PeerProxy. Helps
-     * keep track of which connections we've sent to whom.
-     */
-    Hashmap* connections;
-};
-
-/** Server socket path. */
-static const char* MASTER_PATH = "/master.peer";
-
-/** Credentials of the master peer. */
-static const Credentials MASTER_CREDENTIALS = {0, 0, 0};
-
-/** Creates a peer proxy and adds it to the peer proxy map. */
-static PeerProxy* peerProxyCreate(Peer* peer, Credentials credentials);
-
-/** Sets the non-blocking flag on a descriptor. */
-static void setNonBlocking(int fd) {
-    int flags;
-    if ((flags = fcntl(fd, F_GETFL, 0)) < 0) { 
-        LOG_ALWAYS_FATAL("fcntl() error: %s", strerror(errno));
-    } 
-    if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { 
-        LOG_ALWAYS_FATAL("fcntl() error: %s", strerror(errno));
-    } 
-}
-
-/** Closes a fd and logs a warning if the close fails. */
-static void closeWithWarning(int fd) {
-    int result = close(fd);
-    if (result == -1) {
-        ALOGW("close() error: %s", strerror(errno));
-    }
-}
-
-/** Hashes pid_t keys. */
-static int pidHash(void* key) {
-    pid_t* pid = (pid_t*) key;
-    return (int) (*pid);
-}
-
-/** Compares pid_t keys. */
-static bool pidEquals(void* keyA, void* keyB) {
-    pid_t* a = (pid_t*) keyA;
-    pid_t* b = (pid_t*) keyB;
-    return *a == *b;
-}
-
-/** Gets the master address. Not thread safe. */
-static UnixAddress* getMasterAddress() {
-    static UnixAddress masterAddress;
-    static bool initialized = false;
-    if (initialized == false) {
-        masterAddress.sun_family = AF_LOCAL;
-        strcpy(masterAddress.sun_path, MASTER_PATH); 
-        initialized = true;
-    }
-    return &masterAddress;
-}
-
-/** Gets exclusive access to the peer for this thread. */
-static void peerLock(Peer* peer) {
-    pthread_mutex_lock(&peer->mutex);
-}
-
-/** Releases exclusive access to the peer. */
-static void peerUnlock(Peer* peer) {
-    pthread_mutex_unlock(&peer->mutex);
-}
-
-/** Frees a simple, i.e. header-only, outgoing packet. */
-static void outgoingPacketFree(OutgoingPacket* packet) {
-    ALOGD("Freeing outgoing packet.");
-	free(packet);
-}
-
-/**
- * Prepare to read a new packet from the peer.
- */
-static void peerProxyExpectHeader(PeerProxy* peerProxy) {
-    peerProxy->inputState = READING_HEADER;
-    bufferPrepareForRead(peerProxy->inputBuffer, sizeof(Header));
-}
-
-/** Sets up the buffer for the outgoing header. */
-static void peerProxyPrepareOutgoingHeader(PeerProxy* peerProxy) {
-    peerProxy->outgoingHeader.data 
-        = (char*) &(peerProxy->currentPacket->header);
-    peerProxy->outgoingHeader.size = sizeof(Header);
-    bufferPrepareForWrite(&peerProxy->outgoingHeader);
-}
-
-/** Adds a packet to the end of the queue. Callers must have the mutex. */
-static void peerProxyEnqueueOutgoingPacket(PeerProxy* peerProxy,
-        OutgoingPacket* newPacket) {
-    newPacket->nextPacket = NULL; // Just in case.
-    if (peerProxy->currentPacket == NULL) {
-        // The queue is empty.
-        peerProxy->currentPacket = newPacket;
-        peerProxy->lastPacket = newPacket;
-        
-        peerProxyPrepareOutgoingHeader(peerProxy); 
-    } else {
-        peerProxy->lastPacket->nextPacket = newPacket;
-    }
-}
-
-/** Takes the peer lock and enqueues the given packet. */
-static void peerProxyLockAndEnqueueOutgoingPacket(PeerProxy* peerProxy,
-        OutgoingPacket* newPacket) {
-    Peer* peer = peerProxy->peer;
-    peerLock(peer);
-    peerProxyEnqueueOutgoingPacket(peerProxy, newPacket);
-    peerUnlock(peer);
-}
-
-/** 
- * Frees current packet and moves to the next one. Returns true if there is
- * a next packet or false if the queue is empty.
- */
-static bool peerProxyNextPacket(PeerProxy* peerProxy) {
-    Peer* peer = peerProxy->peer;
-    peerLock(peer);
-    
-    OutgoingPacket* current = peerProxy->currentPacket;
-    
-    if (current == NULL) {
-    	// The queue is already empty.
-        peerUnlock(peer);
-        return false;
-    }
-    
-    OutgoingPacket* next = current->nextPacket;
-    peerProxy->currentPacket = next;
-    current->nextPacket = NULL;
-    current->free(current);
-    if (next == NULL) {
-        // The queue is empty.
-        peerProxy->lastPacket = NULL;
-        peerUnlock(peer);
-        return false;
-    } else {
-        peerUnlock(peer);
-        peerProxyPrepareOutgoingHeader(peerProxy); 
-
-        // TODO: Start writing next packet? It would reduce the number of
-        // system calls, but we could also starve other peers.
-        return true;
-    }
-}
-
-/**
- * Checks whether a peer died recently.
- */
-static bool peerIsDead(Peer* peer, pid_t pid) {
-    size_t i;
-    for (i = 0; i < PEER_HISTORY; i++) {
-        pid_t deadPeer = peer->deadPeers[i];
-        if (deadPeer == 0) {
-            return false;
-        }
-        if (deadPeer == pid) {
-            return true;
-        }
-    }
-    return false;
-}
-
-/**
- * Cleans up connection information.
- */
-static bool peerProxyRemoveConnection(void* key, void* value, void* context) {
-    PeerProxy* deadPeer = (PeerProxy*) context;
-    PeerProxy* otherPeer = (PeerProxy*) value;
-    hashmapRemove(otherPeer->connections, &(deadPeer->credentials.pid));
-    return true;
-}
-
-/**
- * Called when the peer dies.
- */
-static void peerProxyKill(PeerProxy* peerProxy, bool errnoIsSet) {
-    if (errnoIsSet) {
-        ALOGI("Peer %d died. errno: %s", peerProxy->credentials.pid, 
-                strerror(errno));
-    } else {
-        ALOGI("Peer %d died.", peerProxy->credentials.pid);
-    }
-    
-    // If we lost the master, we're up a creek. We can't let this happen.
-    if (peerProxy->master) {    
-        LOG_ALWAYS_FATAL("Lost connection to master.");
-    }
-
-    Peer* localPeer = peerProxy->peer;
-    pid_t pid = peerProxy->credentials.pid;
-    
-    peerLock(localPeer);
-    
-    // Remember for awhile that the peer died.
-    localPeer->deadPeers[localPeer->deadPeerCursor] 
-        = peerProxy->credentials.pid;
-    localPeer->deadPeerCursor++;
-    if (localPeer->deadPeerCursor == PEER_HISTORY) {
-        localPeer->deadPeerCursor = 0;
-    }
-  
-    // Remove from peer map.
-    hashmapRemove(localPeer->peerProxies, &pid);
-    
-    // External threads can no longer get to this peer proxy, so we don't 
-    // need the lock anymore.
-    peerUnlock(localPeer);
-    
-    // Remove the fd from the selector.
-    if (peerProxy->fd != NULL) {
-        peerProxy->fd->remove = true;
-    }
-
-    // Clear outgoing packet queue.
-    while (peerProxyNextPacket(peerProxy)) {}
-
-    bufferFree(peerProxy->inputBuffer);
-
-    // This only applies to the master.
-    if (peerProxy->connections != NULL) {
-        // We can't leave these other maps pointing to freed memory.
-        hashmapForEach(peerProxy->connections, &peerProxyRemoveConnection, 
-                peerProxy);
-        hashmapFree(peerProxy->connections);
-    }
-
-    // Invoke death listener.
-    localPeer->onDeath(pid);
-
-    // Free the peer proxy itself.
-    free(peerProxy);
-}
-
-static void peerProxyHandleError(PeerProxy* peerProxy, char* functionName) {
-    if (errno == EINTR) {
-        // Log interruptions but otherwise ignore them.
-        ALOGW("%s() interrupted.", functionName);
-    } else if (errno == EAGAIN) {
-        ALOGD("EWOULDBLOCK");
-        // Ignore.
-    } else {
-        ALOGW("Error returned by %s().", functionName);
-        peerProxyKill(peerProxy, true);
-    }
-}
-
-/**
- * Buffers output sent to a peer. May be called multiple times until the entire
- * buffer is filled. Returns true when the buffer is empty.
- */
-static bool peerProxyWriteFromBuffer(PeerProxy* peerProxy, Buffer* outgoing) {
-    ssize_t size = bufferWrite(outgoing, peerProxy->fd->fd);
-    if (size < 0) {
-        peerProxyHandleError(peerProxy, "write");
-        return false;
-    } else {
-        return bufferWriteComplete(outgoing);
-    }
-}
-
-/** Writes packet bytes to peer. */
-static void peerProxyWriteBytes(PeerProxy* peerProxy) {	
-	Buffer* buffer = peerProxy->currentPacket->bytes;
-	if (peerProxyWriteFromBuffer(peerProxy, buffer)) {
-        ALOGD("Bytes written.");
-        peerProxyNextPacket(peerProxy);
-    }    
-}
-
-/** Sends a socket to the peer. */
-static void peerProxyWriteConnection(PeerProxy* peerProxy) {
-    int socket = peerProxy->currentPacket->socket;
-
-    // Why does sending and receiving fds have to be such a PITA?
-    struct msghdr msg;
-    struct iovec iov[1];
-    
-    union {
-        struct cmsghdr cm;
-        char control[CMSG_SPACE(sizeof(int))];
-    } control_un;
-   
-    struct cmsghdr *cmptr;
-    
-    msg.msg_control = control_un.control;
-    msg.msg_controllen = sizeof(control_un.control);
-    cmptr = CMSG_FIRSTHDR(&msg);
-    cmptr->cmsg_len = CMSG_LEN(sizeof(int));
-    cmptr->cmsg_level = SOL_SOCKET;
-    cmptr->cmsg_type = SCM_RIGHTS;
-   
-    // Store the socket in the message.
-    *((int *) CMSG_DATA(cmptr)) = peerProxy->currentPacket->socket;
-
-    msg.msg_name = NULL;
-    msg.msg_namelen = 0;
-    iov[0].iov_base = "";
-    iov[0].iov_len = 1;
-    msg.msg_iov = iov;
-    msg.msg_iovlen = 1;
-
-    ssize_t result = sendmsg(peerProxy->fd->fd, &msg, 0);
-    
-    if (result < 0) {
-        peerProxyHandleError(peerProxy, "sendmsg");
-    } else {
-        // Success. Queue up the next packet.
-        peerProxyNextPacket(peerProxy);
-        
-    }
-}
-
-/**
- * Writes some outgoing data.
- */
-static void peerProxyWrite(SelectableFd* fd) {
-    // TODO: Try to write header and body with one system call.
-
-    PeerProxy* peerProxy = (PeerProxy*) fd->data;
-    OutgoingPacket* current = peerProxy->currentPacket;
-    
-    if (current == NULL) {
-        // We have nothing left to write.
-        return;
-    }
-
-    // Write the header.
-    Buffer* outgoingHeader = &peerProxy->outgoingHeader;
-    bool headerWritten = bufferWriteComplete(outgoingHeader);
-    if (!headerWritten) {
-        ALOGD("Writing header...");
-        headerWritten = peerProxyWriteFromBuffer(peerProxy, outgoingHeader);
-        if (headerWritten) {
-            ALOGD("Header written.");
-        }
-    }    
-
-    // Write body.
-    if (headerWritten) {
-        PacketType type = current->header.type;
-        switch (type) {
-            case CONNECTION:
-                peerProxyWriteConnection(peerProxy);
-                break;
-            case BYTES:
-                peerProxyWriteBytes(peerProxy);
-                break;
-            case CONNECTION_REQUEST:
-            case CONNECTION_ERROR:
-                // These packets consist solely of a header.
-                peerProxyNextPacket(peerProxy);
-                break;
-            default:
-                LOG_ALWAYS_FATAL("Unknown packet type: %d", type); 
-        }
-    }
-}
-
-/**
- * Sets up a peer proxy's fd before we try to select() it.
- */
-static void peerProxyBeforeSelect(SelectableFd* fd) {
-    ALOGD("Before select...");
-
-    PeerProxy* peerProxy = (PeerProxy*) fd->data;
-  
-    peerLock(peerProxy->peer);
-    bool hasPackets = peerProxy->currentPacket != NULL;
-    peerUnlock(peerProxy->peer);
-    
-    if (hasPackets) {
-        ALOGD("Packets found. Setting onWritable().");
-            
-        fd->onWritable = &peerProxyWrite;
-    } else {
-        // We have nothing to write.
-        fd->onWritable = NULL;
-    }
-}
-
-/** Prepare to read bytes from the peer. */
-static void peerProxyExpectBytes(PeerProxy* peerProxy, Header* header) {
-    ALOGD("Expecting %d bytes.", header->size);
-
-    peerProxy->inputState = READING_BYTES;
-    if (bufferPrepareForRead(peerProxy->inputBuffer, header->size) == -1) {
-        ALOGW("Couldn't allocate memory for incoming data. Size: %u",
-                (unsigned int) header->size);    
-        
-        // TODO: Ignore the packet and log a warning?
-        peerProxyKill(peerProxy, false);
-    }
-}
-
-/**
- * Gets a peer proxy for the given ID. Creates a peer proxy if necessary.
- * Sends a connection request to the master if desired.
- *
- * Returns NULL if an error occurs. Sets errno to EHOSTDOWN if the peer died
- * or ENOMEM if memory couldn't be allocated.
- */
-static PeerProxy* peerProxyGetOrCreate(Peer* peer, pid_t pid, 
-        bool requestConnection) {
-    if (pid == peer->pid) {
-        errno = EINVAL;
-        return NULL;
-    }
-    
-    if (peerIsDead(peer, pid)) {
-        errno = EHOSTDOWN;
-        return NULL;
-    }
-    
-    PeerProxy* peerProxy = hashmapGet(peer->peerProxies, &pid);
-    if (peerProxy != NULL) {
-        return peerProxy;
-    }
-
-    // If this is the master peer, we already know about all peers.
-    if (peer->master) {
-        errno = EHOSTDOWN;
-        return NULL;
-    }
-
-    // Try to create a peer proxy.
-    Credentials credentials;
-    credentials.pid = pid;
-
-    // Fake gid and uid until we have the real thing. The real creds are
-    // filled in by masterProxyExpectConnection(). These fake creds will
-    // never be exposed to the user.
-    credentials.uid = 0;
-    credentials.gid = 0;
-
-    // Make sure we can allocate the connection request packet.
-    OutgoingPacket* packet = NULL;
-    if (requestConnection) {
-        packet = calloc(1, sizeof(OutgoingPacket));
-        if (packet == NULL) {
-            errno = ENOMEM;
-            return NULL;
-        }
-
-        packet->header.type = CONNECTION_REQUEST;
-        packet->header.credentials = credentials;
-        packet->free = &outgoingPacketFree;
-    }
-    
-    peerProxy = peerProxyCreate(peer, credentials);
-    if (peerProxy == NULL) {
-        free(packet);
-        errno = ENOMEM;
-        return NULL;
-    } else {
-        // Send a connection request to the master.
-        if (requestConnection) {
-            PeerProxy* masterProxy = peer->masterProxy;
-            peerProxyEnqueueOutgoingPacket(masterProxy, packet);
-        }
-        
-        return peerProxy;
-    }
-}
-
-/**
- * Switches the master peer proxy into a state where it's waiting for a
- * connection from the master.
- */
-static void masterProxyExpectConnection(PeerProxy* masterProxy,
-        Header* header) {
-    // TODO: Restructure things so we don't need this check.
-    // Verify that this really is the master.
-    if (!masterProxy->master) {
-        ALOGW("Non-master process %d tried to send us a connection.", 
-            masterProxy->credentials.pid);
-        // Kill off the evil peer.
-        peerProxyKill(masterProxy, false);
-        return;
-    }
-    
-    masterProxy->inputState = ACCEPTING_CONNECTION;
-    Peer* localPeer = masterProxy->peer;
-   
-    // Create a peer proxy so we have somewhere to stash the creds.
-    // See if we already have a proxy set up.
-    pid_t pid = header->credentials.pid;
-    peerLock(localPeer);
-    PeerProxy* peerProxy = peerProxyGetOrCreate(localPeer, pid, false);
-    if (peerProxy == NULL) {
-        ALOGW("Peer proxy creation failed: %s", strerror(errno));
-    } else {
-        // Fill in full credentials.
-        peerProxy->credentials = header->credentials;
-    }
-    peerUnlock(localPeer);
-    
-    // Keep track of which peer proxy we're accepting a connection for.
-    masterProxy->connecting = peerProxy;
-}
-
-/**
- * Reads input from a peer process.
- */
-static void peerProxyRead(SelectableFd* fd);
-
-/** Sets up fd callbacks. */
-static void peerProxySetFd(PeerProxy* peerProxy, SelectableFd* fd) {
-    peerProxy->fd = fd;
-    fd->data = peerProxy;
-    fd->onReadable = &peerProxyRead;
-    fd->beforeSelect = &peerProxyBeforeSelect;
-    
-    // Make the socket non-blocking.
-    setNonBlocking(fd->fd);
-}
-
-/**
- * Accepts a connection sent by the master proxy.
- */
-static void masterProxyAcceptConnection(PeerProxy* masterProxy) {
-    struct msghdr msg;
-    struct iovec iov[1];
-    ssize_t size;
-    char ignored;
-    int incomingFd;
-    
-    // TODO: Reuse code which writes the connection. Who the heck designed
-    // this API anyway?
-    union {
-        struct cmsghdr cm;
-        char control[CMSG_SPACE(sizeof(int))];
-    } control_un;
-    struct cmsghdr *cmptr;
-    msg.msg_control = control_un.control;
-    msg.msg_controllen = sizeof(control_un.control);
-
-    msg.msg_name = NULL;
-    msg.msg_namelen = 0;
-
-    // We sent 1 byte of data so we can detect EOF.
-    iov[0].iov_base = &ignored;
-    iov[0].iov_len = 1;
-    msg.msg_iov = iov;
-    msg.msg_iovlen = 1;
-
-    size = recvmsg(masterProxy->fd->fd, &msg, 0);
-    if (size < 0) {
-        if (errno == EINTR) {
-            // Log interruptions but otherwise ignore them.
-            ALOGW("recvmsg() interrupted.");
-            return;
-        } else if (errno == EAGAIN) {
-            // Keep waiting for the connection.
-            return;
-        } else {
-            LOG_ALWAYS_FATAL("Error reading connection from master: %s",
-                    strerror(errno));
-        }
-    } else if (size == 0) {
-        // EOF.
-        LOG_ALWAYS_FATAL("Received EOF from master.");
-    }
-
-    // Extract fd from message.
-    if ((cmptr = CMSG_FIRSTHDR(&msg)) != NULL 
-            && cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
-        if (cmptr->cmsg_level != SOL_SOCKET) {
-            LOG_ALWAYS_FATAL("Expected SOL_SOCKET.");
-        }
-        if (cmptr->cmsg_type != SCM_RIGHTS) {
-            LOG_ALWAYS_FATAL("Expected SCM_RIGHTS.");
-        }
-        incomingFd = *((int*) CMSG_DATA(cmptr));
-    } else {
-        LOG_ALWAYS_FATAL("Expected fd.");
-    }
-    
-    // The peer proxy this connection is for.
-    PeerProxy* peerProxy = masterProxy->connecting;
-    if (peerProxy == NULL) {
-        ALOGW("Received connection for unknown peer.");
-        closeWithWarning(incomingFd);
-    } else {
-        Peer* peer = masterProxy->peer;
-        
-        SelectableFd* selectableFd = selectorAdd(peer->selector, incomingFd);
-        if (selectableFd == NULL) {
-            ALOGW("Error adding fd to selector for %d.",
-                    peerProxy->credentials.pid);
-            closeWithWarning(incomingFd);
-            peerProxyKill(peerProxy, false);
-        }
-
-        peerProxySetFd(peerProxy, selectableFd);
-    }
-    
-    peerProxyExpectHeader(masterProxy);
-}
-
-/**
- * Frees an outgoing packet containing a connection.
- */
-static void outgoingPacketFreeSocket(OutgoingPacket* packet) {
-    closeWithWarning(packet->socket);
-    outgoingPacketFree(packet);
-}
-
-/**
- * Connects two known peers.
- */
-static void masterConnectPeers(PeerProxy* peerA, PeerProxy* peerB) {
-    int sockets[2];
-    int result = socketpair(AF_LOCAL, SOCK_STREAM, 0, sockets);
-    if (result == -1) {
-        ALOGW("socketpair() error: %s", strerror(errno));
-        // TODO: Send CONNECTION_FAILED packets to peers.
-        return;
-    }
-
-    OutgoingPacket* packetA = calloc(1, sizeof(OutgoingPacket));
-    OutgoingPacket* packetB = calloc(1, sizeof(OutgoingPacket));
-    if (packetA == NULL || packetB == NULL) {
-        free(packetA);
-        free(packetB);
-        ALOGW("malloc() error. Failed to tell process %d that process %d is"
-                " dead.", peerA->credentials.pid, peerB->credentials.pid);
-        return;
-    }
-   
-    packetA->header.type = CONNECTION;
-    packetB->header.type = CONNECTION;
-    
-    packetA->header.credentials = peerB->credentials;
-    packetB->header.credentials = peerA->credentials;
-
-    packetA->socket = sockets[0];
-    packetB->socket = sockets[1];
-
-    packetA->free = &outgoingPacketFreeSocket;
-    packetB->free = &outgoingPacketFreeSocket;
-   
-    peerLock(peerA->peer);
-    peerProxyEnqueueOutgoingPacket(peerA, packetA);   
-    peerProxyEnqueueOutgoingPacket(peerB, packetB);   
-    peerUnlock(peerA->peer);
-}
-
-/**
- * Informs a peer that the peer they're trying to connect to couldn't be
- * found.
- */
-static void masterReportConnectionError(PeerProxy* peerProxy,
-        Credentials credentials) {
-    OutgoingPacket* packet = calloc(1, sizeof(OutgoingPacket));
-    if (packet == NULL) {
-        ALOGW("malloc() error. Failed to tell process %d that process %d is"
-                " dead.", peerProxy->credentials.pid, credentials.pid);
-        return;
-    }
-   
-    packet->header.type = CONNECTION_ERROR;
-    packet->header.credentials = credentials;
-    packet->free = &outgoingPacketFree;
-    
-    peerProxyLockAndEnqueueOutgoingPacket(peerProxy, packet);   
-}
-
-/**
- * Handles a request to be connected to another peer.
- */
-static void masterHandleConnectionRequest(PeerProxy* peerProxy, 
-        Header* header) {
-    Peer* master = peerProxy->peer;
-    pid_t targetPid = header->credentials.pid;
-    if (!hashmapContainsKey(peerProxy->connections, &targetPid)) {
-        // We haven't connected these peers yet.
-        PeerProxy* targetPeer 
-            = (PeerProxy*) hashmapGet(master->peerProxies, &targetPid);
-        if (targetPeer == NULL) {
-            // Unknown process.
-            masterReportConnectionError(peerProxy, header->credentials);
-        } else {
-            masterConnectPeers(peerProxy, targetPeer);
-        }
-    }
-    
-    // This packet is complete. Get ready for the next one.
-    peerProxyExpectHeader(peerProxy);
-}
-
-/**
- * The master told us this peer is dead.
- */
-static void masterProxyHandleConnectionError(PeerProxy* masterProxy,
-        Header* header) {
-    Peer* peer = masterProxy->peer;
-    
-    // Look up the peer proxy.
-    pid_t pid = header->credentials.pid;
-    PeerProxy* peerProxy = NULL;
-    peerLock(peer);
-    peerProxy = hashmapGet(peer->peerProxies, &pid);
-    peerUnlock(peer);
-
-    if (peerProxy != NULL) {
-        ALOGI("Couldn't connect to %d.", pid);
-        peerProxyKill(peerProxy, false);
-    } else {
-        ALOGW("Peer proxy for %d not found. This shouldn't happen.", pid);
-    }
-    
-    peerProxyExpectHeader(masterProxy);
-}
-
-/**
- * Handles a packet header.
- */
-static void peerProxyHandleHeader(PeerProxy* peerProxy, Header* header) {
-    switch (header->type) {
-        case CONNECTION_REQUEST:
-            masterHandleConnectionRequest(peerProxy, header);
-            break;
-        case CONNECTION:
-            masterProxyExpectConnection(peerProxy, header);
-            break;
-        case CONNECTION_ERROR:
-            masterProxyHandleConnectionError(peerProxy, header);
-            break;
-        case BYTES:    
-            peerProxyExpectBytes(peerProxy, header);
-            break;
-        default:
-            ALOGW("Invalid packet type from %d: %d", peerProxy->credentials.pid, 
-                    header->type);
-            peerProxyKill(peerProxy, false);
-    }
-}
-
-/**
- * Buffers input sent by peer. May be called multiple times until the entire
- * buffer is filled. Returns true when the buffer is full.
- */
-static bool peerProxyBufferInput(PeerProxy* peerProxy) {
-    Buffer* in = peerProxy->inputBuffer;
-    ssize_t size = bufferRead(in, peerProxy->fd->fd);
-    if (size < 0) {
-        peerProxyHandleError(peerProxy, "read");
-        return false;
-    } else if (size == 0) {
-        // EOF.
-    	ALOGI("EOF");
-        peerProxyKill(peerProxy, false);
-        return false;
-    } else if (bufferReadComplete(in)) {
-        // We're done!
-        return true;
-    } else {
-        // Continue reading.
-        return false;
-    }
-}
-
-/**
- * Reads input from a peer process.
- */
-static void peerProxyRead(SelectableFd* fd) {
-    ALOGD("Reading...");
-    PeerProxy* peerProxy = (PeerProxy*) fd->data;
-    int state = peerProxy->inputState;
-    Buffer* in = peerProxy->inputBuffer;
-    switch (state) {
-        case READING_HEADER:
-            if (peerProxyBufferInput(peerProxy)) {
-                ALOGD("Header read.");
-                // We've read the complete header.
-                Header* header = (Header*) in->data;
-                peerProxyHandleHeader(peerProxy, header);
-            }
-            break;
-        case READING_BYTES:
-            ALOGD("Reading bytes...");
-            if (peerProxyBufferInput(peerProxy)) {
-                ALOGD("Bytes read.");
-                // We have the complete packet. Notify bytes listener.
-                peerProxy->peer->onBytes(peerProxy->credentials,
-                    in->data, in->size);
-                        
-                // Get ready for the next packet.
-                peerProxyExpectHeader(peerProxy);
-            }
-            break;
-        case ACCEPTING_CONNECTION:
-            masterProxyAcceptConnection(peerProxy);
-            break;
-        default:
-            LOG_ALWAYS_FATAL("Unknown state: %d", state);
-    }
-}
-
-static PeerProxy* peerProxyCreate(Peer* peer, Credentials credentials) {
-    PeerProxy* peerProxy = calloc(1, sizeof(PeerProxy));
-    if (peerProxy == NULL) {
-        return NULL;
-    }
-   
-    peerProxy->inputBuffer = bufferCreate(sizeof(Header));
-    if (peerProxy->inputBuffer == NULL) {
-        free(peerProxy);
-        return NULL;
-    }
-
-    peerProxy->peer = peer;
-    peerProxy->credentials = credentials;
-
-    // Initial state == expecting a header.
-    peerProxyExpectHeader(peerProxy); 
-  
-    // Add this proxy to the map. Make sure the key points to the stable memory
-    // inside of the peer proxy itself.
-    pid_t* pid = &(peerProxy->credentials.pid);
-    hashmapPut(peer->peerProxies, pid, peerProxy);
-    return peerProxy;
-}
-
-/** Accepts a connection to the master peer. */
-static void masterAcceptConnection(SelectableFd* listenerFd) {
-    // Accept connection.
-    int socket = accept(listenerFd->fd, NULL, NULL);
-    if (socket == -1) {
-        ALOGW("accept() error: %s", strerror(errno));
-        return;
-    }
-    
-    ALOGD("Accepted connection as fd %d.", socket);
-    
-    // Get credentials.
-    Credentials credentials;
-    struct ucred ucredentials;
-    socklen_t credentialsSize = sizeof(struct ucred);
-    int result = getsockopt(socket, SOL_SOCKET, SO_PEERCRED, 
-                &ucredentials, &credentialsSize);
-    // We might want to verify credentialsSize.
-    if (result == -1) {
-        ALOGW("getsockopt() error: %s", strerror(errno));
-        closeWithWarning(socket);
-        return;
-    }
-
-    // Copy values into our own structure so we know we have the types right.
-    credentials.pid = ucredentials.pid;
-    credentials.uid = ucredentials.uid;
-    credentials.gid = ucredentials.gid;
-    
-    ALOGI("Accepted connection from process %d.", credentials.pid);
-   
-    Peer* masterPeer = (Peer*) listenerFd->data;
-    
-    peerLock(masterPeer);
-    
-    // Make sure we don't already have a connection from that process.
-    PeerProxy* peerProxy 
-        = hashmapGet(masterPeer->peerProxies, &credentials.pid);
-    if (peerProxy != NULL) {
-        peerUnlock(masterPeer);
-        ALOGW("Alread connected to process %d.", credentials.pid);
-        closeWithWarning(socket);
-        return;
-    }
-   
-    // Add connection to the selector.
-    SelectableFd* socketFd = selectorAdd(masterPeer->selector, socket);
-    if (socketFd == NULL) {
-        peerUnlock(masterPeer);
-        ALOGW("malloc() failed.");
-        closeWithWarning(socket);
-        return;
-    }
-
-    // Create a peer proxy.
-    peerProxy = peerProxyCreate(masterPeer, credentials);
-    peerUnlock(masterPeer);
-    if (peerProxy == NULL) {
-        ALOGW("malloc() failed.");
-        socketFd->remove = true;
-        closeWithWarning(socket);
-    }
-    peerProxy->connections = hashmapCreate(10, &pidHash, &pidEquals);
-    peerProxySetFd(peerProxy, socketFd);
-}
-
-/**
- * Creates the local peer.
- */
-static Peer* peerCreate() {
-    Peer* peer = calloc(1, sizeof(Peer));
-    if (peer == NULL) {
-        LOG_ALWAYS_FATAL("malloc() error.");
-    }
-    peer->peerProxies = hashmapCreate(10, &pidHash, &pidEquals);
-    peer->selector = selectorCreate();
-    
-    pthread_mutexattr_t attributes;
-    if (pthread_mutexattr_init(&attributes) != 0) {
-        LOG_ALWAYS_FATAL("pthread_mutexattr_init() error.");
-    }
-    if (pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_RECURSIVE) != 0) {
-        LOG_ALWAYS_FATAL("pthread_mutexattr_settype() error.");
-    }
-    if (pthread_mutex_init(&peer->mutex, &attributes) != 0) {
-        LOG_ALWAYS_FATAL("pthread_mutex_init() error.");
-    }
-    
-    peer->pid = getpid();
-    return peer;
-}
-
-/** The local peer. */
-static Peer* localPeer;
-
-/** Frees a packet of bytes. */
-static void outgoingPacketFreeBytes(OutgoingPacket* packet) {
-    ALOGD("Freeing outgoing packet.");
-    bufferFree(packet->bytes);
-    free(packet);
-}
-
-/**
- * Sends a packet of bytes to a remote peer. Returns 0 on success.
- *
- * Returns -1 if an error occurs. Sets errno to ENOMEM if memory couldn't be
- * allocated. Sets errno to EHOSTDOWN if the peer died recently. Sets errno
- * to EINVAL if pid is the same as the local pid.
- */
-int peerSendBytes(pid_t pid, const char* bytes, size_t size) {
-	Peer* peer = localPeer;
-    assert(peer != NULL);
-
-    OutgoingPacket* packet = calloc(1, sizeof(OutgoingPacket));
-    if (packet == NULL) {
-        errno = ENOMEM;
-        return -1;
-    }
-
-    Buffer* copy = bufferCreate(size); 
-    if (copy == NULL) {
-        free(packet);
-        errno = ENOMEM;
-        return -1;
-    }
-
-    // Copy data.
-    memcpy(copy->data, bytes, size);
-    copy->size = size;
-    
-    packet->bytes = copy;
-    packet->header.type = BYTES;
-    packet->header.size = size;
-    packet->free = outgoingPacketFreeBytes;
-    bufferPrepareForWrite(packet->bytes);
-    
-    peerLock(peer);
-    
-    PeerProxy* peerProxy = peerProxyGetOrCreate(peer, pid, true);
-    if (peerProxy == NULL) {
-        // The peer is already dead or we couldn't alloc memory. Either way,
-        // errno is set.
-        peerUnlock(peer);
-        packet->free(packet); 
-        return -1;
-    } else {
-        peerProxyEnqueueOutgoingPacket(peerProxy, packet);
-        peerUnlock(peer);
-        selectorWakeUp(peer->selector);
-        return 0; 
-    }
-}
-
-/** Keeps track of how to free shared bytes. */
-typedef struct {
-    void (*free)(void* context);
-    void* context;
-} SharedBytesFreer;
-
-/** Frees shared bytes. */
-static void outgoingPacketFreeSharedBytes(OutgoingPacket* packet) {
-    SharedBytesFreer* sharedBytesFreer 
-        = (SharedBytesFreer*) packet->context;
-    sharedBytesFreer->free(sharedBytesFreer->context);
-    free(sharedBytesFreer);
-    free(packet);
-}
-
-/**
- * Sends a packet of bytes to a remote peer without copying the bytes. Calls
- * free() with context after the bytes have been sent.
- *
- * Returns -1 if an error occurs. Sets errno to ENOMEM if memory couldn't be
- * allocated. Sets errno to EHOSTDOWN if the peer died recently. Sets errno
- * to EINVAL if pid is the same as the local pid.
- */
-int peerSendSharedBytes(pid_t pid, char* bytes, size_t size,
-        void (*free)(void* context), void* context) {
-    Peer* peer = localPeer;
-    assert(peer != NULL);
-
-    OutgoingPacket* packet = calloc(1, sizeof(OutgoingPacket));
-    if (packet == NULL) {
-        errno = ENOMEM;
-        return -1;
-    }
-
-    Buffer* wrapper = bufferWrap(bytes, size, size);
-    if (wrapper == NULL) {
-        free(packet);
-        errno = ENOMEM;
-        return -1;
-    }
-
-    SharedBytesFreer* sharedBytesFreer = malloc(sizeof(SharedBytesFreer));
-    if (sharedBytesFreer == NULL) {
-        free(packet);
-        free(wrapper);
-        errno = ENOMEM;
-        return -1;
-    }
-    sharedBytesFreer->free = free;
-    sharedBytesFreer->context = context;
-    
-    packet->bytes = wrapper;
-    packet->context = sharedBytesFreer;
-    packet->header.type = BYTES;
-    packet->header.size = size;
-    packet->free = &outgoingPacketFreeSharedBytes;
-    bufferPrepareForWrite(packet->bytes);
-    
-    peerLock(peer);
-    
-    PeerProxy* peerProxy = peerProxyGetOrCreate(peer, pid, true);
-    if (peerProxy == NULL) {
-        // The peer is already dead or we couldn't alloc memory. Either way,
-        // errno is set.
-        peerUnlock(peer);
-        packet->free(packet); 
-        return -1;
-    } else {
-        peerProxyEnqueueOutgoingPacket(peerProxy, packet);
-        peerUnlock(peer);
-        selectorWakeUp(peer->selector);
-        return 0; 
-    }
-}
-
-/**
- * Starts the master peer. The master peer differs from other peers in that
- * it is responsible for connecting the other peers. You can only have one
- * master peer.
- *
- * Goes into an I/O loop and does not return.
- */
-void masterPeerInitialize(BytesListener* bytesListener, 
-        DeathListener* deathListener) {
-    // Create and bind socket.
-    int listenerSocket = socket(AF_LOCAL, SOCK_STREAM, 0);
-    if (listenerSocket == -1) {
-        LOG_ALWAYS_FATAL("socket() error: %s", strerror(errno));
-    }
-    unlink(MASTER_PATH);
-    int result = bind(listenerSocket, (SocketAddress*) getMasterAddress(), 
-            sizeof(UnixAddress));
-    if (result == -1) {
-        LOG_ALWAYS_FATAL("bind() error: %s", strerror(errno));
-    }
-
-    ALOGD("Listener socket: %d",  listenerSocket);
-    
-    // Queue up to 16 connections.
-    result = listen(listenerSocket, 16);
-    if (result != 0) {
-        LOG_ALWAYS_FATAL("listen() error: %s", strerror(errno));
-    }
-
-    // Make socket non-blocking.
-    setNonBlocking(listenerSocket);
-
-    // Create the peer for this process. Fail if we already have one.
-    if (localPeer != NULL) {
-        LOG_ALWAYS_FATAL("Peer is already initialized.");
-    }
-    localPeer = peerCreate();
-    if (localPeer == NULL) {
-        LOG_ALWAYS_FATAL("malloc() failed.");
-    }
-    localPeer->master = true;
-    localPeer->onBytes = bytesListener;
-    localPeer->onDeath = deathListener;
-    
-    // Make listener socket selectable.
-    SelectableFd* listenerFd = selectorAdd(localPeer->selector, listenerSocket);
-    if (listenerFd == NULL) {
-        LOG_ALWAYS_FATAL("malloc() error.");
-    }
-    listenerFd->data = localPeer;
-    listenerFd->onReadable = &masterAcceptConnection;
-}
-
-/**
- * Starts a local peer.
- *
- * Goes into an I/O loop and does not return.
- */
-void peerInitialize(BytesListener* bytesListener, 
-        DeathListener* deathListener) {
-    // Connect to master peer.
-    int masterSocket = socket(AF_LOCAL, SOCK_STREAM, 0);
-    if (masterSocket == -1) {
-        LOG_ALWAYS_FATAL("socket() error: %s", strerror(errno));
-    }
-    int result = connect(masterSocket, (SocketAddress*) getMasterAddress(),
-            sizeof(UnixAddress));
-    if (result != 0) {
-        LOG_ALWAYS_FATAL("connect() error: %s", strerror(errno));
-    }
-
-    // Create the peer for this process. Fail if we already have one.
-    if (localPeer != NULL) {
-        LOG_ALWAYS_FATAL("Peer is already initialized.");
-    }
-    localPeer = peerCreate();
-    if (localPeer == NULL) {
-        LOG_ALWAYS_FATAL("malloc() failed.");
-    }
-    localPeer->onBytes = bytesListener;
-    localPeer->onDeath = deathListener;
-    
-    // Make connection selectable.
-    SelectableFd* masterFd = selectorAdd(localPeer->selector, masterSocket);
-    if (masterFd == NULL) {
-        LOG_ALWAYS_FATAL("malloc() error.");
-    }
-
-    // Create a peer proxy for the master peer.
-    PeerProxy* masterProxy = peerProxyCreate(localPeer, MASTER_CREDENTIALS);
-    if (masterProxy == NULL) {
-        LOG_ALWAYS_FATAL("malloc() error.");
-    }
-    peerProxySetFd(masterProxy, masterFd);
-    masterProxy->master = true;
-    localPeer->masterProxy = masterProxy;
-}
-
-/** Starts the master peer I/O loop. Doesn't return. */
-void peerLoop() {
-    assert(localPeer != NULL);
-    
-    // Start selector.
-    selectorLoop(localPeer->selector);
-}
-
diff --git a/libcutils/qsort_r_compat.c b/libcutils/qsort_r_compat.c
deleted file mode 100644
index 8971cb5..0000000
--- a/libcutils/qsort_r_compat.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <cutils/qsort_r_compat.h>
-
-#if HAVE_BSD_QSORT_R
-
-/*
- * BSD qsort_r parameter order is as we have defined here.
- */
-
-void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
-        int (*compar)(void*, const void* , const void*)) {
-    qsort_r(base, nel, width, thunk, compar);
-}
-
-#elif HAVE_GNU_QSORT_R
-
-/*
- * GNU qsort_r parameter order places the thunk parameter last.
- */
-
-struct compar_data {
-    void* thunk;
-    int (*compar)(void*, const void* , const void*);
-};
-
-static int compar_wrapper(const void* a, const void* b, void* data) {
-    struct compar_data* compar_data = (struct compar_data*)data;
-    return compar_data->compar(compar_data->thunk, a, b);
-}
-
-void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
-        int (*compar)(void*, const void* , const void*)) {
-    struct compar_data compar_data;
-    compar_data.thunk = thunk;
-    compar_data.compar = compar;
-    qsort_r(base, nel, width, compar_wrapper, &compar_data);
-}
-
-#else
-
-/*
- * Emulate qsort_r using thread local storage to access the thunk data.
- */
-
-#include <cutils/threads.h>
-
-static thread_store_t compar_data_key = THREAD_STORE_INITIALIZER;
-
-struct compar_data {
-    void* thunk;
-    int (*compar)(void*, const void* , const void*);
-};
-
-static int compar_wrapper(const void* a, const void* b) {
-    struct compar_data* compar_data = (struct compar_data*)thread_store_get(&compar_data_key);
-    return compar_data->compar(compar_data->thunk, a, b);
-}
-
-void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
-        int (*compar)(void*, const void* , const void*)) {
-    struct compar_data compar_data;
-    compar_data.thunk = thunk;
-    compar_data.compar = compar;
-    thread_store_set(&compar_data_key, &compar_data, NULL);
-    qsort(base, nel, width, compar_wrapper);
-}
-
-#endif
diff --git a/libcutils/record_stream.c b/libcutils/record_stream.c
deleted file mode 100644
index 6994904..0000000
--- a/libcutils/record_stream.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/* libs/cutils/record_stream.c
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <assert.h>
-#include <errno.h>
-#include <cutils/record_stream.h>
-#include <string.h>
-#include <stdint.h>
-#ifdef HAVE_WINSOCK
-#include <winsock2.h>   /* for ntohl */
-#else
-#include <netinet/in.h>
-#endif
-
-#define HEADER_SIZE 4
-
-struct RecordStream {
-    int fd;
-    size_t maxRecordLen;
-
-    unsigned char *buffer;
-
-    unsigned char *unconsumed;
-    unsigned char *read_end;
-    unsigned char *buffer_end;
-};
-
-
-extern RecordStream *record_stream_new(int fd, size_t maxRecordLen)
-{
-    RecordStream *ret;
-
-    assert (maxRecordLen <= 0xffff);
-
-    ret = (RecordStream *)calloc(1, sizeof(RecordStream));
-
-    ret->fd = fd;
-    ret->maxRecordLen = maxRecordLen;
-    ret->buffer = (unsigned char *)malloc (maxRecordLen + HEADER_SIZE);
-    
-    ret->unconsumed = ret->buffer;
-    ret->read_end = ret->buffer;
-    ret->buffer_end = ret->buffer + maxRecordLen + HEADER_SIZE;
-
-    return ret;
-}
-
-
-extern void record_stream_free(RecordStream *rs)
-{
-    free(rs->buffer);
-    free(rs);
-}
-
-
-/* returns NULL; if there isn't a full record in the buffer */
-static unsigned char * getEndOfRecord (unsigned char *p_begin,
-                                            unsigned char *p_end)
-{
-    size_t len;
-    unsigned char * p_ret;
-
-    if (p_end < p_begin + HEADER_SIZE) {
-        return NULL;
-    }
-
-    //First four bytes are length
-    len = ntohl(*((uint32_t *)p_begin));
-
-    p_ret = p_begin + HEADER_SIZE + len;
-
-    if (p_end < p_ret) {
-        return NULL;
-    }
-
-    return p_ret;
-}
-
-static void *getNextRecord (RecordStream *p_rs, size_t *p_outRecordLen)
-{
-    unsigned char *record_start, *record_end;
-
-    record_end = getEndOfRecord (p_rs->unconsumed, p_rs->read_end);
-
-    if (record_end != NULL) {
-        /* one full line in the buffer */
-        record_start = p_rs->unconsumed + HEADER_SIZE;
-        p_rs->unconsumed = record_end;
-
-        *p_outRecordLen = record_end - record_start;
-
-        return record_start;
-    }
-
-    return NULL;
-}
-
-/**
- * Reads the next record from stream fd
- * Records are prefixed by a 16-bit big endian length value
- * Records may not be larger than maxRecordLen
- *
- * Doesn't guard against EINTR
- *
- * p_outRecord and p_outRecordLen may not be NULL
- *
- * Return 0 on success, -1 on fail
- * Returns 0 with *p_outRecord set to NULL on end of stream
- * Returns -1 / errno = EAGAIN if it needs to read again
- */
-int record_stream_get_next (RecordStream *p_rs, void ** p_outRecord, 
-                                    size_t *p_outRecordLen)
-{
-    void *ret;
-
-    ssize_t countRead;
-
-    /* is there one record already in the buffer? */
-    ret = getNextRecord (p_rs, p_outRecordLen);
-
-    if (ret != NULL) {
-        *p_outRecord = ret;
-        return 0;
-    }
-
-    // if the buffer is full and we don't have a full record
-    if (p_rs->unconsumed == p_rs->buffer 
-        && p_rs->read_end == p_rs->buffer_end
-    ) {
-        // this should never happen
-        //ALOGE("max record length exceeded\n");
-        assert (0);
-        errno = EFBIG;
-        return -1;
-    }
-
-    if (p_rs->unconsumed != p_rs->buffer) {
-        // move remainder to the beginning of the buffer
-        size_t toMove;
-
-        toMove = p_rs->read_end - p_rs->unconsumed;
-        if (toMove) {
-            memmove(p_rs->buffer, p_rs->unconsumed, toMove);
-        }
-
-        p_rs->read_end = p_rs->buffer + toMove;
-        p_rs->unconsumed = p_rs->buffer;
-    }
-
-    countRead = read (p_rs->fd, p_rs->read_end, p_rs->buffer_end - p_rs->read_end);
-
-    if (countRead <= 0) {
-        /* note: end-of-stream drops through here too */
-        *p_outRecord = NULL;
-        return countRead;
-    }
-
-    p_rs->read_end += countRead;
-
-    ret = getNextRecord (p_rs, p_outRecordLen);
-
-    if (ret == NULL) {
-        /* not enough of a buffer to for a whole command */
-        errno = EAGAIN;
-        return -1;
-    }
-
-    *p_outRecord = ret;        
-    return 0;
-}
diff --git a/libcutils/selector.c b/libcutils/selector.c
deleted file mode 100644
index 3776bbb..0000000
--- a/libcutils/selector.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "selector"
-
-#include <assert.h>
-#include <errno.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <cutils/array.h>
-#include <cutils/selector.h>
-
-#include "loghack.h"
-
-struct Selector {
-    Array* selectableFds;
-    bool looping;
-    fd_set readFds;
-    fd_set writeFds;
-    fd_set exceptFds;
-    int maxFd;
-    int wakeupPipe[2];
-    SelectableFd* wakeupFd;
-
-    bool inSelect;
-    pthread_mutex_t inSelectLock; 
-};
-
-/** Reads and ignores wake up data. */ 
-static void eatWakeupData(SelectableFd* wakeupFd) {
-    static char garbage[64];
-    if (read(wakeupFd->fd, garbage, sizeof(garbage)) < 0) {
-        if (errno == EINTR) {
-            ALOGI("read() interrupted.");    
-        } else {
-            LOG_ALWAYS_FATAL("This should never happen: %s", strerror(errno));
-        }
-    }
-}
-
-static void setInSelect(Selector* selector, bool inSelect) {
-    pthread_mutex_lock(&selector->inSelectLock);
-    selector->inSelect = inSelect;
-    pthread_mutex_unlock(&selector->inSelectLock);
-}
-
-static bool isInSelect(Selector* selector) {
-    pthread_mutex_lock(&selector->inSelectLock);
-    bool inSelect = selector->inSelect;
-    pthread_mutex_unlock(&selector->inSelectLock);
-    return inSelect;
-}
-
-void selectorWakeUp(Selector* selector) {
-    if (!isInSelect(selector)) {
-        // We only need to write wake-up data if we're blocked in select().
-        return;
-    }
-    
-    static char garbage[1];
-    if (write(selector->wakeupPipe[1], garbage, sizeof(garbage)) < 0) {
-        if (errno == EINTR) {
-            ALOGI("read() interrupted.");    
-        } else {
-            LOG_ALWAYS_FATAL("This should never happen: %s", strerror(errno));
-        }
-    }
-}
-
-Selector* selectorCreate(void) {
-    Selector* selector = calloc(1, sizeof(Selector));
-    if (selector == NULL) {
-        LOG_ALWAYS_FATAL("malloc() error.");
-    }
-    selector->selectableFds = arrayCreate();
-    
-    // Set up wake-up pipe.
-    if (pipe(selector->wakeupPipe) < 0) {
-        LOG_ALWAYS_FATAL("pipe() error: %s", strerror(errno));
-    }
-    
-    ALOGD("Wakeup fd: %d", selector->wakeupPipe[0]);
-    
-    SelectableFd* wakeupFd = selectorAdd(selector, selector->wakeupPipe[0]);
-    if (wakeupFd == NULL) {
-        LOG_ALWAYS_FATAL("malloc() error.");
-    }
-    wakeupFd->onReadable = &eatWakeupData; 
-    
-    pthread_mutex_init(&selector->inSelectLock, NULL);
-
-    return selector;
-}
-
-SelectableFd* selectorAdd(Selector* selector, int fd) {
-    assert(selector != NULL);
-
-    SelectableFd* selectableFd = calloc(1, sizeof(SelectableFd));
-    if (selectableFd != NULL) {
-        selectableFd->selector = selector;
-        selectableFd->fd = fd;
-    
-        arrayAdd(selector->selectableFds, selectableFd);
-    }
-
-    return selectableFd;
-}
-
-/**
- * Adds an fd to the given set if the callback is non-null. Returns true
- * if the fd was added.
- */
-static inline bool maybeAdd(SelectableFd* selectableFd,
-        void (*callback)(SelectableFd*), fd_set* fdSet) {
-    if (callback != NULL) {
-        FD_SET(selectableFd->fd, fdSet);
-        return true;
-    }
-    return false;
-}
-
-/**
- * Removes stale file descriptors and initializes file descriptor sets.
- */
-static void prepareForSelect(Selector* selector) {
-    fd_set* exceptFds = &selector->exceptFds;
-    fd_set* readFds = &selector->readFds;
-    fd_set* writeFds = &selector->writeFds;
-    
-    FD_ZERO(exceptFds);
-    FD_ZERO(readFds);
-    FD_ZERO(writeFds);
-
-    Array* selectableFds = selector->selectableFds;
-    int i = 0;
-    selector->maxFd = 0;
-    int size = arraySize(selectableFds);
-    while (i < size) {
-        SelectableFd* selectableFd = arrayGet(selectableFds, i);
-        if (selectableFd->remove) {
-            // This descriptor should be removed.
-            arrayRemove(selectableFds, i);
-            size--;
-            if (selectableFd->onRemove != NULL) {
-                selectableFd->onRemove(selectableFd);
-            }
-            free(selectableFd);
-        } else {
-            if (selectableFd->beforeSelect != NULL) {
-                selectableFd->beforeSelect(selectableFd);
-            }
-            
-            bool inSet = false;
-            if (maybeAdd(selectableFd, selectableFd->onExcept, exceptFds)) {
-                ALOGD("Selecting fd %d for writing...", selectableFd->fd);
-                inSet = true;
-            }
-            if (maybeAdd(selectableFd, selectableFd->onReadable, readFds)) {
-                ALOGD("Selecting fd %d for reading...", selectableFd->fd);
-                inSet = true;
-            }
-            if (maybeAdd(selectableFd, selectableFd->onWritable, writeFds)) {
-                inSet = true;
-            }
-
-            if (inSet) {
-                // If the fd is in a set, check it against max.
-                int fd = selectableFd->fd;
-                if (fd > selector->maxFd) {
-                    selector->maxFd = fd;
-                }
-            }
-            
-            // Move to next descriptor.
-            i++;
-        }
-    }
-}
-
-/**
- * Invokes a callback if the callback is non-null and the fd is in the given
- * set.
- */
-static inline void maybeInvoke(SelectableFd* selectableFd,
-        void (*callback)(SelectableFd*), fd_set* fdSet) {
-    if (callback != NULL && !selectableFd->remove && 
-            FD_ISSET(selectableFd->fd, fdSet)) {
-        ALOGD("Selected fd %d.", selectableFd->fd);
-        callback(selectableFd);
-    }
-}
-
-/**
- * Notifies user if file descriptors are readable or writable, or if
- * out-of-band data is present.
- */
-static void fireEvents(Selector* selector) {
-    Array* selectableFds = selector->selectableFds;
-    int size = arraySize(selectableFds);
-    int i;
-    for (i = 0; i < size; i++) {
-        SelectableFd* selectableFd = arrayGet(selectableFds, i);
-        maybeInvoke(selectableFd, selectableFd->onExcept,
-                &selector->exceptFds);
-        maybeInvoke(selectableFd, selectableFd->onReadable,
-                &selector->readFds);
-        maybeInvoke(selectableFd, selectableFd->onWritable,
-                &selector->writeFds);
-    }
-}
-
-void selectorLoop(Selector* selector) {
-    // Make sure we're not already looping.
-    if (selector->looping) {
-        LOG_ALWAYS_FATAL("Already looping.");
-    }
-    selector->looping = true;
-    
-    while (true) {
-        setInSelect(selector, true);
-        
-        prepareForSelect(selector);
-
-        ALOGD("Entering select().");
-        
-        // Select file descriptors.
-        int result = select(selector->maxFd + 1, &selector->readFds, 
-                &selector->writeFds, &selector->exceptFds, NULL);
-        
-        ALOGD("Exiting select().");
-        
-        setInSelect(selector, false);
-        
-        if (result == -1) {
-            // Abort on everything except EINTR.
-            if (errno == EINTR) {
-                ALOGI("select() interrupted.");    
-            } else {
-                LOG_ALWAYS_FATAL("select() error: %s", 
-                        strerror(errno));
-            }
-        } else if (result > 0) {
-            fireEvents(selector);
-        }
-    }
-}
diff --git a/libcutils/zygote.c b/libcutils/zygote.c
deleted file mode 100644
index 37236e8..0000000
--- a/libcutils/zygote.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Zygote"
-
-#include <cutils/sockets.h>
-#include <cutils/zygote.h>
-#include <cutils/log.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <time.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <arpa/inet.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#define ZYGOTE_SOCKET "zygote"
-
-#define ZYGOTE_RETRY_COUNT 1000
-#define ZYGOTE_RETRY_MILLIS 500
-
-static void replace_nl(char *str);
-
-/*
- * If sendStdio is non-zero, the current process's stdio file descriptors
- * will be sent and inherited by the spawned process.
- */
-static int send_request(int fd, int sendStdio, int argc, const char **argv)
-{
-#ifndef HAVE_ANDROID_OS
-    // not supported on simulator targets
-    //ALOGE("zygote_* not supported on simulator targets");
-    return -1;
-#else /* HAVE_ANDROID_OS */
-    uint32_t pid;
-    int i;
-    struct iovec ivs[2];
-    struct msghdr msg;
-    char argc_buffer[12];
-    const char *newline_string = "\n";
-    struct cmsghdr *cmsg;
-    char msgbuf[CMSG_SPACE(sizeof(int) * 3)];
-    int *cmsg_payload;
-    ssize_t ret;
-
-    memset(&msg, 0, sizeof(msg));
-    memset(&ivs, 0, sizeof(ivs));
-
-    // First line is arg count 
-    snprintf(argc_buffer, sizeof(argc_buffer), "%d\n", argc);
-
-    ivs[0].iov_base = argc_buffer;
-    ivs[0].iov_len = strlen(argc_buffer);
-
-    msg.msg_iov = ivs;
-    msg.msg_iovlen = 1;
-
-    if (sendStdio != 0) {
-        // Pass the file descriptors with the first write
-        msg.msg_control = msgbuf;
-        msg.msg_controllen = sizeof msgbuf;
-
-        cmsg = CMSG_FIRSTHDR(&msg);
-
-        cmsg->cmsg_len = CMSG_LEN(3 * sizeof(int));
-        cmsg->cmsg_level = SOL_SOCKET;
-        cmsg->cmsg_type = SCM_RIGHTS;
-
-        cmsg_payload = (int *)CMSG_DATA(cmsg);
-        cmsg_payload[0] = STDIN_FILENO;
-        cmsg_payload[1] = STDOUT_FILENO;
-        cmsg_payload[2] = STDERR_FILENO;
-    }
-
-    do {
-        ret = sendmsg(fd, &msg, MSG_NOSIGNAL);
-    } while (ret < 0 && errno == EINTR);
-
-    if (ret < 0) {
-        return -1;
-    }
-
-    // Only send the fd's once
-    msg.msg_control = NULL;
-    msg.msg_controllen = 0;
-
-    // replace any newlines with spaces and send the args
-    for (i = 0; i < argc; i++) {
-        char *tofree = NULL;
-        const char *toprint;
-
-        toprint = argv[i];
-
-        if (strchr(toprint, '\n') != NULL) {
-            tofree = strdup(toprint);
-            toprint = tofree;
-            replace_nl(tofree);
-        }
-
-        ivs[0].iov_base = (char *)toprint;
-        ivs[0].iov_len = strlen(toprint);
-        ivs[1].iov_base = (char *)newline_string;
-        ivs[1].iov_len = 1;
-
-        msg.msg_iovlen = 2;
-
-        do {
-            ret = sendmsg(fd, &msg, MSG_NOSIGNAL);
-        } while (ret < 0 && errno == EINTR);
-
-        if (tofree != NULL) {
-            free(tofree);
-        }
-
-        if (ret < 0) {
-            return -1;
-        }
-    }
-
-    // Read the pid, as a 4-byte network-order integer
-
-    ivs[0].iov_base = &pid;
-    ivs[0].iov_len = sizeof(pid);
-    msg.msg_iovlen = 1;
-
-    do {
-        do {
-            ret = recvmsg(fd, &msg, MSG_NOSIGNAL | MSG_WAITALL);
-        } while (ret < 0 && errno == EINTR);
-
-        if (ret < 0) {
-            return -1;
-        }
-
-        ivs[0].iov_len -= ret;
-        ivs[0].iov_base += ret;
-    } while (ivs[0].iov_len > 0);
-
-    pid = ntohl(pid);
-
-    return pid;
-#endif /* HAVE_ANDROID_OS */
-}
-
-/**
- * Spawns a new dalvik instance via the Zygote process. The non-zygote
- * arguments are passed to com.android.internal.os.RuntimeInit(). The
- * first non-option argument should be a class name in the system class path.
- *
- * The arg list  may start with zygote params such as --set-uid.
- *
- * If sendStdio is non-zero, the current process's stdio file descriptors
- * will be sent and inherited by the spawned process.
- *
- * The pid of the child process is returned, or -1 if an error was 
- * encountered.
- *
- * zygote_run_oneshot waits up to ZYGOTE_RETRY_COUNT * 
- * ZYGOTE_RETRY_MILLIS for the zygote socket to be available.
- */
-int zygote_run_oneshot(int sendStdio, int argc, const char **argv) 
-{
-    int fd = -1;
-    int err;
-    int i;
-    int retries;
-    int pid;
-    const char **newargv = argv;
-    const int newargc = argc;
-
-    for (retries = 0; (fd < 0) && (retries < ZYGOTE_RETRY_COUNT); retries++) {
-        if (retries > 0) { 
-            struct timespec ts;
-
-            memset(&ts, 0, sizeof(ts));
-            ts.tv_nsec = ZYGOTE_RETRY_MILLIS * 1000 * 1000;
-
-            do {
-                err = nanosleep (&ts, &ts);
-            } while (err < 0 && errno == EINTR);
-        }
-        fd = socket_local_client(ZYGOTE_SOCKET, AF_LOCAL, 
-                ANDROID_SOCKET_NAMESPACE_RESERVED);
-    }
-
-    if (fd < 0) {
-        return -1;
-    }
-
-    pid = send_request(fd, 0, newargc, newargv);
-
-    do {
-        err = close(fd);
-    } while (err < 0 && errno == EINTR);
-
-    return pid;
-}
-
-/**
- * Replaces all occurrances of newline with space.
- */
-static void replace_nl(char *str)
-{
-    for(; *str; str++) {
-        if (*str == '\n') {
-            *str = ' ';
-        }
-    }
-}
-
-
-