void Port::dump(const char *descr) { if (mPort == MACH_PORT_NULL) { Debug::dump("[%s==NULL]\n", descr ? descr : "port"); } else { Debug::dump("[%s(%d)", descr ? descr : "port", mPort); mach_port_type_t type; if (kern_return_t err = mach_port_type(self(), mPort, &type)) { Debug::dump(" !%s", mach_error_string(err)); } else { if (type & MACH_PORT_TYPE_SEND) Debug::dump(" send(%d)", getRefs(MACH_PORT_RIGHT_SEND)); if (type & MACH_PORT_TYPE_RECEIVE) Debug::dump(" rcv"); if (type & MACH_PORT_TYPE_SEND_ONCE) Debug::dump(" once(%d)", getRefs(MACH_PORT_RIGHT_SEND)); if (type & MACH_PORT_TYPE_PORT_SET) Debug::dump(" set"); if (type & MACH_PORT_TYPE_DEAD_NAME) Debug::dump(" dead(%d)", getRefs(MACH_PORT_RIGHT_SEND)); if (type & MACH_PORT_TYPE_DNREQUEST) Debug::dump(" dnreq"); // handle unknown/unexpected type flags if (type & ~(MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_RECEIVE|MACH_PORT_TYPE_SEND_ONCE| MACH_PORT_TYPE_PORT_SET|MACH_PORT_TYPE_DEAD_NAME|MACH_PORT_TYPE_DNREQUEST)) Debug::dump(" type(0x%x)", type); } Debug::dump("]\n"); } }
void test_mach_debug_port(mach_port_t name, const char *str, unsigned int line) { mach_port_type_t type; mach_msg_bits_t ns = 0, nr = 0, nso = 0, nd = 0; unsigned int dnreqs = 0, dnrsiz; kern_return_t kr = mach_port_type(mach_task_self(), name, &type); if (kr) { fprintf(stderr, "machport[0x%08x] = { error(0x%x) \"%s\" }: %s %u\n", name, kr, mach_error_string(kr), str, line); return; } if (type & MACH_PORT_TYPE_SEND) { test_mach_assume_zero(mach_port_get_refs(mach_task_self(), name, MACH_PORT_RIGHT_SEND, &ns)); } if (type & MACH_PORT_TYPE_SEND_ONCE) { test_mach_assume_zero(mach_port_get_refs(mach_task_self(), name, MACH_PORT_RIGHT_SEND_ONCE, &nso)); } if (type & MACH_PORT_TYPE_DEAD_NAME) { test_mach_assume_zero(mach_port_get_refs(mach_task_self(), name, MACH_PORT_RIGHT_DEAD_NAME, &nd)); } if (type & (MACH_PORT_TYPE_RECEIVE|MACH_PORT_TYPE_SEND)) { test_mach_assume_zero(mach_port_dnrequest_info(mach_task_self(), name, &dnrsiz, &dnreqs)); } if (type & MACH_PORT_TYPE_RECEIVE) { mach_port_status_t status = { .mps_pset = 0, }; mach_msg_type_number_t cnt = MACH_PORT_RECEIVE_STATUS_COUNT; test_mach_assume_zero(mach_port_get_refs(mach_task_self(), name, MACH_PORT_RIGHT_RECEIVE, &nr)); test_mach_assume_zero(mach_port_get_attributes(mach_task_self(), name, MACH_PORT_RECEIVE_STATUS, (void*)&status, &cnt)); fprintf(stderr, "machport[0x%08x] = { R(%03u) S(%03u) SO(%03u) D(%03u) " "dnreqs(%03u) spreq(%s) nsreq(%s) pdreq(%s) srights(%s) " "sorights(%03u) qlim(%03u) msgcount(%03u) mkscount(%03u) " "seqno(%03u) }: %s %u\n", name, nr, ns, nso, nd, dnreqs, type & MACH_PORT_TYPE_SPREQUEST ? "Y":"N", status.mps_nsrequest ? "Y":"N", status.mps_pdrequest ? "Y":"N", status.mps_srights ? "Y":"N", status.mps_sorights, status.mps_qlimit, status.mps_msgcount, status.mps_mscount, status.mps_seqno, str, line); } else if (type & (MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_SEND_ONCE|
/* Translate the port FROM between the tasks in X, returning the translated name in TO, and the types of TO in TO_TYPE, or an error. If TYPE is non-zero, it should be what mach_port_type returns for FROM. */ error_t port_name_xlator_xlate (struct port_name_xlator *x, mach_port_t from, mach_port_type_t from_type, mach_port_t *to, mach_port_type_t *to_type) { error_t err; mach_port_t port; mach_msg_type_number_t i; mach_msg_type_name_t aquired_type; mach_msg_type_name_t valid_to_types; if (from_type == 0) { error_t err = mach_port_type (x->from_task, from, &from_type); if (err) return err; } if (from_type & MACH_PORT_TYPE_RECEIVE) valid_to_types = MACH_PORT_TYPE_SEND; else if (from_type & MACH_PORT_TYPE_SEND) valid_to_types = MACH_PORT_TYPE_SEND | MACH_PORT_TYPE_RECEIVE; else return EKERN_INVALID_RIGHT; /* Translate the name FROM, in FROM_TASK's namespace into our namespace. */ err = mach_port_extract_right (x->from_task, from, ((from_type & MACH_PORT_TYPE_RECEIVE) ? MACH_MSG_TYPE_MAKE_SEND : MACH_MSG_TYPE_COPY_SEND), &port, &aquired_type); if (err) return err; /* Look for likely candidates in TO_TASK's namespace to test against PORT. */ for (i = 0; i < x->to_names_len; i++) { if (x->ports[i] == MACH_PORT_NULL && (x->to_types[i] & valid_to_types)) /* Port I shows possibilities... */ { err = mach_port_extract_right (x->to_task, x->to_names[i], ((x->to_types[i] & MACH_PORT_TYPE_RECEIVE) ? MACH_MSG_TYPE_MAKE_SEND : MACH_MSG_TYPE_COPY_SEND), &x->ports[i], &aquired_type); if (err) x->to_types[i] = 0; /* Don't try to fetch this port again. */ } if (x->ports[i] == port) /* We win! Port I in TO_TASK is the same as PORT. */ break; } mach_port_deallocate (mach_task_self (), port); if (i < x->to_names_len) /* Port I is the right translation; return its name in TO_TASK. */ { *to = x->to_names[i]; *to_type = x->to_types[i]; return 0; } else return EKERN_INVALID_NAME; }