mio_aucat.c revision 1.8
1/* $OpenBSD: mio_aucat.c,v 1.8 2012/10/27 12:08:25 ratchov Exp $ */ 2/* 3 * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18#include <sys/types.h> 19#include <sys/socket.h> 20#include <sys/un.h> 21#include <netinet/in.h> 22 23#include <errno.h> 24#include <fcntl.h> 25#include <poll.h> 26#include <stdio.h> 27#include <stdlib.h> 28#include <string.h> 29#include <unistd.h> 30 31#include "aucat.h" 32#include "debug.h" 33#include "mio_priv.h" 34 35struct mio_aucat_hdl { 36 struct mio_hdl mio; 37 struct aucat aucat; 38 int events; 39}; 40 41static void mio_aucat_close(struct mio_hdl *); 42static size_t mio_aucat_read(struct mio_hdl *, void *, size_t); 43static size_t mio_aucat_write(struct mio_hdl *, const void *, size_t); 44static int mio_aucat_nfds(struct mio_hdl *); 45static int mio_aucat_pollfd(struct mio_hdl *, struct pollfd *, int); 46static int mio_aucat_revents(struct mio_hdl *, struct pollfd *); 47 48static struct mio_ops mio_aucat_ops = { 49 mio_aucat_close, 50 mio_aucat_write, 51 mio_aucat_read, 52 mio_aucat_nfds, 53 mio_aucat_pollfd, 54 mio_aucat_revents 55}; 56 57struct mio_hdl * 58mio_aucat_open(const char *str, unsigned int mode, 59 int nbio, unsigned int type) 60{ 61 struct mio_aucat_hdl *hdl; 62 63 hdl = malloc(sizeof(struct mio_aucat_hdl)); 64 if (hdl == NULL) 65 return NULL; 66 if (!aucat_open(&hdl->aucat, str, mode, type)) 67 goto bad; 68 mio_create(&hdl->mio, &mio_aucat_ops, mode, nbio); 69 if (!aucat_setfl(&hdl->aucat, 1, &hdl->mio.eof)) 70 goto bad; 71 return (struct mio_hdl *)hdl; 72bad: 73 free(hdl); 74 return NULL; 75} 76 77static void 78mio_aucat_close(struct mio_hdl *sh) 79{ 80 struct mio_aucat_hdl *hdl = (struct mio_aucat_hdl *)sh; 81 82 if (!hdl->mio.eof) 83 aucat_setfl(&hdl->aucat, 0, &hdl->mio.eof); 84 aucat_close(&hdl->aucat, hdl->mio.eof); 85 free(hdl); 86} 87 88static size_t 89mio_aucat_read(struct mio_hdl *sh, void *buf, size_t len) 90{ 91 struct mio_aucat_hdl *hdl = (struct mio_aucat_hdl *)sh; 92 93 while (hdl->aucat.rstate == RSTATE_MSG) { 94 if (!aucat_rmsg(&hdl->aucat, &hdl->mio.eof)) 95 return 0; 96 } 97 return aucat_rdata(&hdl->aucat, buf, len, &hdl->mio.eof); 98} 99 100static size_t 101mio_aucat_write(struct mio_hdl *sh, const void *buf, size_t len) 102{ 103 struct mio_aucat_hdl *hdl = (struct mio_aucat_hdl *)sh; 104 105 return aucat_wdata(&hdl->aucat, buf, len, 1, &hdl->mio.eof); 106} 107 108static int 109mio_aucat_nfds(struct mio_hdl *sh) 110{ 111 return 1; 112} 113 114static int 115mio_aucat_pollfd(struct mio_hdl *sh, struct pollfd *pfd, int events) 116{ 117 struct mio_aucat_hdl *hdl = (struct mio_aucat_hdl *)sh; 118 119 hdl->events = events; 120 return aucat_pollfd(&hdl->aucat, pfd, events); 121} 122 123static int 124mio_aucat_revents(struct mio_hdl *sh, struct pollfd *pfd) 125{ 126 struct mio_aucat_hdl *hdl = (struct mio_aucat_hdl *)sh; 127 int revents = pfd->revents; 128 129 if (revents & POLLIN) { 130 while (hdl->aucat.rstate == RSTATE_MSG) { 131 if (!aucat_rmsg(&hdl->aucat, &hdl->mio.eof)) 132 break; 133 } 134 if (hdl->aucat.rstate != RSTATE_DATA) 135 revents &= ~POLLIN; 136 } 137 if (hdl->mio.eof) 138 return POLLHUP; 139 return revents & (hdl->events | POLLHUP); 140} 141