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