ref: 93e6ec6e9bef1c1bc2b3fa75836b422aa96ca13b
dir: /util.c/
/*
* This work is dedicated to the public domain.
* See COPYING file for more information.
*/
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netdb.h>
#include <poll.h>
#include <unistd.h>
/*
* ecalloc - calloc with error handling
*/
void *
ecalloc(size_t nmemb, size_t size)
{
void *p;
if ((p = calloc(nmemb, size)) == NULL) {
printf("error: calloc: %s\n", strerror(errno));
exit(1);
}
return p;
}
/*
* erecalloc -- allocate more memory, zero new memory, handle error
* ptr - pointer of the old memory
* omemb - no. of member of old pointer
* nmemb - no. of member to extend
* size - size of one member
*/
void *
erecalloc(void *ptr, size_t omemb, size_t nmemb, size_t size)
{
void *p;
if ((p = realloc(ptr, (omemb + nmemb) * size)) == NULL) {
printf("error: realloc: %s\n", strerror(errno));
exit(1);
}
/* memset(p + omemb * size, 0, nmemb * size); */
return p;
}
char*
split(char **str, char ch)
{
char *token = *str;
if (**str == '\0') return *str;
while (**str != ch && **str != '\0')
(*str)++;
if (**str == '\0')
return token;
**str = '\0';
(*str)++;
while(**str == ch && **str != '\0')
(*str)++;
return token;
}
int
fifo_open(char *path)
{
struct stat st;
int fd;
/* make fifo if it doesn't exists */
if (lstat(path, &st) != -1) {
if (!(st.st_mode & S_IFIFO)) {
printf("error: '%s' is not a fifo file\n", path);
return -1;
}
} else if (mkfifo(path, S_IRWXU) != 0) {
printf("error: failed to create fifo file '%s'\n", path);
return -1;
}
/* open fifo */
fd = open(path, O_RDONLY | O_NONBLOCK, 0);
if (fd == -1)
printf("error: cannot open() '%s'\n", path);
return fd;
}
ssize_t
writeall(int fd, char *buf)
{
ssize_t left, sent, n;
left = (ssize_t)strlen(buf);
sent = 0;
while (sent < left) {
if ((n = write(fd, buf+sent, (size_t)left)) == -1) {
printf("error: write failed: %s\n", strerror(errno));
return -1;
}
sent += n;
left -= n;
}
return sent;
}
int
dial(char *host, char *port)
{
static struct addrinfo hints, *res = NULL, *res0;
int fd = -1, r;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if ((r = getaddrinfo(host, port, &hints, &res0)) != 0) {
printf("error: getaddrinfo: %s\n", gai_strerror(r));
return -1;
}
for (res = res0; res != NULL; res = res->ai_next) {
if ((fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0)
continue;
if (connect(fd, res->ai_addr, res->ai_addrlen) == -1) {
close(fd);
fd = -1;
continue;
}
break;
}
if (fd == -1)
printf("error: cannot connect to host '%s'\n", host);
freeaddrinfo(res0);
return fd;
}
ssize_t
readline(int fd, char *buffer, size_t size)
{
ssize_t n, i = 0;
char c;
do {
if ((n = read(fd, &c, sizeof(char))) != sizeof(char))
return n;
buffer[i++] = c;
} while ((i < (ssize_t)size) && (c != '\n') && (c != '\0'));
buffer[i-1] = '\0';
return i;
}