void mowgli_simple_eventloop_error_handler(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata) { mowgli_eventloop_pollable_t *pollable = mowgli_eventloop_io_pollable(io); if (pollable != NULL) mowgli_pollable_destroy(eventloop, pollable); }
void mowgli_helper_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_helper_proc_t *helper) { return_if_fail(eventloop != NULL); return_if_fail(helper != NULL); mowgli_process_kill(helper->child); mowgli_pollable_destroy(eventloop, helper->pfd); close(helper->fd); mowgli_free(helper); }
mowgli_eventloop_helper_proc_t * mowgli_helper_spawn(mowgli_eventloop_t *eventloop, const char *path, char *const argv[]) { mowgli_eventloop_helper_proc_t *helper; int io_fd[2]; char buf[64]; return_val_if_fail(eventloop != NULL, NULL); return_val_if_fail(path != NULL, NULL); helper = mowgli_alloc(sizeof(mowgli_eventloop_helper_proc_t)); helper->type.type = MOWGLI_EVENTLOOP_TYPE_HELPER; helper->eventloop = eventloop; socketpair(AF_UNIX, SOCK_STREAM, 0, io_fd); /* set up helper/child fd mapping */ helper->fd = io_fd[0]; /* make pollables and make them non-blocking */ helper->pfd = mowgli_pollable_create(eventloop, helper->fd, helper); snprintf(buf, sizeof buf, "%d", io_fd[1]); setenv("IO_FD", buf, 1); /* Spawn helper process using mowgli_process_spawn(), helper will get * IO_FD mapping from getenv(). Ugly hack, but it works... * --nenolod */ helper->child = mowgli_process_spawn(path, argv); if (helper->child == NULL) { mowgli_pollable_destroy(eventloop, helper->pfd); close(io_fd[0]); close(io_fd[1]); mowgli_free(helper); return NULL; } close(io_fd[1]); return helper; }
mowgli_eventloop_helper_proc_t * mowgli_helper_create(mowgli_eventloop_t *eventloop, mowgli_eventloop_helper_start_fn_t *start_fn, const char *helpername, void *userdata) { mowgli_eventloop_helper_proc_t *helper; mowgli_helper_create_req_t child; int io_fd[2]; return_val_if_fail(eventloop != NULL, NULL); return_val_if_fail(start_fn != NULL, NULL); child.start_fn = start_fn; child.userdata = userdata; helper = mowgli_alloc(sizeof(mowgli_eventloop_helper_proc_t)); helper->type.type = MOWGLI_EVENTLOOP_TYPE_HELPER; helper->eventloop = eventloop; socketpair(AF_UNIX, SOCK_STREAM, 0, io_fd); /* set up helper/child fd mapping */ helper->fd = io_fd[0]; child.fd = io_fd[1]; /* make pollables and make them non-blocking */ helper->pfd = mowgli_pollable_create(eventloop, helper->fd, helper); mowgli_pollable_set_nonblocking(helper->pfd, true); /* spawn helper process using mowgli_process_clone() */ helper->child = mowgli_process_clone((mowgli_process_start_fn_t) mowgli_helper_trampoline, helpername, &child); if (helper->child == NULL) { mowgli_pollable_destroy(eventloop, helper->pfd); close(io_fd[0]); close(io_fd[1]); mowgli_free(helper); return NULL; } close(child.fd); return helper; }
static void read_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata) { mowgli_eventloop_pollable_t *pollable = mowgli_eventloop_io_pollable(io); mowgli_dns_t *dns = userdata; char buf[2048]; char *ch; int ret; return_if_fail(pollable->fd == STDIN_FILENO); if ((ret = read(pollable->fd, buf, sizeof(buf))) < 0) { perror("read"); mowgli_pollable_destroy(eventloop, io); return; } else if (ret == 0) { return; } buf[--ret] = '\0'; ch = strtok(buf, " "); while (ch != NULL) { dns_query *dnsquery = mowgli_alloc(sizeof(dns_query)); mowgli_dns_query_t *query = &dnsquery->query; printf("Domain input: %s\n", ch); printf("End domain input\n"); query->callback = resolve_cb; query->ptr = dnsquery; dnsquery->domain = mowgli_strdup(ch); if (*ch == '+') { int type; void *addrptr; struct sockaddr_storage addr; if (strchr(++ch, ':') != NULL) { struct sockaddr_in6 *saddr = (struct sockaddr_in6 *) &addr; type = AF_INET6; addrptr = &saddr->sin6_addr; } else { struct sockaddr_in *saddr = (struct sockaddr_in *) &addr; type = AF_INET; addrptr = &saddr->sin_addr; } addr.ss_family = type; if ((ret = inet_pton(type, ch, addrptr)) != 1) { if (ret == -1) perror("inet_pton"); else printf("Invalid address %s\n", ch); return; } mowgli_dns_gethost_byaddr(dns, &addr, query); } else { mowgli_dns_gethost_byname(dns, ch, query, MOWGLI_DNS_T_A); } dnsquery->domain = mowgli_strdup(ch); ch = strtok(NULL, " "); } }