void ipc_init(void) { int sd; struct sockaddr_un addr; size_t psiz = sizeof(addr.sun_path); addr.sun_family = PF_UNIX; if (snprintf(addr.sun_path, psiz, "%s/sock", btpd_dir) >= psiz) btpd_err("'%s/sock' is too long.\n", btpd_dir); if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) btpd_err("sock: %s\n", strerror(errno)); if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) != 0) { if (errno == EADDRINUSE) { unlink(addr.sun_path); if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) != 0) btpd_err("bind: %s\n", strerror(errno)); } else btpd_err("bind: %s\n", strerror(errno)); } if (chmod(addr.sun_path, ipcprot) == -1) btpd_err("chmod: %s (%s).\n", addr.sun_path, strerror(errno)); listen(sd, 4); set_nonblocking(sd); btpd_ev_new(&m_cli_incoming, sd, EV_READ, client_connection_cb, NULL); m_listen_sd = sd; }
static void nc_connect(struct nameconn *nc) { struct addrinfo *ai; int err; again: if ((ai = nc->ai_cur) == NULL) { nc_done(nc, -1); return; } if ((nc->sd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0) btpd_err("Failed to create socket (%s).\r\n", strerror(errno)); set_nonblocking(nc->sd); err = connect(nc->sd, ai->ai_addr, ai->ai_addrlen); if (err == 0) nc_done(nc, 0); else if (err == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK) btpd_ev_new(&nc->write_ev, nc->sd, EV_WRITE, nc_write_cb, nc); else { closesocket(nc->sd); nc->ai_cur = ai->ai_next; goto again; } }
void client_connection_cb(int sd, short type, void *arg) { int nsd; if ((nsd = accept(sd, NULL, NULL)) < 0) { if (errno == EWOULDBLOCK || errno == ECONNABORTED) return; else btpd_err("client accept: %s\n", strerror(errno)); } if ((errno = set_blocking(nsd)) != 0) btpd_err("set_blocking: %s.\n", strerror(errno)); struct cli *cli = btpd_calloc(1, sizeof(*cli)); cli->sd = nsd; btpd_ev_new(&cli->read, cli->sd, EV_READ, cli_read_cb, cli); }
static void httptr_nc_cb(void *arg, int error, int sd) { struct tr_response res; struct httptr_req *treq = arg; if (error) { res.type = TR_RES_CONN; tr_result(treq->tr, &res); http_cancel(treq->req); httptr_free(treq); } else { treq->sd = sd; uint16_t flags = (http_want_read(treq->req) ? EV_READ : 0) | (http_want_write(treq->req) ? EV_WRITE : 0); btpd_ev_new(&treq->ioev, sd, flags, httptr_io_cb, treq); btpd_timer_add(&treq->timer, (& (struct timespec) { 30, 0 })); }