oskit/oskit-20020317/unix/socket.c

878 lines
23 KiB
C
Executable File

/*
* Copyright (c) 1998, 1999, 2000, 2001 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.
*/
/*
* Implementation of socket factory and socket based on NATIVEOS() functions.
*
* This implementation is incomplete (asyncio listeners are missing),
* untested and mostly likely not working.
*
* Use
*
* oskit_error_t
* oskit_native_net_init(oskit_socket_factory_t **f);
*
* to access it.
*/
/*
* OS Kit includes
*/
#include <oskit/dev/dev.h>
#include <oskit/net/socket.h>
#include <oskit/io/asyncio.h>
#include <oskit/io/bufio_stream.h>
#include <oskit/com/listener_mgr.h>
#include <oskit/clientos.h>
#include <oskit/net/socket.h>
#include "native.h"
#include "support.h"
/*
* FreeBSD includes
*/
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <string.h>
#include <errno.h>
/*
* socket implementation
*/
struct oskit_sockimpl {
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 */
unsigned count; /* reference count */
int fd; /* native OS fd */
osenv_sleeprec_t sleeprec; /* For non-blocking I/O */
oskit_u32_t selmask; /* Select mask */
struct listener_mgr *readers; /* listeners for asyncio READ */
struct listener_mgr *writers; /* listeners for asyncio WRITE*/
};
typedef struct oskit_sockimpl oskit_sockimpl_t;
static oskit_sockimpl_t * create_sockimpl(int fd);
/*
* implementations of query, addref and release dealing with
* different COM interfaces
*/
/*
* query
*/
static oskit_error_t
query(oskit_sockimpl_t *b, const struct oskit_guid *iid, void **out_ihandle)
{
if (b == NULL)
osenv_panic("%s:%d: null oskit_sockimpl_t", __FILE__, __LINE__);
if (b->count == 0)
osenv_panic("%s:%d: bad count", __FILE__, __LINE__);
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;
return 0;
}
if (memcmp(iid, &oskit_stream_iid, sizeof(*iid)) == 0) {
*out_ihandle = &b->ios;
++b->count;
return 0;
}
if (memcmp(iid, &oskit_asyncio_iid, sizeof(*iid)) == 0) {
*out_ihandle = &b->ioa;
++b->count;
return 0;
}
*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);
}
/*
* addref
*/
static oskit_u32_t
addref(oskit_sockimpl_t *b)
{
if (b == NULL)
osenv_panic("%s:%d: null oskit_sockimpl_t", __FILE__, __LINE__);
if (b->count == 0)
osenv_panic("%s:%d: bad count", __FILE__, __LINE__);
return ++b->count;
}
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);
}
/*
* release
*/
static oskit_u32_t
release(oskit_sockimpl_t *si)
{
unsigned newcount;
if (si == NULL)
osenv_panic("%s:%d: null sockimpl_t", __FILE__, __LINE__);
if (si->count == 0)
osenv_panic("%s:%d: bad count", __FILE__, __LINE__);
if ((newcount = --si->count) == 0) {
oskitunix_unregister_async_fd(si->fd);
NATIVEOS(close)(si->fd);
oskit_destroy_listener_mgr(si->readers);
oskit_destroy_listener_mgr(si->writers);
osenv_mem_free(si, 0, sizeof(*si));
}
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);
}
/*******************************************************/
/******* 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)
{
/* XXX do a fstat and convert the values */
memset(out_stats, 0, sizeof *out_stats);
out_stats->mode = OSKIT_S_IFSOCK;
return 0;
}
static OSKIT_COMDECL
socket_setstat(oskit_socket_t *f, oskit_u32_t mask,
const struct oskit_stat *stats)
{
return OSKIT_ENOTSUP;
}
static OSKIT_COMDECL
socket_pathconf(oskit_socket_t *f, oskit_s32_t option, oskit_s32_t *out_val)
{
return OSKIT_ENOTSUP;
}
#ifdef NATIVE_HAVE_SA_LEN
#define SA_FIX_OUT(sa, salen) ((void)0)
#define SA_IN(sa, salen) struct sockaddr *const SA = (void *)(sa);
#else
#define SA_FIX_OUT(sa, len) \
((((struct oskit_sockaddr *) (sa))->sa_family = \
((struct sockaddr *) (sa))->sa_family), \
((struct oskit_sockaddr *) (sa))->sa_len = (len))
#define SA_IN(sa, salen) \
struct sockaddr _sa, *const SA = &_sa; \
assert((salen) <= sizeof _sa); \
_sa.sa_family = (sa)->sa_family; \
memcpy(_sa.sa_data, (sa)->sa_data, \
(salen) - offsetof(struct oskit_sockaddr, sa_data))
#endif
/*** 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;
int nfd;
assert(offsetof(struct oskit_sockaddr, sa_data) ==
offsetof(struct sockaddr, sa_data));
if ((nfd = oskitunix_threaded_accept(((oskit_sockimpl_t*)s)->fd,
(struct sockaddr *)name, anamelen)) < 0)
return native_to_oskit_error(NATIVEOS(errno));
SA_FIX_OUT(name, *anamelen);
/* create a new sockimpl */
b = create_sockimpl(nfd); /* XXX error check */
*newopenso = &b->ioi;
return 0;
}
static OSKIT_COMDECL
socket_bind(oskit_socket_t *s, const struct oskit_sockaddr *name,
oskit_size_t namelen)
{
SA_IN(name, namelen);
if (NATIVEOS(bind)(((oskit_sockimpl_t *)s)->fd,
SA, namelen) < 0)
return native_to_oskit_error(NATIVEOS(errno));
return 0;
}
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;
SA_IN(name, namelen);
if (oskitunix_threaded_connect(b->fd, SA, namelen) < 0)
return native_to_oskit_error(NATIVEOS(errno));
return 0;
}
static OSKIT_COMDECL
socket_listen(oskit_socket_t *s, oskit_u32_t n)
{
if (NATIVEOS(listen)(((oskit_sockimpl_t *)s)->fd, n) < 0)
return native_to_oskit_error(NATIVEOS(errno));
return 0;
}
static OSKIT_COMDECL
socket_getsockname(oskit_socket_t *s, struct oskit_sockaddr *asa,
oskit_size_t *alen)
{
if (NATIVEOS(getsockname)(((oskit_sockimpl_t *)s)->fd,
(struct sockaddr *)asa, alen) < 0)
return native_to_oskit_error(NATIVEOS(errno));
SA_FIX_OUT(asa, *alen);
return 0;
}
/* XXX translate sockopts! */
static OSKIT_COMDECL
socket_setsockopt(oskit_socket_t *s, oskit_u32_t level, oskit_u32_t name,
const void *val, oskit_size_t valsize)
{
if (NATIVEOS(setsockopt)(((oskit_sockimpl_t *)s)->fd,
level, name, val, valsize) < 0)
return native_to_oskit_error(NATIVEOS(errno));
return 0;
}
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)
{
int count;
SA_IN(to, tolen);
if ((count = oskitunix_threaded_sendto(((oskit_sockimpl_t *)s)->fd,
msg, len, flags,
SA, tolen)) < 0)
return native_to_oskit_error(NATIVEOS(errno));
*retval = (oskit_size_t) count;
return 0;
}
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)
{
int count;
if ((count = oskitunix_threaded_recvfrom(((oskit_sockimpl_t *)s)->fd,
buf, len, flags,
(struct sockaddr *)from, fromlen)) < 0)
return native_to_oskit_error(NATIVEOS(errno));
SA_FIX_OUT(from, *fromlen);
*retval = (oskit_size_t) count;
return 0;
}
static OSKIT_COMDECL
socket_getsockopt(oskit_socket_t *s, oskit_u32_t level, oskit_u32_t name,
void *val, oskit_size_t *valsize)
{
return OSKIT_E_NOTIMPL;
}
static OSKIT_COMDECL
socket_sendmsg(oskit_socket_t *s, const struct oskit_msghdr *msg,
oskit_u32_t flags, oskit_size_t *retval)
{
return OSKIT_E_NOTIMPL;
}
static OSKIT_COMDECL
socket_recvmsg(oskit_socket_t *s, struct oskit_msghdr *msg,
oskit_u32_t flags, oskit_size_t *retval)
{
return OSKIT_E_NOTIMPL;
}
static OSKIT_COMDECL
socket_getpeername(oskit_socket_t *f,
struct oskit_sockaddr *asa, oskit_size_t *alen)
{
oskit_sockimpl_t *s = (oskit_sockimpl_t *)f;
if (NATIVEOS(getpeername)(s->fd, (struct sockaddr *)asa, alen) < 0)
return native_to_oskit_error(NATIVEOS(errno));
SA_FIX_OUT(asa, *alen);
return 0;
}
static OSKIT_COMDECL
socket_shutdown(oskit_socket_t *f, oskit_u32_t how)
{
if (NATIVEOS(shutdown)(((oskit_sockimpl_t *)f)->fd, how) < 0)
return native_to_oskit_error(NATIVEOS(errno));
return 0;
}
/*******************************************************/
/******* 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);
int count;
if ((count = oskitunix_threaded_read(s->fd, buf, len)) < 0)
return native_to_oskit_error(NATIVEOS(errno));
*out_actual = count;
return 0;
}
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);
int count;
if ((count = oskitunix_threaded_write(s->fd, buf, len)) < 0)
return native_to_oskit_error(NATIVEOS(errno));
*out_actual = count;
return 0;
}
static OSKIT_COMDECL
opensocket_seek(oskit_stream_t *f, oskit_s64_t ofs,
oskit_seek_t whence, oskit_u64_t *out_newpos)
{
return OSKIT_E_NOTIMPL;
}
static OSKIT_COMDECL
opensocket_setsize(oskit_stream_t *f, oskit_u64_t new_size)
{
return OSKIT_E_NOTIMPL;
}
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)
{
return OSKIT_E_NOTIMPL;
}
static OSKIT_COMDECL
opensocket_commit(oskit_stream_t *f, oskit_u32_t commit_flags)
{
return OSKIT_E_NOTIMPL;
}
static OSKIT_COMDECL
opensocket_revert(oskit_stream_t *f)
{
return OSKIT_E_NOTIMPL;
}
static OSKIT_COMDECL
opensocket_lock_region(oskit_stream_t *f,
oskit_u64_t offset, oskit_u64_t size, oskit_u32_t lock_type)
{
return OSKIT_E_NOTIMPL;
}
static OSKIT_COMDECL
opensocket_unlock_region(oskit_stream_t *f,
oskit_u64_t offset, oskit_u64_t size, oskit_u32_t lock_type)
{
return OSKIT_E_NOTIMPL;
}
static OSKIT_COMDECL
opensocket_stat(oskit_stream_t *f, oskit_stream_stat_t *out_stat,
oskit_u32_t stat_flags)
{
/* this should be implemented soon */
return OSKIT_E_NOTIMPL;
}
static OSKIT_COMDECL
opensocket_clone(oskit_stream_t *f, oskit_stream_t **out_stream)
{
return OSKIT_E_NOTIMPL;
}
/*******************************************************/
/******* Implementation of the oskit_asyncio_t if *******/
/*******************************************************/
/*
* return a mask with all conditions that currently apply to that socket
* must be called with splnet()!
*/
static oskit_u32_t
get_socket_conditions(int fd)
{
oskit_u32_t res = 0;
int r;
struct timeval nulltime = { 0, 0 };
fd_set in, out, err;
FD_ZERO(&in);
FD_ZERO(&out);
FD_ZERO(&err);
FD_SET(fd, &in);
FD_SET(fd, &out);
FD_SET(fd, &err);
/* poll socket */
r = NATIVEOS(select) (fd + 1, &in, &out, &err, &nulltime);
if (r < 1)
return res;
if (FD_ISSET(fd, &in))
res |= OSKIT_ASYNCIO_READABLE;
if (FD_ISSET(fd, &out))
res |= OSKIT_ASYNCIO_WRITABLE;
if (FD_ISSET(fd, &err))
res |= OSKIT_ASYNCIO_EXCEPTION;
return res;
}
/*
* Callback for asyncio interface. Determine which conditions are
* ready and requested, and initiate those callbacks.
*/
static void
asyncio_callback(void *arg)
{
oskit_sockimpl_t *si = (oskit_sockimpl_t *) arg;
oskit_u32_t ready;
unsigned iotype = 0;
ready = si->selmask & get_socket_conditions(si->fd);
/* for read and exceptional conditions */
if (ready & (OSKIT_ASYNCIO_READABLE | OSKIT_ASYNCIO_EXCEPTION)) {
oskit_listener_mgr_notify(si->readers);
iotype |= IOTYPE_READ;
}
/* for write */
if (ready & OSKIT_ASYNCIO_WRITABLE) {
oskit_listener_mgr_notify(si->writers);
iotype |= IOTYPE_WRITE;
}
}
/*
* Poll for currently pending asynchronous I/O conditions.
* If successful, returns a mask of the OSKIT_ASYNC_IO_* flags above,
* indicating which conditions are currently present.
*/
static OSKIT_COMDECL
asyncio_poll(oskit_asyncio_t *f)
{
oskit_sockimpl_t *si = (oskit_sockimpl_t *)(f-2);
oskit_u32_t cond;
int enabled;
enabled = osenv_intr_save_disable();
cond = get_socket_conditions(si->fd);
if (enabled)
osenv_intr_enable();
return cond;
}
/*
* Add a callback object (a "listener" for async I/O events).
* When an event of interest occurs on this I/O object
* (i.e., when one of the three I/O conditions becomes true),
* all registered listeners will be called.
* Also, if successful, this method returns a mask
* describing which of the OSKIT_ASYNC_IO_* conditions are already true,
* which the caller must check in order to avoid missing events
* that occur just before the listener is registered.
*/
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_s32_t cond;
int enabled;
unsigned iotype = 0;
enabled = osenv_intr_save_disable();
cond = get_socket_conditions(si->fd);
/* for read and exceptional conditions */
if (mask & (OSKIT_ASYNCIO_READABLE | OSKIT_ASYNCIO_EXCEPTION)) {
oskit_listener_mgr_add(si->readers, l);
iotype |= IOTYPE_READ;
}
/* for write */
if (mask & OSKIT_ASYNCIO_WRITABLE) {
oskit_listener_mgr_add(si->writers, l);
iotype |= IOTYPE_WRITE;
}
si->selmask |= mask;
oskitunix_register_async_fd(si->fd, iotype, asyncio_callback, si);
if (enabled)
osenv_intr_enable();
return cond;
}
/*
* Remove a previously registered listener callback object.
* Returns an error if the specified callback has not been registered.
*/
static OSKIT_COMDECL
asyncio_remove_listener(oskit_asyncio_t *f, struct oskit_listener *l0)
{
oskit_sockimpl_t *si = (oskit_sockimpl_t *)(f-2);
int enabled;
oskit_error_t rc1, rc2;
/*
* protect against interrupts, since clients might call
* remove_listener out of the asynciolistener callback
*/
enabled = osenv_intr_save_disable();
/*
* we don't know where was added - if at all - so let's check
* both lists
*
* turn off notifications if no listeners left
*/
rc1 = oskit_listener_mgr_remove(si->readers, l0);
if (oskit_listener_mgr_count(si->readers) == 0)
si->selmask &=
~(OSKIT_ASYNCIO_READABLE | OSKIT_ASYNCIO_EXCEPTION);
rc2 = oskit_listener_mgr_remove(si->writers, l0);
if (oskit_listener_mgr_count(si->writers) == 0)
si->selmask &= ~(OSKIT_ASYNCIO_WRITABLE);
if (! si->selmask)
oskitunix_unregister_async_fd(si->fd);
if (enabled)
osenv_intr_enable();
/* flag error if both removes failed */
return (rc1 && rc2) ? OSKIT_E_INVALIDARG : 0; /* is that right ? */
}
/*
* 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);
int b;
int rc;
rc = NATIVEOS(ioctl)(si->fd, FIONREAD, &b);
return b; /* XXX ??? */
}
/***************************************************************************/
/*
* 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
};
/*
* create the COM part of a new sockimpl object
*/
static oskit_sockimpl_t *
create_sockimpl(int fd)
{
int rc;
oskit_sockimpl_t *si = osenv_mem_alloc(sizeof(*si), 0, 0);
if (si == NULL)
return NULL;
memset(si, 0, sizeof(*si));
si->count = 1;
si->ioi.ops = &sockops;
si->ios.ops = &opensockops;
si->ioa.ops = &asyncioops;
si->fd = fd;
si->readers = oskit_create_listener_mgr((oskit_iunknown_t *)&si->ioa);
si->writers = oskit_create_listener_mgr((oskit_iunknown_t *)&si->ioa);
rc = oskitunix_set_async_fd(fd);
if (rc)
osenv_panic("%s:%d: "
"OSKit/UNIX emulation fault: cannot make fd (%d)"
" async/non-blocking: native errno=%d\n",
__FILE__, __LINE__,
fd, rc);
return si;
}
/***************************************************************************/
/*
* methods of socket_factories
*/
static OSKIT_COMDECL
socket_factory_query(oskit_socket_factory_t *b,
const struct oskit_guid *iid, void **out_ihandle)
{
if (memcmp(iid, &oskit_iunknown_iid, sizeof(*iid)) == 0 ||
memcmp(iid, &oskit_socket_factory_iid, sizeof(*iid)) == 0) {
*out_ihandle = b;
return 0;
}
*out_ihandle = NULL;
return OSKIT_E_NOINTERFACE;
}
static OSKIT_COMDECL_U
socket_factory_addref(oskit_socket_factory_t *b)
{
return 1;
}
static OSKIT_COMDECL_U
socket_factory_release(oskit_socket_factory_t *b)
{
return 1;
}
/*
* function to create a socket - analog to socket(2)
*/
static OSKIT_COMDECL
socket_factory_create(
oskit_socket_factory_t *factory,
oskit_u32_t domain,
oskit_u32_t type, oskit_u32_t protocol, oskit_socket_t **aso)
{
oskit_sockimpl_t *b;
int fd;
fd = NATIVEOS(socket)(domain, type, protocol);
if (fd < 0)
return native_to_oskit_error(NATIVEOS(errno));
b = create_sockimpl(fd);
*aso = &b->ioi;
return 0;
}
/*
* function to create a pair of connected sockets - analog to socketpair(2)
*/
static OSKIT_COMDECL
socket_factory_create_pair(
oskit_socket_factory_t *factory,
oskit_u32_t domain,
oskit_u32_t type, oskit_u32_t protocol,
oskit_socket_t **aso1, oskit_socket_t **aso2)
{
oskit_sockimpl_t *b;
int fds[2];
if (NATIVEOS(socketpair)(domain, type, protocol, fds) < 0);
return native_to_oskit_error(NATIVEOS(errno));
b = create_sockimpl(fds[0]);
*aso1 = &b->ioi;
b = create_sockimpl(fds[1]);
*aso2 = &b->ioi;
return 0;
}
static struct oskit_socket_factory_ops sf_ops = {
socket_factory_query,
socket_factory_addref,
socket_factory_release,
socket_factory_create,
socket_factory_create_pair
};
static
struct oskit_socket_factory oskit_native_socket_factory = { &sf_ops };
oskit_error_t
oskit_native_net_init(oskit_socket_factory_t **f)
{
char hostname[256];
NATIVEOS(gethostname)(hostname, 256);
oskit_clientos_sethostname(hostname, 256);
*f = &oskit_native_socket_factory;
return 0;
}