/* Prints info about every port common to both tasks in X, but only if the port in X->from_task has a type in ONLY, to STREAM. */ error_t print_xlated_task_ports_info (struct port_name_xlator *x, mach_port_type_t only, unsigned show, FILE *stream) { mach_port_t *names = 0; mach_port_type_t *types = 0; mach_msg_type_number_t names_len = 0, types_len = 0, i; error_t err = mach_port_names (x->from_task, &names, &names_len, &types, &types_len); if (err) return err; for (i = 0; i < names_len; i++) if (types[i] & only) print_xlated_port_info (names[i], types[i], x, show, stream); munmap ((caddr_t) names, names_len * sizeof *names); munmap ((caddr_t) types, types_len * sizeof *types); return 0; }
int main (int argc, char **argv) { error_t err; task_t task; int search = 0; unsigned show = 0; /* what info we print */ mach_port_type_t only = 0, target_only = 0; /* Which names to show */ task_t xlate_task = MACH_PORT_NULL; int no_translation_errors = 0; /* inhibit complaints about bad names */ struct port_name_xlator *xlator = 0; /* Parse our options... */ error_t parse_opt (int key, char *arg, struct argp_state *state) { switch (key) { case 'v': show |= PORTINFO_DETAILS; break; case 'm': show |= PORTINFO_MEMBERS; break; case 'x': show |= PORTINFO_HEX_NAMES; break; case 'r': only |= MACH_PORT_TYPE_RECEIVE; break; case 's': only |= MACH_PORT_TYPE_SEND; break; case 'o': only |= MACH_PORT_TYPE_SEND_ONCE; break; case 'd': only |= MACH_PORT_TYPE_DEAD_NAME; break; case 'p': only |= MACH_PORT_TYPE_PORT_SET; break; case 'R': target_only |= MACH_PORT_TYPE_RECEIVE; break; case 'S': target_only |= MACH_PORT_TYPE_SEND; break; case 'O': target_only |= MACH_PORT_TYPE_SEND_ONCE; break; case 't': xlate_task = parse_task (arg); break; case 'a': search = 1; break; case 'E': no_translation_errors = 1; break; case '*': hold = 1; while (hold) sleep (1); break; case ARGP_KEY_NO_ARGS: argp_usage (state); return EINVAL; case ARGP_KEY_ARG: if (state->arg_num == 0) /* The task */ { task = parse_task (arg); if (only == 0) only = ~0; if (target_only == 0) target_only = ~0; if (xlate_task != MACH_PORT_NULL) { if (search) argp_error (state, "Both --search and --translate specified"); err = port_name_xlator_create (task, xlate_task, &xlator); if (err) error (13, err, "Cannot setup task translation"); } if (state->next == state->argc) /* No port names specified, print all of them. */ { if (xlator) err = print_xlated_task_ports_info (xlator, only, show, stdout); else err = print_task_ports_info (task, only, show, stdout); if (err) error (12, err, "%s", arg); } break; } /* A port name */ { char *end; mach_port_t name = strtoul (arg, &end, 0); if (name == 0) error (0, 0, "%s: Invalid port name", arg); else { if (xlator) { err = print_xlated_port_info (name, 0, xlator, show, stdout); if (err && no_translation_errors) break; } else err = print_port_info (name, 0, task, show, stdout); if (err) error (0, err, "%s", arg); } } break; default: return ARGP_ERR_UNKNOWN; } return 0; } const struct argp argp = { options, parse_opt, args_doc, doc }; /* Parse our arguments. */ argp_parse (&argp, argc, argv, 0, 0, 0); exit (0); }