donut snapshot
diff --git a/libs/utils/Parcel.cpp b/libs/utils/Parcel.cpp
index 0f4b647..b0e3750 100644
--- a/libs/utils/Parcel.cpp
+++ b/libs/utils/Parcel.cpp
@@ -409,12 +409,16 @@
             mObjects[idx++] = off;
             mObjectsSize++;
 
-            const flat_binder_object* flat
+            flat_binder_object* flat
                 = reinterpret_cast<flat_binder_object*>(mData + off);
             acquire_object(proc, *flat, this);
 
-            // take note if the object is a file descriptor
             if (flat->type == BINDER_TYPE_FD) {
+                // If this is a file descriptor, we need to dup it so the
+                // new Parcel now owns its own fd, and can declare that we
+                // officially know we have fds.
+                flat->handle = dup(flat->handle);
+                flat->cookie = (void*)1;
                 mHasFds = mFdsKnown = true;
             }
         }
@@ -650,28 +654,26 @@
     return flatten_binder(ProcessState::self(), val, this);
 }
 
-status_t Parcel::writeNativeHandle(const native_handle& handle)
+status_t Parcel::writeNativeHandle(const native_handle* handle)
 {
-    if (handle.version != sizeof(native_handle))
+    if (handle->version != sizeof(native_handle))
         return BAD_TYPE;
 
     status_t err;
-    err = writeInt32(handle.numFds);
+    err = writeInt32(handle->numFds);
     if (err != NO_ERROR) return err;
 
-    err = writeInt32(handle.numInts);
+    err = writeInt32(handle->numInts);
     if (err != NO_ERROR) return err;
 
-    for (int i=0 ; err==NO_ERROR && i<handle.numFds ; i++)
-        err = writeDupFileDescriptor(handle.data[i]);
+    for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)
+        err = writeDupFileDescriptor(handle->data[i]);
 
     if (err != NO_ERROR) {
         LOGD("write native handle, write dup fd failed");
         return err;
     }
-
-    err = write(handle.data + handle.numFds, sizeof(int)*handle.numInts);
-
+    err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
     return err;
 }
 
@@ -928,7 +930,7 @@
 }
 
 
-native_handle* Parcel::readNativeHandle(native_handle* (*alloc)(void*, int, int), void* cookie) const
+native_handle* Parcel::readNativeHandle() const
 {
     int numFds, numInts;
     status_t err;
@@ -937,31 +939,15 @@
     err = readInt32(&numInts);
     if (err != NO_ERROR) return 0;
 
-    native_handle* h;
-    if (alloc == 0) {
-        size_t size = sizeof(native_handle) + sizeof(int)*(numFds + numInts);
-        h = (native_handle*)malloc(size); 
-        h->version = sizeof(native_handle);
-        h->numFds = numFds;
-        h->numInts = numInts;
-    } else {
-        h = alloc(cookie, numFds, numInts);
-        if (h->version != sizeof(native_handle)) {
-            return 0;
-        }
-    }
-    
+    native_handle* h = native_handle_create(numFds, numInts);
     for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
         h->data[i] = dup(readFileDescriptor());
         if (h->data[i] < 0) err = BAD_VALUE;
     }
-    
     err = read(h->data + numFds, sizeof(int)*numInts);
-    
     if (err != NO_ERROR) {
-        if (alloc == 0) {
-            free(h);
-        }
+        native_handle_close(h);
+        native_handle_delete(h);
         h = 0;
     }
     return h;