bool hfp_hf_register(struct hfp_hf *hfp, hfp_hf_result_func_t callback, const char *prefix, void *user_data, hfp_destroy_func_t destroy) { struct event_handler *handler; if (!callback) return false; handler = new0(struct event_handler, 1); if (!handler) return false; handler->callback = callback; handler->user_data = user_data; handler->prefix = strdup(prefix); if (!handler->prefix) { free(handler); return false; } if (queue_find(hfp->event_handlers, match_handler_event_prefix, handler->prefix)) { destroy_event_handler(handler); return false; } handler->destroy = destroy; return queue_push_tail(hfp->event_handlers, handler); }
bool hfp_hf_unregister(struct hfp_hf *hfp, const char *prefix) { struct cmd_handler *handler; /* Cast to void as queue_remove needs that */ handler = queue_remove_if(hfp->event_handlers, match_handler_event_prefix, (void *) prefix); if (!handler) return false; destroy_event_handler(handler); return true; }
static void handle_clone(Event * event) { Process *p; debug(DEBUG_FUNCTION, "handle_clone(pid=%d)", event->proc->pid); p = malloc(sizeof(Process)); if (!p) { perror("malloc()"); exit(1); } memcpy(p, event->proc, sizeof(Process)); p->pid = event->e_un.newpid; p->parent = event->proc; /* We save register values to the arch pointer, and these need to be per-thread. */ p->arch_ptr = NULL; if (pending_new(p->pid)) { pending_new_remove(p->pid); if (p->event_handler != NULL) destroy_event_handler(p); if (event->proc->state == STATE_ATTACHED && options.follow) { p->state = STATE_ATTACHED; } else { p->state = STATE_IGNORED; } continue_process(p->pid); add_process(p); } else { p->state = STATE_BEING_CREATED; add_process(p); } if (p->leader == p) clone_breakpoints(p, event->proc->leader); else /* Thread groups share breakpoints. */ p->breakpoints = NULL; if (event->type == EVENT_VFORK) continue_after_vfork(p); else continue_process(event->proc->pid); }