perf_datafile_t * perf_datafile_open(isc_mem_t *mctx, const char *filename) { perf_datafile_t *dfile; struct stat buf; dfile = isc_mem_get(mctx, sizeof(*dfile)); if (dfile == NULL) perf_log_fatal("out of memory"); dfile->mctx = mctx; MUTEX_INIT(&dfile->lock); dfile->pipe_fd = -1; dfile->is_file = ISC_FALSE; dfile->size = 0; dfile->cached = ISC_FALSE; dfile->maxruns = 1; dfile->nruns = 0; dfile->read_any = ISC_FALSE; isc_buffer_init(&dfile->data, dfile->databuf, BUFFER_SIZE); if (filename == NULL) { dfile->fd = STDIN_FILENO; } else { dfile->fd = open(filename, O_RDONLY); if (dfile->fd < 0) perf_log_fatal("unable to open file: %s", filename); if (fstat(dfile->fd, &buf) == 0 && S_ISREG(buf.st_mode)) { dfile->is_file = ISC_TRUE; dfile->size = buf.st_size; } } nul_terminate(dfile); return dfile; }
isc_result_t perf_os_waituntilreadable(int fd, int pipe_fd, isc_int64_t timeout) { fd_set read_fds; int maxfd; struct timeval tv, *tvp; int n; FD_ZERO(&read_fds); FD_SET(fd, &read_fds); FD_SET(pipe_fd, &read_fds); maxfd = pipe_fd > fd ? pipe_fd : fd; if (timeout < 0) { tvp = NULL; } else { tv.tv_sec = timeout / MILLION; tv.tv_usec = timeout % MILLION; tvp = &tv; } n = select(maxfd + 1, &read_fds, NULL, NULL, tvp); if (n < 0) { if (errno != EINTR) perf_log_fatal("select() failed"); return (ISC_R_CANCELED); } else if (FD_ISSET(fd, &read_fds)) { return (ISC_R_SUCCESS); } else if (FD_ISSET(pipe_fd, &read_fds)) { return (ISC_R_CANCELED); } else { return (ISC_R_TIMEDOUT); } }
void perf_opt_add(char c, perf_opttype_t type, const char *desc, const char *help, const char *defval, void *valp) { opt_t *opt; char s[3]; if (nopts == MAX_OPTS) perf_log_fatal("too many defined options"); opt = &opts[nopts++]; opt->c = c; opt->type = type; opt->desc = desc; opt->help = help; if (defval != NULL) { strncpy(opt->defvalbuf, defval, sizeof(opt->defvalbuf)); opt->defval = opt->defvalbuf; } else { opt->defval = NULL; } opt->u.valp = valp; sprintf(s, "%c%s", c, (type == perf_opt_boolean ? "" : ":")); strcat(optstr, s); }
isc_result_t perf_os_waituntilwriteable(int fd, isc_int64_t timeout) { struct pollfd write_fds[1]; int timeout_msec; int n; write_fds[0].fd = fd; write_fds[0].events = POLLOUT; if (timeout < 0) { timeout_msec = 0; } else { timeout_msec = timeout / THOUSAND; } n = poll(write_fds, 1, timeout_msec); if (n < 0) { if (errno != EINTR) perf_log_fatal("select() failed: Error was %s", strerror(errno)); return (ISC_R_CANCELED); } else if (write_fds[0].revents & POLLOUT) { return (ISC_R_SUCCESS); } else { return (ISC_R_TIMEDOUT); } }
isc_result_t perf_os_waituntilanyreadable(int *fds, unsigned int nfds, int pipe_fd, isc_int64_t timeout) { struct pollfd read_fds[nfds + 1]; int timeout_msec; unsigned int i; int n; for (i = 0; i < nfds; i++) { read_fds[i].fd = fds[i]; read_fds[i].events = POLLIN; } read_fds[nfds].fd = pipe_fd; if (timeout < 0) { timeout_msec = 0; } else { timeout_msec = timeout / THOUSAND; } n = poll(read_fds, nfds + 1, timeout_msec); if (n < 0) { if (errno != EINTR) perf_log_fatal("select() failed: Error was %s", strerror(errno)); return (ISC_R_CANCELED); } else if (n == 0) { return (ISC_R_TIMEDOUT); } else if (read_fds[nfds].revents & POLLIN) { return (ISC_R_CANCELED); } else { return (ISC_R_SUCCESS); } }
void perf_os_handlesignal(int sig, void (*handler)(int)) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = handler; if (sigfillset(&sa.sa_mask) < 0 || sigaction(sig, &sa, NULL) < 0) perf_log_fatal("sigaction: %s", strerror(errno)); }
static void reopen_file(perf_datafile_t *dfile) { if (dfile->cached) { isc_buffer_first(&dfile->data); } else { if (lseek(dfile->fd, 0L, SEEK_SET) < 0) perf_log_fatal("cannot reread input"); isc_buffer_clear(&dfile->data); nul_terminate(dfile); } }
void perf_os_blocksignal(int sig, isc_boolean_t block) { sigset_t sset; int op; op = block ? SIG_BLOCK : SIG_UNBLOCK; if (sigemptyset(&sset) < 0 || sigaddset(&sset, sig) < 0 || pthread_sigmask(op, &sset, NULL) < 0) perf_log_fatal("pthread_sigmask: %s", strerror(errno)); }
isc_result_t perf_os_waituntilanyreadable(int *fds, unsigned int nfds, int pipe_fd, isc_int64_t timeout) { fd_set read_fds; unsigned int i; int maxfd; struct timeval tv, *tvp; int n; FD_ZERO(&read_fds); maxfd = 0; for (i = 0; i < nfds; i++) { FD_SET(fds[i], &read_fds); if (fds[i] > maxfd) maxfd = fds[i]; } FD_SET(pipe_fd, &read_fds); if (pipe_fd > maxfd) maxfd = pipe_fd; if (timeout < 0) { tvp = NULL; } else { tv.tv_sec = timeout / MILLION; tv.tv_usec = timeout % MILLION; tvp = &tv; } n = select(maxfd + 1, &read_fds, NULL, NULL, tvp); if (n < 0) { if (errno != EINTR) perf_log_fatal("select() failed"); return (ISC_R_CANCELED); } else if (n == 0) { return (ISC_R_TIMEDOUT); } else if (FD_ISSET(pipe_fd, &read_fds)) { return (ISC_R_CANCELED); } else { return (ISC_R_SUCCESS); } }
int perf_net_opensocket(const isc_sockaddr_t *server, const isc_sockaddr_t *local, unsigned int offset, int bufsize) { int family; int sock; isc_sockaddr_t tmp; int port; int ret; int flags; family = isc_sockaddr_pf(server); if (isc_sockaddr_pf(local) != family) perf_log_fatal("server and local addresses have " "different families"); sock = socket(family, SOCK_DGRAM, 0); if (sock == -1) perf_log_fatal("Error: socket: %s\n", strerror(errno)); #if defined(AF_INET6) && defined(IPV6_V6ONLY) if (family == AF_INET6) { int on = 1; if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1) { perf_log_warning("setsockopt(IPV6_V6ONLY) failed"); } } #endif tmp = *local; port = isc_sockaddr_getport(&tmp); if (port != 0 && offset != 0) { port += offset; if (port >= 0xFFFF) perf_log_fatal("port %d out of range", port); isc_sockaddr_setport(&tmp, port); } if (bind(sock, &tmp.type.sa, tmp.length) == -1) perf_log_fatal("bind: %s\n", strerror(errno)); if (bufsize > 0) { bufsize *= 1024; ret = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)); if (ret < 0) perf_log_warning("setsockbuf(SO_RCVBUF) failed"); ret = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)); if (ret < 0) perf_log_warning("setsockbuf(SO_SNDBUF) failed"); } flags = fcntl(sock, F_GETFL, 0); if (flags < 0) perf_log_fatal("fcntl(F_GETFL)"); ret = fcntl(sock, F_SETFL, flags | O_NONBLOCK); if (ret < 0) perf_log_fatal("fcntl(F_SETFL)"); return sock; }