wm: ticl

ref: 375f68cba6f87f824a01f604b65057138c754a43
dir: /util.c/

View raw version
/*
 * This work is dedicated to the public domain.
 * See COPYING file for more information.
 */

#include <sys/socket.h>
#include <sys/stat.h>

#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#ifdef __gnu_linux__
#include <bsd/err.h>
#else
#include <err.h>
#endif

#define FALSE 0
#define TRUE 1

/*
 * ecalloc - calloc with error handling
 */
void *
ecalloc(size_t nmemb, size_t size)
{
	void *p;
	if ((p = calloc(nmemb, size)) == NULL)
		err(1, "calloc");
	return p;
}

/*
 * realloc0 -- allocate more memory and zero new memory
 * 	ptr	- pointer of the old memory
 * 	osize	- size of old memory
 * 	nsize	- size to new memory
 */
void *
realloc0(void *ptr, size_t osize, size_t nsize)
{
	void *p;
	if ((p = realloc(ptr, nsize)) == NULL)
		err(1, "realloc");
	memset(((char *)p + osize), 0, nsize - osize);
	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))
			errx(1, "'%s' is not a fifo file", path);
	} else if (mkfifo(path, S_IRWXU) == -1) {
		err(1, "mkfifo: %s", path);
	}

	fd = open(path, O_RDONLY | O_NONBLOCK, 0);
	if (fd == -1)
		err(1, "open: %s", 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)
			err(1, "%d: write", fd);
		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) {
		warnx("getaddrinfo: %s", 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)) == -1)
			continue;
		if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
			warn("fnctl");
			continue;
		}
		if ((connect(fd, res->ai_addr, res->ai_addrlen) == -1)
		    && (errno == EINPROGRESS))
			break;

		warn("connect");
		close(fd);
		fd = -1;
	}
	if (fd == -1)
		warnx("cannot connect to %s", host);

	freeaddrinfo(res0);
	return fd;
}

ssize_t
readline(int fd, char *buffer, size_t size)
{
	size_t i = 0;
	char c;
	ssize_t l;

	do {
		l = read(fd, &c, sizeof(char));
		if (l > 0)
			buffer[i++] = c;
		else if (l == 0)
			return 0;
		else if (l == -1 && errno == EAGAIN)
			continue;
		else
			return -1;
	} while ((i < size) && (c != '\r') && (c != '\n'));

	buffer[i-1] = '\0';
	return (ssize_t)i;
}