]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/ipc/ipc_pset.c
xnu-2782.10.72.tar.gz
[apple/xnu.git] / osfmk / ipc / ipc_pset.c
index e2e6a65987c24f2dc13efbf5a226f0dafcb47293..533ee3f08a67453003d642e7566d171bca6dfb65 100644 (file)
@@ -107,10 +107,11 @@ ipc_pset_alloc(
                              &name, (ipc_object_t *) &pset);
        if (kr != KERN_SUCCESS)
                return kr;
-       /* pset is locked */
+       /* pset and space are locked */
 
        pset->ips_local_name = name;
        ipc_mqueue_init(&pset->ips_messages, TRUE /* set */);
+       is_write_unlock(space);
 
        *namep = name;
        *psetp = pset;
@@ -429,7 +430,8 @@ filt_machport(
         * provided, just force a MACH_RCV_TOO_LARGE to detect the
         * name of the port and sizeof the waiting message.
         */
-       option = kn->kn_sfflags & (MACH_RCV_MSG|MACH_RCV_LARGE|MACH_RCV_TRAILER_MASK);
+       option = kn->kn_sfflags & (MACH_RCV_MSG|MACH_RCV_LARGE|MACH_RCV_LARGE_IDENTITY|
+                                  MACH_RCV_TRAILER_MASK|MACH_RCV_VOUCHER);
        if (option & MACH_RCV_MSG) {
                self->ith_msg_addr = (mach_vm_address_t) kn->kn_ext[0];
                size = (mach_msg_size_t)kn->kn_ext[1];
@@ -453,7 +455,7 @@ filt_machport(
        self->ith_receiver_name = MACH_PORT_NULL;
        self->ith_continuation = NULL;
        option |= MACH_RCV_TIMEOUT; // never wait
-       assert((self->ith_state = MACH_RCV_IN_PROGRESS) == MACH_RCV_IN_PROGRESS);
+       self->ith_state = MACH_RCV_IN_PROGRESS;
 
        wresult = ipc_mqueue_receive_on_thread(
                        &pset->ips_messages,
@@ -492,10 +494,20 @@ filt_machport(
         * the results in the fflags field.
         */
        assert(option & MACH_RCV_MSG);
-        kn->kn_data = MACH_PORT_NULL;
        kn->kn_ext[1] = self->ith_msize;
+       kn->kn_data = MACH_PORT_NULL;
        kn->kn_fflags = mach_msg_receive_results();
        /* kmsg and pset reference consumed */
+
+       /*
+        * if the user asked for the identity of ports containing a
+        * a too-large message, return it in the data field (as we
+        * do for messages we didn't try to receive).
+        */
+        if ((kn->kn_fflags == MACH_RCV_TOO_LARGE) &&
+           (option & MACH_RCV_LARGE_IDENTITY))
+           kn->kn_data = self->ith_receiver_name;
+
        return 1;
 }
 
@@ -506,6 +518,8 @@ filt_machporttouch(struct knote *kn, struct kevent64_s *kev, long type)
         case EVENT_REGISTER:
                 kn->kn_sfflags = kev->fflags;
                 kn->kn_sdata = kev->data;
+               kn->kn_ext[0] = kev->ext[0];
+               kn->kn_ext[1] = kev->ext[1];
                 break;
         case EVENT_PROCESS:
                 *kev = kn->kn_kevent;
@@ -543,5 +557,5 @@ filt_machportpeek(struct knote *kn)
         ipc_pset_t              pset = kn->kn_ptr.p_pset;
        ipc_mqueue_t            set_mq = &pset->ips_messages;
 
-       return (ipc_mqueue_peek(set_mq));
+       return (ipc_mqueue_set_peek(set_mq));
 }