From 051b1e60c1e80994388521ae37d7035babbd12b6 Mon Sep 17 00:00:00 2001 From: cel Date: Mon, 10 Jul 2017 13:28:28 -1000 Subject: Init --- io.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 io.c (limited to 'io.c') diff --git a/io.c b/io.c new file mode 100644 index 0000000..615f346 --- /dev/null +++ b/io.c @@ -0,0 +1,106 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "io.h" + +int read_all(int fd, unsigned char *buf, size_t len) { + ssize_t nbytes; + while (len > 0) { + nbytes = read(fd, buf, len); + if (nbytes == 0) { errno = EPIPE; return -1; } + if (nbytes < 0 && errno == EINTR) continue; + if (nbytes < 0) return -1; + buf += nbytes; + len -= nbytes; + } + return 0; +} + +int read_some(int fd, unsigned char *buf, size_t *lenp) { + ssize_t nbytes; + do nbytes = read(fd, buf, *lenp); + while (nbytes < 0 && errno == EINTR); + if (nbytes == 0) { errno = EPIPE; return -1; } + if (nbytes < 0) return -1; + *lenp = nbytes; + return 0; +} + +int write_all(int fd, const unsigned char *buf, size_t count) { + ssize_t nbytes; + while (count > 0) { + nbytes = write(fd, buf, count); + if (nbytes < 0 && errno == EINTR) continue; + if (nbytes < 0) return -1; + buf += nbytes; + count -= nbytes; + } + return 0; +} + +ssize_t read_file(char *buf, size_t len, const char *fmt, ...) { + va_list ap; + int rc; + struct stat st; + int fd; + + va_start(ap, fmt); + rc = vsnprintf(buf, len, fmt, ap); + va_end(ap); + if (rc < 0) return -1; + if ((size_t)rc >= len) { errno = ENAMETOOLONG; return -1; } + + rc = stat(buf, &st); + if (rc < 0) return -1; + if ((size_t)st.st_size > len-1) { errno = EMSGSIZE; return -1; } + + fd = open(buf, O_RDONLY); + if (fd < 0) return -1; + + rc = read_all(fd, buf, st.st_size); + if (rc < 0) return -1; + + buf[(size_t)st.st_size] = '\0'; + + close(fd); + return st.st_size; +} + +int tcp_connect(const char *host, const char *port, const char **errp) { + struct addrinfo hints; + struct addrinfo *result, *rp; + int s; + int fd; + int err; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_protocol = IPPROTO_TCP; + + if (host && host[0] == '\0') host = NULL; + s = getaddrinfo(host, port, &hints, &result); + if (s < 0) { + *errp = gai_strerror(s); + return -1; + } + + for (rp = result; rp; rp = rp->ai_next) { + fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (fd < 0) continue; + if (connect(fd, rp->ai_addr, rp->ai_addrlen) == 0) break; + err = errno; + close(fd); + errno = err; + } + if (rp == NULL) fd = -1; + + freeaddrinfo(result); + return fd; +} -- cgit v1.2.3