Path: blob/master/concurrency-webserver/src/io_helper.h
909 views
#ifndef __IO_HELPER__1#define __IO_HELPER__23#include <arpa/inet.h>4#include <assert.h>5#include <ctype.h>6#include <errno.h>7#include <fcntl.h>8#include <netdb.h>9#include <netinet/in.h>10#include <setjmp.h>11#include <signal.h>12#include <stdio.h>13#include <stdlib.h>14#include <string.h>15#include <strings.h>16#include <sys/mman.h>17#include <sys/time.h>18#include <sys/socket.h>19#include <sys/stat.h>20#include <sys/types.h>21#include <sys/wait.h>22#include <unistd.h>2324typedef struct sockaddr sockaddr_t;2526// useful here: gcc statement expressions27// http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html28// macro ({ ...; x; }) returns value 'x' for caller29// e.g., macro 'fork_or_die()' below returns 'pid' value30#define fork_or_die() \31({ pid_t pid = fork(); assert(pid >= 0); pid; })32#define execve_or_die(filename, argv, envp) \33assert(execve(filename, argv, envp) == 0);34#define wait_or_die(status) \35({ pid_t pid = wait(status); assert(pid >= 0); pid; })36#define gethostname_or_die(name, len) \37({ int rc = gethostname(name, len); assert(rc == 0); rc; })38#define setenv_or_die(name, value, overwrite) \39({ int rc = setenv(name, value, overwrite); assert(rc == 0); rc; })40#define chdir_or_die(path) \41assert(chdir(path) == 0);42#define open_or_die(pathname, flags, mode) \43({ int rc = open(pathname, flags, mode); assert(rc >= 0); rc; })44#define read_or_die(fd, buf, count) \45({ ssize_t rc = read(fd, buf, count); assert(rc >= 0); rc; })46#define write_or_die(fd, buf, count) \47({ ssize_t rc = write(fd, buf, count); assert(rc >= 0); rc; })48#define lseek_or_die(fd, offset, whence) \49({ off_t rc = lseek(fd, offset, whence); assert(rc >= 0); rc; })50#define close_or_die(fd) \51assert(close(fd) == 0);52#define select_or_die(n, readfds, writefds, exceptfds, timeout) \53({ int rc = select(n, readfds, writefds, exceptfds, timeout); assert(rc >= 0); rc; })54#define dup2_or_die(fd1, fd2) \55({ int rc = dup2(fd1, fd2); assert(rc >= 0); rc; })56#define stat_or_die(filename, buf) \57assert(stat(filename, buf) >= 0);58#define fstat_or_die(fd, buf) \59{ assert(fstat(fd, buf) >= 0); }60#define mmap_or_die(addr, len, prot, flags, fd, offset) \61({ void *ptr = mmap(addr, len, prot, flags, fd, offset); assert(ptr != (void *) -1); ptr; })62#define munmap_or_die(start, length) \63assert(munmap(start, length) >= 0);64#define socket_or_die(domain, type, protocol) \65({ int rc = socket(domain, type, protocol); assert(rc >= 0); rc; })66#define setsockopt_or_die(s, level, optname, optval, optlen) \67{ assert(setsockopt(s, level, optname, optval, optlen) >= 0); }68#define bind_or_die(sockfd, my_addr, addrlen) \69{ assert(bind(sockfd, my_addr, addrlen) >= 0); }70#define listen_or_die(s, backlog) \71{ assert(listen(s, backlog) >= 0); }72#define accept_or_die(s, addr, addrlen) \73({ int rc = accept(s, addr, addrlen); assert(rc >= 0); rc; })74#define connect_or_die(sockfd, serv_addr, addrlen) \75{ assert(connect(sockfd, serv_addr, addrlen) >= 0); }76#define gethostbyname_or_die(name) \77({ struct hostent *p = gethostbyname(name); assert(p != NULL); p; })78#define gethostbyaddr_or_die(addr, len, type) \79({ struct hostent *p = gethostbyaddr(addr, len, type); assert(p != NULL); p; })8081// client/server helper functions82ssize_t readline(int fd, void *buf, size_t maxlen);83int open_client_fd(char *hostname, int portno);84int open_listen_fd(int portno);8586// wrappers for above87#define readline_or_die(fd, buf, maxlen) \88({ ssize_t rc = readline(fd, buf, maxlen); assert(rc >= 0); rc; })89#define open_client_fd_or_die(hostname, port) \90({ int rc = open_client_fd(hostname, port); assert(rc >= 0); rc; })91#define open_listen_fd_or_die(port) \92({ int rc = open_listen_fd(port); assert(rc >= 0); rc; })9394#endif // __IO_HELPER__959697