mirror of https://github.com/dzavalishin/oskit/
784 lines
18 KiB
C
Executable File
784 lines
18 KiB
C
Executable File
/*
|
|
* Copyright (c) 1997-1998 University of Utah and the Flux Group.
|
|
* All rights reserved.
|
|
*
|
|
* This file is part of the Flux OSKit. The OSKit is free software, also known
|
|
* as "open source;" you can redistribute it and/or modify it under the terms
|
|
* of the GNU General Public License (GPL), version 2, as published by the Free
|
|
* Software Foundation (FSF). To explore alternate licensing terms, contact
|
|
* the University of Utah at csl-dist@cs.utah.edu or +1-801-585-3271.
|
|
*
|
|
* The OSKit is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
* FOR A PARTICULAR PURPOSE. See the GPL for more details. You should have
|
|
* received a copy of the GPL along with the OSKit; see the file COPYING. If
|
|
* not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
/*
|
|
* Definitions for a COM object containing and wrapping the four interfaces
|
|
* contained in our socket implementation - socket, stream, asyncio, and
|
|
* bufio_stream.
|
|
*/
|
|
|
|
#include <oskit/com.h>
|
|
#include <oskit/com/wrapper.h>
|
|
#include <oskit/net/socket.h>
|
|
#include <oskit/c/string.h>
|
|
#include <oskit/c/stdlib.h>
|
|
#include <oskit/c/stdio.h>
|
|
#include <oskit/io/asyncio.h>
|
|
#include <oskit/io/bufio_stream.h>
|
|
|
|
/*
|
|
* Wrapped up socket interfaces.
|
|
*/
|
|
typedef struct {
|
|
oskit_socket_t ioi; /* COM I/O interface Nr. 1 */
|
|
oskit_stream_t ios; /* COM I/O interface Nr. 2 */
|
|
oskit_asyncio_t ioa; /* COM I/O interface Nr. 3 */
|
|
oskit_bufio_stream_t iob; /* COM I/O interface Nr. 4 */
|
|
unsigned count; /* reference count */
|
|
oskit_socket_t *w_ioi; /* COM I/O interface Nr. 1 */
|
|
oskit_stream_t *w_ios; /* COM I/O interface Nr. 2 */
|
|
oskit_asyncio_t *w_ioa; /* COM I/O interface Nr. 3 */
|
|
oskit_bufio_stream_t *w_iob; /* COM I/O interface Nr. 4 */
|
|
void (*before)(void *);
|
|
void (*after)(void *);
|
|
void *cookie;
|
|
} oskit_sockimpl_t;
|
|
|
|
#define WRAPPERCALL(impl, ops, iface, call, args...) ({ \
|
|
oskit_error_t __err; \
|
|
impl->before(impl->cookie); \
|
|
__err = oskit_##iface##_##call(impl->w_##ops ,##args); \
|
|
impl->after(impl->cookie); \
|
|
__err; })
|
|
|
|
#define WRAPPERCALL_NOARGS(impl, ops, iface, call) ({ \
|
|
oskit_error_t __err; \
|
|
impl->before(impl->cookie); \
|
|
__err = oskit_##iface##_##call(impl->w_##ops); \
|
|
impl->after(impl->cookie); \
|
|
__err; })
|
|
|
|
/*
|
|
* implementations of query, addref and release dealing with
|
|
* different COM interfaces.
|
|
*/
|
|
|
|
static OSKIT_COMDECL_U addref(oskit_sockimpl_t *b);
|
|
/*
|
|
* query
|
|
*/
|
|
|
|
static OSKIT_COMDECL
|
|
query(oskit_sockimpl_t *b, const struct oskit_guid *iid, void **out_ihandle)
|
|
{
|
|
oskit_error_t rc = 0;
|
|
|
|
b->before(b->cookie);
|
|
if (memcmp(iid, &oskit_iunknown_iid, sizeof(*iid)) == 0 ||
|
|
memcmp(iid, &oskit_posixio_iid, sizeof(*iid)) == 0 ||
|
|
memcmp(iid, &oskit_socket_iid, sizeof(*iid)) == 0) {
|
|
*out_ihandle = &b->ioi;
|
|
++b->count;
|
|
b->after(b->cookie);
|
|
return 0;
|
|
}
|
|
|
|
if (memcmp(iid, &oskit_stream_iid, sizeof(*iid)) == 0) {
|
|
if (b->w_ios == 0)
|
|
rc = oskit_socket_query(b->w_ioi,
|
|
&oskit_stream_iid, (void **)&b->w_ios);
|
|
if (rc == 0) {
|
|
*out_ihandle = &b->ios;
|
|
++b->count;
|
|
b->after(b->cookie);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (memcmp(iid, &oskit_bufio_stream_iid, sizeof(*iid)) == 0) {
|
|
if (b->w_iob == 0)
|
|
rc = oskit_socket_query(b->w_ioi,
|
|
&oskit_bufio_stream_iid, (void **)&b->w_iob);
|
|
if (rc == 0) {
|
|
*out_ihandle = &b->iob;
|
|
++b->count;
|
|
b->after(b->cookie);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (memcmp(iid, &oskit_asyncio_iid, sizeof(*iid)) == 0) {
|
|
if (b->w_ioa == 0)
|
|
rc = oskit_socket_query(b->w_ioi,
|
|
&oskit_asyncio_iid, (void **)&b->w_ioa);
|
|
if (rc == 0) {
|
|
*out_ihandle = &b->ioa;
|
|
++b->count;
|
|
b->after(b->cookie);
|
|
return 0;
|
|
}
|
|
}
|
|
b->after(b->cookie);
|
|
|
|
*out_ihandle = NULL;
|
|
return OSKIT_E_NOINTERFACE;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
socket_query(oskit_socket_t *f, const struct oskit_guid *iid,
|
|
void **out_ihandle)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)f;
|
|
return query(b, iid, out_ihandle);
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
opensocket_query(oskit_stream_t *f, const struct oskit_guid *iid,
|
|
void **out_ihandle)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(f-1);
|
|
return query(b, iid, out_ihandle);
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
asyncio_query(oskit_asyncio_t *f, const struct oskit_guid *iid,
|
|
void **out_ihandle)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(f-2);
|
|
return query(b, iid, out_ihandle);
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
bufio_stream_query(oskit_bufio_stream_t *f, const struct oskit_guid *iid,
|
|
void **out_ihandle)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(f-3);
|
|
return query(b, iid, out_ihandle);
|
|
}
|
|
|
|
/*
|
|
* addref
|
|
*/
|
|
static OSKIT_COMDECL_U
|
|
addref(oskit_sockimpl_t *b)
|
|
{
|
|
unsigned newcount;
|
|
b->before(b->cookie);
|
|
newcount = ++b->count;
|
|
b->after(b->cookie);
|
|
return newcount;
|
|
}
|
|
|
|
static OSKIT_COMDECL_U
|
|
socket_addref(oskit_socket_t *f)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)f;
|
|
return addref(b);
|
|
}
|
|
|
|
static OSKIT_COMDECL_U
|
|
opensocket_addref(oskit_stream_t *f)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(f-1);
|
|
return addref(b);
|
|
}
|
|
|
|
static OSKIT_COMDECL_U
|
|
asyncio_addref(oskit_asyncio_t *f)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(f-2);
|
|
return addref(b);
|
|
}
|
|
|
|
static OSKIT_COMDECL_U
|
|
bufio_stream_addref(oskit_bufio_stream_t *f)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(f-3);
|
|
return addref(b);
|
|
}
|
|
|
|
/*
|
|
* release. The contained sockimpl was released, so release the wrapper.
|
|
*/
|
|
static OSKIT_COMDECL_U
|
|
release(oskit_sockimpl_t *b)
|
|
{
|
|
unsigned newcount;
|
|
|
|
b->before(b->cookie);
|
|
if ((newcount = --b->count) == 0) {
|
|
if (b->w_ioi)
|
|
oskit_socket_release(b->w_ioi);
|
|
if (b->w_ios)
|
|
oskit_stream_release(b->w_ios);
|
|
if (b->w_ioa)
|
|
oskit_asyncio_release(b->w_ioa);
|
|
if (b->w_iob)
|
|
oskit_bufio_stream_release(b->w_iob);
|
|
b->after(b->cookie);
|
|
free(b);
|
|
} else {
|
|
b->after(b->cookie);
|
|
}
|
|
return newcount;
|
|
}
|
|
|
|
static OSKIT_COMDECL_U
|
|
socket_release(oskit_socket_t *f)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)f;
|
|
return release(b);
|
|
}
|
|
|
|
static OSKIT_COMDECL_U
|
|
opensocket_release(oskit_stream_t *f)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(f-1);
|
|
return release(b);
|
|
}
|
|
|
|
static OSKIT_COMDECL_U
|
|
asyncio_release(oskit_asyncio_t *f)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(f-2);
|
|
return release(b);
|
|
}
|
|
|
|
static OSKIT_COMDECL_U
|
|
bufio_stream_release(oskit_bufio_stream_t *f)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(f-3);
|
|
return release(b);
|
|
}
|
|
|
|
/*******************************************************/
|
|
/******* Implementation of the oskit_socket_t if ********/
|
|
/*******************************************************/
|
|
|
|
/*** Operations inherited from oskit_posixio_t ***/
|
|
static OSKIT_COMDECL
|
|
socket_stat(oskit_socket_t *f, struct oskit_stat *out_stats)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(f);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(b, ioi, socket, stat, out_stats);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
socket_setstat(oskit_socket_t *f, oskit_u32_t mask,
|
|
const struct oskit_stat *stats)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(f);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(b, ioi, socket, setstat, mask, stats);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
socket_pathconf(oskit_socket_t *f, oskit_s32_t option, oskit_s32_t *out_val)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(f);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(b, ioi, socket, pathconf, option, out_val);
|
|
|
|
return err;
|
|
}
|
|
|
|
/*** Operations specific to oskit_socket_t ***/
|
|
static OSKIT_COMDECL
|
|
socket_accept(oskit_socket_t *s, struct oskit_sockaddr *name,
|
|
oskit_size_t *anamelen, struct oskit_socket **newopenso)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(s);
|
|
oskit_error_t err;
|
|
oskit_socket_t *newso;
|
|
|
|
err = WRAPPERCALL(b, ioi, socket, accept, name, anamelen, &newso);
|
|
if (err == 0) {
|
|
err = oskit_wrap_sockio(newso,
|
|
b->before, b->after, b->cookie, newopenso);
|
|
oskit_socket_release(newso);
|
|
}
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
socket_bind(oskit_socket_t *s, const struct oskit_sockaddr *name,
|
|
oskit_size_t namelen)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(s);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(b, ioi, socket, bind, name, namelen);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
socket_connect(oskit_socket_t *s, const struct oskit_sockaddr *name,
|
|
oskit_size_t namelen)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(s);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(b, ioi, socket, connect, name, namelen);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
socket_listen(oskit_socket_t *s, oskit_u32_t n)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(s);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(b, ioi, socket, listen, n);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
socket_getsockname(oskit_socket_t *s, struct oskit_sockaddr *asa,
|
|
oskit_size_t *alen)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(s);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(b, ioi, socket, getsockname, asa, alen);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
socket_setsockopt(oskit_socket_t *s, oskit_u32_t level, oskit_u32_t name,
|
|
const void *val, oskit_size_t valsize)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(s);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(b, ioi, socket, setsockopt,
|
|
level, name, val, valsize);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
socket_sendto(oskit_socket_t *s, const void *msg, oskit_size_t len,
|
|
oskit_u32_t flags, const struct oskit_sockaddr *to,
|
|
oskit_size_t tolen, oskit_size_t *retval)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(s);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(b, ioi, socket, sendto,
|
|
msg, len, flags, to, tolen, retval);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
socket_recvfrom(oskit_socket_t *s, void *buf,
|
|
oskit_size_t len, oskit_u32_t flags,
|
|
struct oskit_sockaddr *from, oskit_size_t *fromlen,
|
|
oskit_size_t *retval)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(s);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(b, ioi, socket, recvfrom,
|
|
buf, len, flags, from, fromlen, retval);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
socket_getsockopt(oskit_socket_t *s, oskit_u32_t level, oskit_u32_t name,
|
|
void *val, oskit_size_t *valsize)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(s);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(b, ioi, socket, getsockopt,
|
|
level, name, val, valsize);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
socket_sendmsg(oskit_socket_t *s, const struct oskit_msghdr *msg,
|
|
oskit_u32_t flags, oskit_size_t *retval)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(s);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(b, ioi, socket, sendmsg, msg, flags, retval);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
socket_recvmsg(oskit_socket_t *s, struct oskit_msghdr *msg,
|
|
oskit_u32_t flags, oskit_size_t *retval)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(s);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(b, ioi, socket, recvmsg, msg, flags, retval);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
socket_getpeername(oskit_socket_t *f,
|
|
struct oskit_sockaddr *asa, oskit_size_t *alen)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(f);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(b, ioi, socket, getpeername, asa, alen);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
socket_shutdown(oskit_socket_t *f, oskit_u32_t how)
|
|
{
|
|
oskit_sockimpl_t *b = (oskit_sockimpl_t *)(f);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(b, ioi, socket, shutdown, how);
|
|
|
|
return err;
|
|
}
|
|
|
|
/*******************************************************/
|
|
/******* Implementation of the oskit_stream_t if ********/
|
|
/*******************************************************/
|
|
|
|
/*** Operations inherited from oskit_stream interface ***/
|
|
static OSKIT_COMDECL
|
|
opensocket_read(oskit_stream_t *f, void *buf, oskit_u32_t len,
|
|
oskit_u32_t *out_actual)
|
|
{
|
|
oskit_sockimpl_t *s = (oskit_sockimpl_t *)(f-1);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(s, ios, stream, read, buf, len, out_actual);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
opensocket_write(oskit_stream_t *f, const void *buf,
|
|
oskit_u32_t len, oskit_u32_t *out_actual)
|
|
{
|
|
oskit_sockimpl_t *s = (oskit_sockimpl_t *)(f-1);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(s, ios, stream, write, buf, len, out_actual);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
opensocket_seek(oskit_stream_t *f, oskit_s64_t ofs,
|
|
oskit_seek_t whence, oskit_u64_t *out_newpos)
|
|
{
|
|
oskit_sockimpl_t *s = (oskit_sockimpl_t *)(f-1);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(s, ios, stream, seek, ofs, whence, out_newpos);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
opensocket_setsize(oskit_stream_t *f, oskit_u64_t new_size)
|
|
{
|
|
oskit_sockimpl_t *s = (oskit_sockimpl_t *)(f-1);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(s, ios, stream, setsize, new_size);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
opensocket_copyto(oskit_stream_t *f, oskit_stream_t *dst,
|
|
oskit_u64_t size,
|
|
oskit_u64_t *out_read,
|
|
oskit_u64_t *out_written)
|
|
{
|
|
oskit_sockimpl_t *s = (oskit_sockimpl_t *)(f-1);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(s, ios, stream, copyto,
|
|
dst, size, out_read, out_written);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
opensocket_commit(oskit_stream_t *f, oskit_u32_t commit_flags)
|
|
{
|
|
oskit_sockimpl_t *s = (oskit_sockimpl_t *)(f-1);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(s, ios, stream, commit, commit_flags);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
opensocket_revert(oskit_stream_t *f)
|
|
{
|
|
oskit_sockimpl_t *s = (oskit_sockimpl_t *)(f-1);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL_NOARGS(s, ios, stream, revert);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
opensocket_lock_region(oskit_stream_t *f,
|
|
oskit_u64_t offset, oskit_u64_t size, oskit_u32_t lock_type)
|
|
{
|
|
oskit_sockimpl_t *s = (oskit_sockimpl_t *)(f-1);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(s, ios, stream, lockregion,
|
|
offset, size, lock_type);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
opensocket_unlock_region(oskit_stream_t *f,
|
|
oskit_u64_t offset, oskit_u64_t size, oskit_u32_t lock_type)
|
|
{
|
|
oskit_sockimpl_t *s = (oskit_sockimpl_t *)(f-1);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(s, ios, stream, unlockregion,
|
|
offset, size, lock_type);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
opensocket_stat(oskit_stream_t *f, oskit_stream_stat_t *out_stat,
|
|
oskit_u32_t stat_flags)
|
|
{
|
|
oskit_sockimpl_t *s = (oskit_sockimpl_t *)(f-1);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(s, ios, stream, stat, out_stat, stat_flags);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
opensocket_clone(oskit_stream_t *f, oskit_stream_t **out_stream)
|
|
{
|
|
oskit_sockimpl_t *s = (oskit_sockimpl_t *)(f-1);
|
|
oskit_error_t err;
|
|
oskit_stream_t *str;
|
|
|
|
err = WRAPPERCALL(s, ios, stream, clone, &str);
|
|
if (err == 0) {
|
|
/* wrap the stream interface only !? */
|
|
err = oskit_wrap_stream(str,
|
|
s->before, s->after, s->cookie,
|
|
out_stream);
|
|
oskit_stream_release(str);
|
|
}
|
|
return err;
|
|
}
|
|
|
|
/*******************************************************/
|
|
/******* Implementation of the oskit_asyncio_t if *******/
|
|
/*******************************************************/
|
|
|
|
static OSKIT_COMDECL
|
|
asyncio_poll(oskit_asyncio_t *f)
|
|
{
|
|
oskit_sockimpl_t *si = (oskit_sockimpl_t *)(f-2);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL_NOARGS(si, ioa, asyncio, poll);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
asyncio_add_listener(oskit_asyncio_t *f, struct oskit_listener *l,
|
|
oskit_s32_t mask)
|
|
{
|
|
oskit_sockimpl_t *si = (oskit_sockimpl_t *)(f-2);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(si, ioa, asyncio, add_listener, l, mask);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
asyncio_remove_listener(oskit_asyncio_t *f, struct oskit_listener *l0)
|
|
{
|
|
oskit_sockimpl_t *si = (oskit_sockimpl_t *)(f-2);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(si, ioa, asyncio, remove_listener, l0);
|
|
|
|
return err;
|
|
}
|
|
/*
|
|
* return the number of bytes that can be read, basically ioctl(FIONREAD)
|
|
*/
|
|
static OSKIT_COMDECL
|
|
asyncio_readable(oskit_asyncio_t *f)
|
|
{
|
|
oskit_sockimpl_t *si = (oskit_sockimpl_t *)(f-2);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL_NOARGS(si, ioa, asyncio, readable);
|
|
|
|
return err;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
/*
|
|
* methods of bufio_streams
|
|
*/
|
|
static OSKIT_COMDECL
|
|
bufio_stream_read(oskit_bufio_stream_t *f,
|
|
struct oskit_bufio **buf, oskit_size_t *bytes)
|
|
{
|
|
oskit_sockimpl_t *si = (oskit_sockimpl_t *)(f-3);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(si, iob, bufio_stream, read, buf, bytes);
|
|
|
|
return err;
|
|
}
|
|
|
|
static OSKIT_COMDECL
|
|
bufio_stream_write(oskit_bufio_stream_t *f,
|
|
struct oskit_bufio *buf, oskit_size_t offset)
|
|
{
|
|
oskit_sockimpl_t *si = (oskit_sockimpl_t *)(f-3);
|
|
oskit_error_t err;
|
|
|
|
err = WRAPPERCALL(si, iob, bufio_stream, write, buf, offset);
|
|
|
|
return err;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
/*
|
|
* vtables for interfaces exported by sockets
|
|
*/
|
|
static struct oskit_socket_ops sockops =
|
|
{
|
|
socket_query,
|
|
socket_addref,
|
|
socket_release,
|
|
socket_stat,
|
|
socket_setstat,
|
|
socket_pathconf,
|
|
socket_accept,
|
|
socket_bind,
|
|
socket_connect,
|
|
socket_shutdown,
|
|
socket_listen,
|
|
socket_getsockname,
|
|
socket_getpeername,
|
|
socket_getsockopt,
|
|
socket_setsockopt,
|
|
socket_sendto,
|
|
socket_recvfrom,
|
|
socket_sendmsg,
|
|
socket_recvmsg
|
|
};
|
|
|
|
static struct oskit_stream_ops opensockops =
|
|
{
|
|
opensocket_query,
|
|
opensocket_addref,
|
|
opensocket_release,
|
|
opensocket_read,
|
|
opensocket_write,
|
|
opensocket_seek,
|
|
opensocket_setsize,
|
|
opensocket_copyto,
|
|
opensocket_commit,
|
|
opensocket_revert,
|
|
opensocket_lock_region,
|
|
opensocket_unlock_region,
|
|
opensocket_stat,
|
|
opensocket_clone
|
|
};
|
|
|
|
static struct oskit_asyncio_ops asyncioops =
|
|
{
|
|
asyncio_query,
|
|
asyncio_addref,
|
|
asyncio_release,
|
|
asyncio_poll,
|
|
asyncio_add_listener,
|
|
asyncio_remove_listener,
|
|
asyncio_readable
|
|
};
|
|
|
|
static struct oskit_bufio_stream_ops bufio_streamops =
|
|
{
|
|
bufio_stream_query,
|
|
bufio_stream_addref,
|
|
bufio_stream_release,
|
|
bufio_stream_read,
|
|
bufio_stream_write
|
|
};
|
|
|
|
/*
|
|
* Wrap a sockimpl in the thread specific version.
|
|
*/
|
|
oskit_error_t
|
|
oskit_wrap_sockio(struct oskit_socket *in,
|
|
void (*before)(),
|
|
void (*after)(),
|
|
void *cookie,
|
|
struct oskit_socket **out)
|
|
{
|
|
oskit_sockimpl_t *newsi = malloc(sizeof(*newsi));
|
|
|
|
if (newsi == NULL)
|
|
return OSKIT_ENOMEM;
|
|
memset(newsi, 0, sizeof(*newsi));
|
|
|
|
newsi->count = 1;
|
|
newsi->ioi.ops = &sockops;
|
|
newsi->ios.ops = &opensockops;
|
|
newsi->ioa.ops = &asyncioops;
|
|
newsi->iob.ops = &bufio_streamops;
|
|
newsi->w_ioi = in;
|
|
oskit_socket_addref(newsi->w_ioi);
|
|
|
|
newsi->before = before;
|
|
newsi->after = after;
|
|
newsi->cookie = cookie;
|
|
|
|
*out = &newsi->ioi;
|
|
return 0;
|
|
}
|