static int proc_data_send(struct client *cl, const char *data, int len) { struct dispatch_proc *p = &cl->dispatch.proc; int retlen = 0; int ret; while (len) { ret = write(p->wrfd.fd, data, len); if (ret < 0) { if (errno == EINTR) continue; if (errno == EAGAIN || errno == EWOULDBLOCK) break; /* consume all data */ ret = len; } if (!ret) break; retlen += ret; len -= ret; data += ret; } if (len) uloop_fd_add(&p->wrfd, ULOOP_WRITE); else uloop_fd_delete(&p->wrfd); return retlen; }
void hncp_io_uninit(hncp o) { close(o->udp_socket); /* clear the timer from uloop. */ uloop_timeout_cancel(&o->timeout); /* and the fd also. */ (void)uloop_fd_delete(&o->ufd); }
static void ping_uloop_fd_close(struct uloop_fd *ufd) { if (ufd != NULL && ufd->fd > 0) { uloop_fd_delete(ufd); close(ufd->fd); ufd->fd = 0; } }
static void log_handle_fd(struct uloop_fd *u, unsigned int events) { if (u->eof) { uloop_fd_delete(u); close(sender.fd); sender.fd = -1; uloop_timeout_set(&retry, 1000); } }
static void close_connection(struct uloop_fd *sock) { struct jrpc_connection *conn; conn = container_of(sock, struct jrpc_connection, sock); uloop_fd_delete(sock); close(sock->fd); free(conn->buffer); free(conn); }
static void handle_client_disconnect(struct ubus_client *cl) { while (ubus_msg_head(cl)) ubus_msg_dequeue(cl); ubusd_proto_free_client(cl); uloop_fd_delete(&cl->sock); close(cl->sock.fd); free(cl); }
static void proc_write_close(struct client *cl) { struct dispatch_proc *p = &cl->dispatch.proc; if (p->wrfd.fd < 0) return; uloop_fd_delete(&p->wrfd); close(p->wrfd.fd); p->wrfd.fd = -1; }
static int uloop_fetch_events(int timeout) { struct timespec ts; int nfds, n; if (timeout >= 0) { ts.tv_sec = timeout / 1000; ts.tv_nsec = (timeout % 1000) * 1000000; } nfds = kevent(poll_fd, NULL, 0, events, ARRAY_SIZE(events), timeout >= 0 ? &ts : NULL); for (n = 0; n < nfds; n++) { struct uloop_fd_event *cur = &cur_fds[n]; struct uloop_fd *u = events[n].udata; unsigned int ev = 0; cur->fd = u; if (!u) continue; if (events[n].flags & EV_ERROR) { u->error = true; if (!(u->flags & ULOOP_ERROR_CB)) uloop_fd_delete(u); } if(events[n].filter == EVFILT_READ) ev |= ULOOP_READ; else if (events[n].filter == EVFILT_WRITE) ev |= ULOOP_WRITE; if (events[n].flags & EV_EOF) u->eof = true; else if (!ev) cur->fd = NULL; cur->events = ev; if (u->flags & ULOOP_EDGE_DEFER) { u->flags &= ~ULOOP_EDGE_DEFER; u->flags |= ULOOP_EDGE_TRIGGER; register_kevent(u, u->flags); } } return nfds; }
static void rdns_shutdown(struct rrdns_context *rctx) { struct rrdns_request *req, *tmp; uloop_timeout_cancel(&rctx->timeout); uloop_fd_delete(&rctx->socket); close(rctx->socket.fd); ubus_send_reply(rctx->context, &rctx->request, rctx->blob.head); ubus_complete_deferred_request(rctx->context, &rctx->request, UBUS_STATUS_OK); avl_remove_all_elements(&rctx->request_addrs, req, by_addr, tmp) free(req); blob_buf_free(&rctx->blob); free(rctx); }
void uloop_run(void) { struct epoll_event events[10]; struct timeval tv; int timeout; int nfds, n; uloop_setup_signals(); while(!cancel) { gettimeofday(&tv, NULL); uloop_process_timeouts(&tv); timeout = uloop_get_next_timeout(&tv); nfds = epoll_wait(epoll_fd, events, ARRAY_SIZE(events), timeout); for(n = 0; n < nfds; ++n) { struct uloop_fd *u = events[n].data.ptr; unsigned int ev = 0; if(events[n].events & EPOLLERR) { u->error = true; uloop_fd_delete(u); } if(!(events[n].events & (EPOLLRDHUP|EPOLLIN|EPOLLOUT|EPOLLERR))) continue; if(events[n].events & EPOLLRDHUP) u->eof = true; if(events[n].events & EPOLLIN) ev |= ULOOP_READ; if(events[n].events & EPOLLOUT) ev |= ULOOP_WRITE; if(u->cb) u->cb(u, ev); } } }
static void connect_cb(struct uloop_fd *f, unsigned int events) { if (ufd.eof || ufd.error) { _debug("connection to sysrepo failed"); uloop_timeout_set(&reconnect_timer, 1000); return; } ___debug("connection with sysrepo established"); uloop_fd_delete(&ufd); usfd.stream.string_data = true; usfd.stream.notify_read = read_cb; usfd.stream.notify_state = state_cb; usfd.stream.notify_write = write_cb; ustream_fd_init(&usfd, ufd.fd); usfd.stream.write_error = 0; u_tcp_printf("%07d\n%s\n", strlen(CUSTOM_XML_HELO) + 1, CUSTOM_XML_HELO); u_tcp_printf("%07d\n%s\n", strlen(CUSTOM_XML_SET_DATASTORE) + 1, CUSTOM_XML_SET_DATASTORE); }
static int log_notify(struct blob_attr *msg) { struct blob_attr *tb[__LOG_MAX]; struct stat s; char buf[512]; uint32_t p; char *str; time_t t; char *c, *m; int ret = 0; if (sender.fd < 0) return 0; blobmsg_parse(log_policy, ARRAY_SIZE(log_policy), tb, blob_data(msg), blob_len(msg)); if (!tb[LOG_ID] || !tb[LOG_PRIO] || !tb[LOG_SOURCE] || !tb[LOG_TIME] || !tb[LOG_MSG]) return 1; if ((log_type == LOG_FILE) && log_size && (!stat(log_file, &s)) && (s.st_size > log_size)) { char *old = malloc(strlen(log_file) + 5); close(sender.fd); if (old) { sprintf(old, "%s.old", log_file); rename(log_file, old); free(old); } sender.fd = open(log_file, O_CREAT | O_WRONLY | O_APPEND, 0600); if (sender.fd < 0) { fprintf(stderr, "failed to open %s: %s\n", log_file, strerror(errno)); exit(-1); } } m = blobmsg_get_string(tb[LOG_MSG]); t = blobmsg_get_u64(tb[LOG_TIME]) / 1000; c = ctime(&t); p = blobmsg_get_u32(tb[LOG_PRIO]); c[strlen(c) - 1] = '\0'; str = blobmsg_format_json(msg, true); if (log_type == LOG_NET) { int err; snprintf(buf, sizeof(buf), "<%u>", p); strncat(buf, c + 4, 16); if (hostname) { strncat(buf, hostname, sizeof(buf) - strlen(buf) - 1); strncat(buf, " ", sizeof(buf) - strlen(buf) - 1); } if (log_prefix) { strncat(buf, log_prefix, sizeof(buf) - strlen(buf) - 1); strncat(buf, ": ", sizeof(buf) - strlen(buf) - 1); } if (blobmsg_get_u32(tb[LOG_SOURCE]) == SOURCE_KLOG) strncat(buf, "kernel: ", sizeof(buf) - strlen(buf) - 1); strncat(buf, m, sizeof(buf) - strlen(buf) - 1); if (log_udp) err = write(sender.fd, buf, strlen(buf)); else { size_t buflen = strlen(buf); if (!log_trailer_null) buf[buflen] = '\n'; err = send(sender.fd, buf, buflen + 1, 0); } if (err < 0) { syslog(LOG_INFO, "failed to send log data to %s:%s via %s\n", log_ip, log_port, (log_udp) ? ("udp") : ("tcp")); uloop_fd_delete(&sender); close(sender.fd); sender.fd = -1; uloop_timeout_set(&retry, 1000); } } else { snprintf(buf, sizeof(buf), "%s %s.%s%s %s\n", c, getcodetext(LOG_FAC(p) << 3, facilitynames), getcodetext(LOG_PRI(p), prioritynames), (blobmsg_get_u32(tb[LOG_SOURCE])) ? ("") : (" kernel:"), m); ret = write(sender.fd, buf, strlen(buf)); } free(str); if (log_type == LOG_FILE) fsync(sender.fd); return ret; }
static void ustream_fd_free(struct ustream *s) { struct ustream_fd *sf = container_of(s, struct ustream_fd, stream); uloop_fd_delete(&sf->fd); }
static struct json *exit_server(struct jrpc_context * ctx, struct json *params, struct json *id) { uloop_fd_delete(&my_server.sock); return json_create_string("Bye!"); }
static int interface_send_packet4(struct interface *iface, struct iovec *iov, int iov_len) { static size_t cmsg_data[( CMSG_SPACE(sizeof(struct in_pktinfo)) / sizeof(size_t)) + 1]; static struct sockaddr_in a; static struct msghdr m = { .msg_name = (struct sockaddr *) &a, .msg_namelen = sizeof(a), .msg_control = cmsg_data, .msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo)), }; struct in_pktinfo *pkti; struct cmsghdr *cmsg; int fd = iface->fd.fd; a.sin_family = AF_INET; a.sin_port = htons(MCAST_PORT); m.msg_iov = iov; m.msg_iovlen = iov_len; memset(cmsg_data, 0, sizeof(cmsg_data)); cmsg = CMSG_FIRSTHDR(&m); cmsg->cmsg_len = m.msg_controllen; cmsg->cmsg_level = IPPROTO_IP; cmsg->cmsg_type = IP_PKTINFO; pkti = (struct in_pktinfo*) CMSG_DATA(cmsg); pkti->ipi_ifindex = iface->ifindex; a.sin_addr.s_addr = inet_addr(MCAST_ADDR); return sendmsg(fd, &m, 0); } static int interface_send_packet6(struct interface *iface, struct iovec *iov, int iov_len) { static size_t cmsg_data[( CMSG_SPACE(sizeof(struct in6_pktinfo)) / sizeof(size_t)) + 1]; static struct sockaddr_in6 a; static struct msghdr m = { .msg_name = (struct sockaddr *) &a, .msg_namelen = sizeof(a), .msg_control = cmsg_data, .msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo)), }; struct in6_pktinfo *pkti; struct cmsghdr *cmsg; int fd = iface->fd.fd; a.sin6_family = AF_INET6; a.sin6_port = htons(MCAST_PORT); m.msg_iov = iov; m.msg_iovlen = iov_len; memset(cmsg_data, 0, sizeof(cmsg_data)); cmsg = CMSG_FIRSTHDR(&m); cmsg->cmsg_len = m.msg_controllen; cmsg->cmsg_level = IPPROTO_IPV6; cmsg->cmsg_type = IPV6_PKTINFO; pkti = (struct in6_pktinfo*) CMSG_DATA(cmsg); pkti->ipi6_ifindex = iface->ifindex; inet_pton(AF_INET6, MCAST_ADDR6, &a.sin6_addr); return sendmsg(fd, &m, 0); } int interface_send_packet(struct interface *iface, struct iovec *iov, int iov_len) { if (debug > 1) { fprintf(stderr, "TX ipv%d: %s\n", iface->v6 * 2 + 4, iface->name); fprintf(stderr, " multicast: %d\n", iface->multicast); } if (iface->v6) return interface_send_packet6(iface, iov, iov_len); return interface_send_packet4(iface, iov, iov_len); } static void interface_close(struct interface *iface) { if (iface->fd.fd < 0) return; announce_free(iface); uloop_fd_delete(&iface->fd); close(iface->fd.fd); iface->fd.fd = -1; } static void interface_free(struct interface *iface) { interface_close(iface); free(iface); } static int interface_valid_src(void *ip1, void *mask, void *ip2, int len) { uint8_t *i1 = ip1; uint8_t *i2 = ip2; uint8_t *m = mask; int i; if (cfg_no_subnet) return 0; for (i = 0; i < len; i++, i1++, i2++, m++) { if ((*i1 & *m) != (*i2 & *m)) return -1; } return 0; }