static int write_header_v1(struct save_data *save_data, struct ipset_node_cache *cache, ipset_node_id root) { /* Output the magic number for an IP set, and the file format * version that we're going to write. */ rii_check(cork_stream_consumer_data(save_data->stream, NULL, 0, true)); rii_check(write_string(save_data->stream, MAGIC_NUMBER)); rii_check(write_uint16(save_data->stream, 0x0001)); /* Determine how many reachable nodes there are, to calculate the * size of the set. */ size_t nonterminal_count = ipset_node_reachable_count(cache, root); size_t set_size = MAGIC_NUMBER_LENGTH + /* magic number */ sizeof(uint16_t) + /* version number */ sizeof(uint64_t) + /* length of set */ sizeof(uint32_t) + /* number of nonterminals */ (nonterminal_count * /* for each nonterminal: */ (sizeof(uint8_t) + /* variable number */ sizeof(uint32_t) + /* low pointer */ sizeof(uint32_t) /* high pointer */ )); /* If the root is a terminal, we need to add 4 bytes to the set * size, for storing the terminal value. */ if (ipset_node_get_type(root) == IPSET_TERMINAL_NODE) { set_size += sizeof(uint32_t); } rii_check(write_uint64(save_data->stream, set_size)); rii_check(write_uint32(save_data->stream, nonterminal_count)); return 0; }
static int write_header_dot(struct save_data *save_data, struct ipset_node_cache *cache, ipset_node_id root) { /* Output the opening clause of the GraphViz script. */ rii_check(cork_stream_consumer_data(save_data->stream, NULL, 0, true)); return write_string(save_data->stream, GRAPHVIZ_HEADER); }
static int cork_read_pipe_read(struct cork_read_pipe *p, char *buf, bool *progress) { if (p->fds[0] == -1) { return 0; } do { DEBUG("[read] Reading from pipe %d\n", p->fds[0]); ssize_t bytes_read = read(p->fds[0], buf, BUF_SIZE); if (bytes_read == -1) { if (errno == EAGAIN) { /* We've exhausted all of the data currently available. */ DEBUG("[read] No more bytes without blocking\n"); return 0; } else if (errno == EINTR) { /* Interrupted by a signal; return so that our wait loop can * catch that. */ DEBUG("[read] Interrupted by signal\n"); return 0; } else { /* An actual error */ cork_system_error_set(); DEBUG("[read] Error: %s\n", cork_error_message()); return -1; } } else if (bytes_read == 0) { DEBUG("[read] End of stream\n"); *progress = true; rii_check(cork_stream_consumer_eof(p->consumer)); rii_check_posix(close(p->fds[0])); p->fds[0] = -1; return 0; } else { DEBUG("[read] Got %zd bytes\n", bytes_read); *progress = true; rii_check(cork_stream_consumer_data (p->consumer, buf, bytes_read, p->first)); p->first = false; } } while (true); }
static int clog_stream_handler__message(struct clog_handler *vself, struct clog_message *msg) { struct clog_stream_handler *self = cork_container_of(vself, struct clog_stream_handler, parent); if (clog_stream_handler_claim(self)) { /* Just claimed the lock; clear the buffer */ rii_check(clog_formatter_start(self->fmt)); } rii_check(clog_formatter_finish(self->fmt, msg, &self->buf)); cork_buffer_append(&self->buf, "\n", 1); rii_check(cork_stream_consumer_data (self->consumer, self->buf.buf, self->buf.size, self->first_chunk)); self->first_chunk = false; clog_stream_handler_release(self); return CLOG_CONTINUE; }
int cork_consume_file(struct cork_stream_consumer *consumer, FILE *fp) { char buf[BUFFER_SIZE]; size_t bytes_read; bool first = true; while (true) { while ((bytes_read = fread(buf, 1, BUFFER_SIZE, fp)) > 0) { rii_check(cork_stream_consumer_data (consumer, buf, bytes_read, first)); first = false; } if (feof(fp)) { return cork_stream_consumer_eof(consumer); } else if (errno != EINTR) { cork_system_error_set(); return -1; } } }
int cork_consume_fd(struct cork_stream_consumer *consumer, int fd) { char buf[BUFFER_SIZE]; ssize_t bytes_read; bool first = true; while (true) { while ((bytes_read = read(fd, buf, BUFFER_SIZE)) > 0) { rii_check(cork_stream_consumer_data (consumer, buf, bytes_read, first)); first = false; } if (bytes_read == 0) { return cork_stream_consumer_eof(consumer); } else if (errno != EINTR) { cork_system_error_set(); return -1; } } }
static int write_uint64(struct cork_stream_consumer *stream, uint64_t val) { CORK_UINT64_HOST_TO_BIG_IN_PLACE(val); return cork_stream_consumer_data(stream, &val, sizeof(uint64_t), false); }
/** * Write a big-endian uint8 to a stream. If we can't write the * integer for some reason, return an error. */ static int write_uint8(struct cork_stream_consumer *stream, uint8_t val) { /* for a byte, we don't need to endian-swap */ return cork_stream_consumer_data(stream, &val, sizeof(uint8_t), false); }
/** * Write a NUL-terminated string to a stream. If we can't write the * string for some reason, return an error. */ static int write_string(struct cork_stream_consumer *stream, const char *str) { size_t len = strlen(str); return cork_stream_consumer_data(stream, str, len, false); }