more code fixes

This commit is contained in:
hyung-hwan 2019-01-28 08:13:06 +00:00
parent e21acce5c1
commit e9c42b28c6
16 changed files with 286 additions and 277 deletions

View File

@ -347,7 +347,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@ -578,7 +577,7 @@ distdir: $(DISTFILES)
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
$(am__post_remove_distdir)
dist-bzip2: distdir
@ -604,7 +603,7 @@ dist-shar: distdir
@echo WARNING: "Support for shar distribution archives is" \
"deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
$(am__post_remove_distdir)
dist-zip: distdir
@ -622,7 +621,7 @@ dist dist-all:
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lz*) \
@ -632,7 +631,7 @@ distcheck: dist
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac

14
mio/configure vendored
View File

@ -771,7 +771,6 @@ infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
@ -862,7 +861,6 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@ -1115,15 +1113,6 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@ -1261,7 +1250,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir runstatedir
libdir localedir mandir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@ -1414,7 +1403,6 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]

View File

@ -365,7 +365,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -517,16 +517,14 @@ static int put_errcs (mio_t* mio, mio_bitmask_t mask, const mio_ooch_t* ptr, mio
}
static mio_ooi_t __errbfmtv (mio_t* mio, mio_bitmask_t mask, const mio_bch_t* fmt, ...);
static int _errbfmtv (mio_t* mio, const mio_bch_t* fmt, mio_fmtout_data_t* data, va_list ap)
{
return __logbfmtv (mio, fmt, data, ap);
return __logbfmtv(mio, fmt, data, ap);
}
static int _errufmtv (mio_t* mio, const mio_uch_t* fmt, mio_fmtout_data_t* data, va_list ap)
{
return __logufmtv (mio, fmt, data, ap);
return __logufmtv(mio, fmt, data, ap);
}
void mio_seterrbfmt (mio_t* mio, mio_errnum_t errnum, const mio_bch_t* fmt, ...)
@ -651,8 +649,6 @@ static int put_sprch (mio_t* mio, mio_bitmask_t mask, mio_ooch_t ch, mio_oow_t l
return 1; /* success */
}
static mio_ooi_t __sprbfmtv (mio_t* mio, mio_bitmask_t mask, const mio_bch_t* fmt, ...);
static int _sprbfmtv (mio_t* mio, const mio_bch_t* fmt, mio_fmtout_data_t* data, va_list ap)
{
return __logbfmtv (mio, fmt, data, ap);

View File

@ -174,7 +174,10 @@ static void tcp_sck_on_connect (mio_dev_sck_t* tcp)
if (tcp->state & MIO_DEV_SCK_CONNECTED)
{
printf ("DEVICE connected to a remote server... LOCAL %s:%d REMOTE %s:%d.", buf1, mio_getsckaddrport(&tcp->localaddr), buf2, mio_getsckaddrport(&tcp->remoteaddr));
mio_logbfmt (tcp->mio, MIO_LOG_UNTYPED | MIO_LOG_INFO, "DEVICE connected to a remote server... LOCAL %hs:%d REMOTE %hs:%d.",
buf1, mio_getsckaddrport(&tcp->localaddr), buf2, mio_getsckaddrport(&tcp->remoteaddr));
printf ("DEVICE connected to a remote server... LOCAL %s:%d REMOTE %s:%d.",
buf1, mio_getsckaddrport(&tcp->localaddr), buf2, mio_getsckaddrport(&tcp->remoteaddr));
}
else if (tcp->state & MIO_DEV_SCK_ACCEPTED)
{

View File

@ -714,19 +714,19 @@ static int pro_ready_slave (mio_dev_t* dev, int events)
static int pro_on_read_slave_out (mio_dev_t* dev, const void* data, mio_iolen_t len, const mio_devaddr_t* srcaddr)
{
mio_dev_pro_slave_t* pro = (mio_dev_pro_slave_t*)dev;
return pro->master->on_read (pro->master, data, len, MIO_DEV_PRO_OUT);
return pro->master->on_read(pro->master, data, len, MIO_DEV_PRO_OUT);
}
static int pro_on_read_slave_err (mio_dev_t* dev, const void* data, mio_iolen_t len, const mio_devaddr_t* srcaddr)
{
mio_dev_pro_slave_t* pro = (mio_dev_pro_slave_t*)dev;
return pro->master->on_read (pro->master, data, len, MIO_DEV_PRO_ERR);
return pro->master->on_read(pro->master, data, len, MIO_DEV_PRO_ERR);
}
static int pro_on_write_slave (mio_dev_t* dev, mio_iolen_t wrlen, void* wrctx, const mio_devaddr_t* dstaddr)
{
mio_dev_pro_slave_t* pro = (mio_dev_pro_slave_t*)dev;
return pro->master->on_write (pro->master, wrlen, wrctx);
return pro->master->on_write(pro->master, wrlen, wrctx);
}
static mio_dev_evcb_t dev_pro_event_callbacks_slave_in =
@ -772,7 +772,7 @@ static mio_dev_pro_slave_t* make_slave (mio_t* mio, slave_info_t* si)
&dev_pro_methods_slave, &dev_pro_event_callbacks_slave_err, si);
default:
mio->errnum = MIO_EINVAL;
mio_seterrnum (mio, MIO_EINVAL);
return MIO_NULL;
}
}
@ -797,7 +797,7 @@ int mio_dev_pro_write (mio_dev_pro_t* dev, const void* data, mio_iolen_t dlen, v
}
else
{
dev->mio->errnum = MIO_ENOCAPA; /* TODO: is it the right error number? */
mio_seterrnum (dev->mio, MIO_ENOCAPA); /* TODO: is it the right error number? */
return -1;
}
}
@ -810,19 +810,19 @@ int mio_dev_pro_timedwrite (mio_dev_pro_t* dev, const void* data, mio_iolen_t dl
}
else
{
dev->mio->errnum = MIO_ENOCAPA; /* TODO: is it the right error number? */
mio_seterrnum (dev->mio, MIO_ENOCAPA); /* TODO: is it the right error number? */
return -1;
}
}
int mio_dev_pro_close (mio_dev_pro_t* dev, mio_dev_pro_sid_t sid)
{
return mio_dev_ioctl ((mio_dev_t*)dev, MIO_DEV_PRO_CLOSE, &sid);
return mio_dev_ioctl((mio_dev_t*)dev, MIO_DEV_PRO_CLOSE, &sid);
}
int mio_dev_pro_killchild (mio_dev_pro_t* dev)
{
return mio_dev_ioctl ((mio_dev_t*)dev, MIO_DEV_PRO_KILL_CHILD, MIO_NULL);
return mio_dev_ioctl((mio_dev_t*)dev, MIO_DEV_PRO_KILL_CHILD, MIO_NULL);
}
#if 0

View File

@ -47,7 +47,7 @@
#if defined(MIO_BUILD_RELEASE)
# define MIO_ASSERT(mio,expr) ((void)0)
#else
# define MIO_ASSERT(mio,expr) ((void)((expr) || mio_sys_assertfail(mio, #expr, __FILE__, __LINE__), 0)))
# define MIO_ASSERT(mio,expr) ((void)((expr) || (mio_sys_assertfail(mio, #expr, __FILE__, __LINE__), 0)))
#endif
@ -152,7 +152,7 @@ mio_errnum_t mio_sys_syserrstrb (
void mio_sys_initlog (
int mio_sys_initlog (
mio_t* mio
);

View File

@ -164,7 +164,7 @@ int mio_getsckaddrinfo (mio_t* mio, const mio_sckaddr_t* addr, mio_scklen_t* len
/* TODO: more address type */
}
mio->errnum = MIO_EINVAL;
mio_seterrnum (mio, MIO_EINVAL);
return -1;
}
@ -272,7 +272,6 @@ static mio_devaddr_t* sckaddr_to_devaddr (mio_dev_sck_t* dev, const mio_sckaddr_
if (sckaddr)
{
mio_scklen_t len;
mio_getsckaddrinfo (dev->mio, sckaddr, &len, MIO_NULL);
devaddr->ptr = (void*)sckaddr;
devaddr->len = len;
@ -411,21 +410,30 @@ static int schedule_timer_job_after (mio_dev_sck_t* dev, const mio_ntime_t* fire
}
/* ======================================================================== */
#if defined(USE_SSL)
static void set_ssl_error (mio_t* mio, int sslerr)
{
mio_bch_t emsg[128];
ERR_error_string_n (sslerr, emsg, MIO_COUNTOF(emsg));
mio_seterrbfmt (mio, MIO_ESYSERR, "%hs", emsg);
}
#endif
static int dev_sck_make (mio_dev_t* dev, void* ctx)
{
mio_t* mio = dev->mio;
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
mio_dev_sck_make_t* arg = (mio_dev_sck_make_t*)ctx;
MIO_ASSERT (dev->mio, arg->type >= 0 && arg->type < MIO_COUNTOF(sck_type_map));
MIO_ASSERT (mio, arg->type >= 0 && arg->type < MIO_COUNTOF(sck_type_map));
if (sck_type_map[arg->type].domain <= -1)
{
dev->mio->errnum = MIO_ENOIMPL;
mio_seterrnum (mio, MIO_ENOIMPL); /* TODO: better error info? */
return -1;
}
rdev->sck = open_async_socket(dev->mio, sck_type_map[arg->type].domain, sck_type_map[arg->type].type, sck_type_map[arg->type].proto);
rdev->sck = open_async_socket(mio, sck_type_map[arg->type].domain, sck_type_map[arg->type].type, sck_type_map[arg->type].proto);
if (rdev->sck == MIO_SCKHND_INVALID) goto oops;
rdev->dev_capa = MIO_DEV_CAPA_IN | MIO_DEV_CAPA_OUT | sck_type_map[arg->type].extra_dev_capa;
@ -441,7 +449,7 @@ static int dev_sck_make (mio_dev_t* dev, void* ctx)
oops:
if (rdev->sck != MIO_SCKHND_INVALID)
{
close_async_socket (rdev->mio, rdev->sck);
close_async_socket (mio, rdev->sck);
rdev->sck = MIO_SCKHND_INVALID;
}
return -1;
@ -449,6 +457,7 @@ oops:
static int dev_sck_make_client (mio_dev_t* dev, void* ctx)
{
mio_t* mio = dev->mio;
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
mio_syshnd_t* sck = (mio_syshnd_t*)ctx;
@ -461,13 +470,13 @@ static int dev_sck_make_client (mio_dev_t* dev, void* ctx)
rdev->sck = *sck;
rdev->tmrjob_index = MIO_TMRIDX_INVALID;
if (mio_makesckasync(rdev->mio, rdev->sck) <= -1) return -1;
if (mio_makesckasync(mio, rdev->sck) <= -1) return -1;
#if defined(FD_CLOEXEC)
{
int flags = fcntl(rdev->sck, F_GETFD, 0);
if (fcntl(rdev->sck, F_SETFD, flags | FD_CLOEXEC) == -1)
{
mio_seterrwithsyserr (rdev->mio, 0, errno);
mio_seterrbfmtwithsyserr (mio, 0, errno, "unable to set FD_CLOEXEC");
return -1;
}
}
@ -478,6 +487,7 @@ static int dev_sck_make_client (mio_dev_t* dev, void* ctx)
static int dev_sck_kill (mio_dev_t* dev, int force)
{
mio_t* mio = dev->mio;
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
if (IS_STATEFUL(rdev))
@ -491,14 +501,14 @@ static int dev_sck_kill (mio_dev_t* dev, int force)
if (rdev->tmrjob_index != MIO_TMRIDX_INVALID)
{
mio_deltmrjob (dev->mio, rdev->tmrjob_index);
MIO_ASSERT (dev->mio, rdev->tmrjob_index == MIO_TMRIDX_INVALID);
mio_deltmrjob (mio, rdev->tmrjob_index);
MIO_ASSERT (mio, rdev->tmrjob_index == MIO_TMRIDX_INVALID);
}
}
else
{
MIO_ASSERT (dev->mio, rdev->state == 0);
MIO_ASSERT (dev->mio, rdev->tmrjob_index == MIO_TMRIDX_INVALID);
MIO_ASSERT (mio, rdev->state == 0);
MIO_ASSERT (mio, rdev->tmrjob_index == MIO_TMRIDX_INVALID);
if (rdev->on_disconnect) rdev->on_disconnect (rdev);
}
@ -519,7 +529,7 @@ static int dev_sck_kill (mio_dev_t* dev, int force)
if (rdev->sck != MIO_SCKHND_INVALID)
{
close_async_socket (rdev->mio, rdev->sck);
close_async_socket (mio, rdev->sck);
rdev->sck = MIO_SCKHND_INVALID;
}
@ -534,6 +544,7 @@ static mio_syshnd_t dev_sck_getsyshnd (mio_dev_t* dev)
static int dev_sck_read_stateful (mio_dev_t* dev, void* buf, mio_iolen_t* len, mio_devaddr_t* srcaddr)
{
mio_t* mio = dev->mio;
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
#if defined(USE_SSL)
@ -541,12 +552,12 @@ static int dev_sck_read_stateful (mio_dev_t* dev, void* buf, mio_iolen_t* len, m
{
int x;
x = SSL_read ((SSL*)rdev->ssl, buf, *len);
x = SSL_read((SSL*)rdev->ssl, buf, *len);
if (x <= -1)
{
int err = SSL_get_error((SSL*)rdev->ssl, x);
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) return 0;
rdev->mio->errnum = MIO_ESYSERR;
set_ssl_error (mio, err);
return -1;
}
@ -557,12 +568,12 @@ static int dev_sck_read_stateful (mio_dev_t* dev, void* buf, mio_iolen_t* len, m
#endif
ssize_t x;
x = recv (rdev->sck, buf, *len, 0);
x = recv(rdev->sck, buf, *len, 0);
if (x == -1)
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data available */
if (errno == EINTR) return 0;
mio_seterrwithsyserr (rdev->mio, 0, errno);
mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -575,6 +586,7 @@ static int dev_sck_read_stateful (mio_dev_t* dev, void* buf, mio_iolen_t* len, m
static int dev_sck_read_stateless (mio_dev_t* dev, void* buf, mio_iolen_t* len, mio_devaddr_t* srcaddr)
{
mio_t* mio = dev->mio;
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
mio_scklen_t srcaddrlen;
ssize_t x;
@ -585,7 +597,7 @@ static int dev_sck_read_stateless (mio_dev_t* dev, void* buf, mio_iolen_t* len,
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data available */
if (errno == EINTR) return 0;
mio_seterrwithsyserr (rdev->mio, 0, errno);
mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -599,6 +611,7 @@ static int dev_sck_read_stateless (mio_dev_t* dev, void* buf, mio_iolen_t* len,
static int dev_sck_write_stateful (mio_dev_t* dev, const void* data, mio_iolen_t* len, const mio_devaddr_t* dstaddr)
{
mio_t* mio = dev->mio;
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
#if defined(USE_SSL)
@ -610,21 +623,20 @@ static int dev_sck_write_stateful (mio_dev_t* dev, const void* data, mio_iolen_t
{
/* it's a writing finish indicator. close the writing end of
* the socket, probably leaving it in the half-closed state */
if (SSL_shutdown ((SSL*)rdev->ssl) == -1)
if ((x = SSL_shutdown((SSL*)rdev->ssl)) == -1)
{
rdev->mio->errnum = MIO_ESYSERR;
set_ssl_error (mio, SSL_get_error((SSL*)rdev->ssl, x));
return -1;
}
return 1;
}
x = SSL_write ((SSL*)rdev->ssl, data, *len);
x = SSL_write((SSL*)rdev->ssl, data, *len);
if (x <= -1)
{
int err = SSL_get_error ((SSL*)rdev->ssl, x);
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) return 0;
rdev->mio->errnum = MIO_ESYSERR;
set_ssl_error (mio, err);
return -1;
}
@ -642,7 +654,7 @@ static int dev_sck_write_stateful (mio_dev_t* dev, const void* data, mio_iolen_t
* the socket, probably leaving it in the half-closed state */
if (shutdown(rdev->sck, SHUT_WR) == -1)
{
mio_seterrwithsyserr (rdev->mio, 0, errno);
mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -658,7 +670,7 @@ static int dev_sck_write_stateful (mio_dev_t* dev, const void* data, mio_iolen_t
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */
if (errno == EINTR) return 0;
mio_seterrwithsyserr (rdev->mio, 0, errno);
mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -671,6 +683,7 @@ static int dev_sck_write_stateful (mio_dev_t* dev, const void* data, mio_iolen_t
static int dev_sck_write_stateless (mio_dev_t* dev, const void* data, mio_iolen_t* len, const mio_devaddr_t* dstaddr)
{
mio_t* mio = dev->mio;
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
ssize_t x;
@ -679,7 +692,7 @@ static int dev_sck_write_stateless (mio_dev_t* dev, const void* data, mio_iolen_
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */
if (errno == EINTR) return 0;
mio_seterrwithsyserr (rdev->mio, 0, errno);
mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -691,26 +704,25 @@ static int dev_sck_write_stateless (mio_dev_t* dev, const void* data, mio_iolen_
static int do_ssl (mio_dev_sck_t* dev, int (*ssl_func)(SSL*))
{
int ret;
int watcher_cmd;
int watcher_events;
mio_t* mio = dev->mio;
int ret, watcher_cmd, watcher_events;
MIO_ASSERT (dev->ssl_ctx);
MIO_ASSERT (mio, dev->ssl_ctx);
if (!dev->ssl)
{
SSL* ssl;
ssl = SSL_new (dev->ssl_ctx);
ssl = SSL_new(dev->ssl_ctx);
if (!ssl)
{
dev->mio->errnum = MIO_ESYSERR;
set_ssl_error (mio, ERR_get_error());
return -1;
}
if (SSL_set_fd (ssl, dev->sck) == 0)
if (SSL_set_fd(ssl, dev->sck) == 0)
{
dev->mio->errnum = MIO_ESYSERR;
set_ssl_error (mio, ERR_get_error());
return -1;
}
@ -722,10 +734,10 @@ static int do_ssl (mio_dev_sck_t* dev, int (*ssl_func)(SSL*))
watcher_cmd = MIO_DEV_WATCH_RENEW;
watcher_events = 0;
ret = ssl_func ((SSL*)dev->ssl);
ret = ssl_func((SSL*)dev->ssl);
if (ret <= 0)
{
int err = SSL_get_error (dev->ssl, ret);
int err = SSL_get_error(dev->ssl, ret);
if (err == SSL_ERROR_WANT_READ)
{
/* handshaking isn't complete */
@ -740,7 +752,7 @@ static int do_ssl (mio_dev_sck_t* dev, int (*ssl_func)(SSL*))
}
else
{
dev->mio->errnum = MIO_ESYSERR;
set_ssl_error (mio, err);
ret = -1;
}
}
@ -751,7 +763,7 @@ static int do_ssl (mio_dev_sck_t* dev, int (*ssl_func)(SSL*))
if (mio_dev_watch ((mio_dev_t*)dev, watcher_cmd, watcher_events) <= -1)
{
mio_stop (dev->mio, MIO_STOPREQ_WATCHER_ERROR);
mio_stop (mio, MIO_STOPREQ_WATCHER_ERROR);
ret = -1;
}
@ -771,8 +783,8 @@ static MIO_INLINE int accept_ssl (mio_dev_sck_t* dev)
static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
{
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
mio_t* mio = dev->mio;
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
switch (cmd)
{
@ -789,16 +801,16 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
if (MIO_DEV_SCK_GET_PROGRESS(rdev))
{
/* can't bind again */
rdev->mio->errnum = MIO_EPERM;
mio_seterrbfmt (mio, MIO_EPERM, "operation in progress. not allowed to bind again");
return -1;
}
if (bnd->options & MIO_DEV_SCK_BIND_BROADCAST)
{
int v = 1;
if (setsockopt (rdev->sck, SOL_SOCKET, SO_BROADCAST, &v, MIO_SIZEOF(v)) == -1)
if (setsockopt(rdev->sck, SOL_SOCKET, SO_BROADCAST, &v, MIO_SIZEOF(v)) == -1)
{
mio_seterrwithsyserr (rdev->mio, 0, errno);
mio_seterrbfmtwithsyserr (mio, 0, errno, "unable to set SO_BROADCAST");
return -1;
}
}
@ -807,13 +819,13 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
{
#if defined(SO_REUSEADDR)
int v = 1;
if (setsockopt (rdev->sck, SOL_SOCKET, SO_REUSEADDR, &v, MIO_SIZEOF(v)) == -1)
if (setsockopt(rdev->sck, SOL_SOCKET, SO_REUSEADDR, &v, MIO_SIZEOF(v)) == -1)
{
mio_seterrwithsyserr (rdev->mio, 0, errno);
mio_seterrbfmtwithsyserr (mio, 0, errno, "unable to set SO_REUSEADDR");
return -1;
}
#else
rdev->mio->errnum = MIO_ENOIMPL;
mio_seterrnum (mio, MIO_ENOIMPL);
return -1;
#endif
}
@ -822,13 +834,13 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
{
#if defined(SO_REUSEPORT)
int v = 1;
if (setsockopt (rdev->sck, SOL_SOCKET, SO_REUSEPORT, &v, MIO_SIZEOF(v)) == -1)
if (setsockopt(rdev->sck, SOL_SOCKET, SO_REUSEPORT, &v, MIO_SIZEOF(v)) == -1)
{
mio_seterrwithsyserr (rdev->mio, 0, errno);
mio_seterrbfmtwithsyserr (mio, 0, errno, "unable to set SO_REUSEPORT");
return -1;
}
#else
rdev->mio->errnum = MIO_ENOIMPL;
mio_seterrnum (mio, MIO_ENOIMPL);
return -1;
#endif
}
@ -839,11 +851,11 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
int v = 1;
if (setsockopt(rdev->sck, SOL_IP, IP_TRANSPARENT, &v, MIO_SIZEOF(v)) == -1)
{
mio_seterrwithsyserr (rdev->mio, 0, errno);
mio_seterrbfmtwithsyserr (mio, 0, errno, "unable to set IP_TRANSPARENT");
return -1;
}
#else
rdev->mio->errnum = MIO_ENOIMPL;
mio_seterrnum (mio, MIO_ENOIMPL);
return -1;
#endif
}
@ -869,14 +881,14 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
#if defined(USE_SSL)
if (!bnd->ssl_certfile || !bnd->ssl_keyfile)
{
rdev->mio->errnum = MIO_EINVAL;
mio_seterrbfmt (mio, MIO_EINVAL, "SSL certficate/key file not set");
return -1;
}
ssl_ctx = SSL_CTX_new(SSLv23_server_method());
if (!ssl_ctx)
{
rdev->mio->errnum = MIO_ESYSERR;
set_ssl_error (mio, ERR_get_error());
return -1;
}
@ -885,8 +897,8 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
SSL_CTX_check_private_key(ssl_ctx) == 0 /*||
SSL_CTX_use_certificate_chain_file (ssl_ctx, bnd->chainfile) == 0*/)
{
set_ssl_error (mio, ERR_get_error());
SSL_CTX_free (ssl_ctx);
rdev->mio->errnum = MIO_ESYSERR;
return -1;
}
@ -899,17 +911,23 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
rdev->tmout = bnd->accept_tmout;
#else
rdev->mio->errnum = MIO_ENOIMPL;
mio_seterrnum (mio, MIO_ENOIMPL);
return -1;
#endif
}
if (mio_getsckaddrinfo(dev->mio, &bnd->localaddr, &sl, &fam) <= -1) return -1;
if (mio_getsckaddrinfo(mio, &bnd->localaddr, &sl, &fam) <= -1)
{
#if defined(USE_SSL)
if (ssl_ctx) SSL_CTX_free (ssl_ctx);
#endif
return -1;
}
x = bind(rdev->sck, sa, sl);
if (x == -1)
{
mio_seterrwithsyserr (rdev->mio, 0, errno);
mio_seterrwithsyserr (mio, 0, errno);
#if defined(USE_SSL)
if (ssl_ctx) SSL_CTX_free (ssl_ctx);
#endif
@ -939,13 +957,13 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
if (MIO_DEV_SCK_GET_PROGRESS(rdev))
{
/* can't connect again */
rdev->mio->errnum = MIO_EPERM;
mio_seterrbfmt (mio, MIO_EPERM, "operation in progress. disallowed to connect again");
return -1;
}
if (!IS_STATEFUL(rdev))
{
dev->mio->errnum = MIO_ENOCAPA;
mio_seterrbfmt (mio, MIO_EPERM, "disallowed to connect stateless device");
return -1;
}
@ -953,7 +971,7 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
else if (sa->sa_family == AF_INET6) sl = MIO_SIZEOF(struct sockaddr_in6);
else
{
dev->mio->errnum = MIO_EINVAL;
mio_seterrbfmt (mio, MIO_EINVAL, "unknown address family %d", sa->sa_family);
return -1;
}
@ -975,7 +993,7 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
ssl_ctx = SSL_CTX_new(SSLv23_client_method());
if (!ssl_ctx)
{
rdev->mio->errnum = MIO_ESYSERR;
set_ssl_error (mio, ERR_get_error());
return -1;
}
@ -1003,7 +1021,7 @@ fcntl (rdev->sck, F_SETFL, flags | O_NONBLOCK);
if (mio_dev_watch((mio_dev_t*)rdev, MIO_DEV_WATCH_UPDATE, MIO_DEV_EVENT_IN | MIO_DEV_EVENT_OUT) <= -1)
{
/* watcher update failure. it's critical */
mio_stop (rdev->mio, MIO_STOPREQ_WATCHER_ERROR);
mio_stop (mio, MIO_STOPREQ_WATCHER_ERROR);
goto oops_connect;
}
else
@ -1020,7 +1038,7 @@ fcntl (rdev->sck, F_SETFL, flags | O_NONBLOCK);
{
/* update rdev->tmout to the deadline of the connect timeout job */
MIO_ASSERT (mio, rdev->tmrjob_index != MIO_TMRIDX_INVALID);
mio_gettmrjobdeadline (rdev->mio, rdev->tmrjob_index, &rdev->tmout);
mio_gettmrjobdeadline (mio, rdev->tmrjob_index, &rdev->tmout);
}
}
@ -1033,13 +1051,13 @@ fcntl (rdev->sck, F_SETFL, flags | O_NONBLOCK);
}
}
mio_seterrwithsyserr (rdev->mio, 0, errno);
mio_seterrwithsyserr (mio, 0, errno);
oops_connect:
if (mio_dev_watch((mio_dev_t*)rdev, MIO_DEV_WATCH_UPDATE, MIO_DEV_EVENT_IN) <= -1)
{
/* watcher update failure. it's critical */
mio_stop (rdev->mio, MIO_STOPREQ_WATCHER_ERROR);
mio_stop (mio, MIO_STOPREQ_WATCHER_ERROR);
}
#if defined(USE_SSL)
@ -1067,12 +1085,12 @@ fcntl (rdev->sck, F_SETFL, flags | O_NONBLOCK);
SSL_CTX_free (rdev->ssl_ctx);
rdev->ssl_ctx = MIO_NULL;
MIO_ASSERT (rdev->ssl == MIO_NULL);
MIO_ASSERT (mio, rdev->ssl == MIO_NULL);
return -1;
}
if (x == 0)
{
MIO_ASSERT (rdev->tmrjob_index == MIO_TMRIDX_INVALID);
MIO_ASSERT (mio, rdev->tmrjob_index == MIO_TMRIDX_INVALID);
MIO_INIT_NTIME (&rdev->tmout, 0, 0); /* just in case */
/* it's ok to use conn->connect_tmout for ssl-connect as
@ -1087,14 +1105,14 @@ fcntl (rdev->sck, F_SETFL, flags | O_NONBLOCK);
SSL_CTX_free (rdev->ssl_ctx);
rdev->ssl_ctx = MIO_NULL;
MIO_ASSERT (rdev->ssl == MIO_NULL);
MIO_ASSERT (mio, rdev->ssl == MIO_NULL);
return -1;
}
else
{
/* update rdev->tmout to the deadline of the connect timeout job */
MIO_ASSERT (rdev->tmrjob_index != MIO_TMRIDX_INVALID);
mio_gettmrjobdeadline (rdev->mio, rdev->tmrjob_index, &rdev->tmout);
MIO_ASSERT (mio, rdev->tmrjob_index != MIO_TMRIDX_INVALID);
mio_gettmrjobdeadline (mio, rdev->tmrjob_index, &rdev->tmout);
}
}
@ -1126,20 +1144,20 @@ fcntl (rdev->sck, F_SETFL, flags | O_NONBLOCK);
if (MIO_DEV_SCK_GET_PROGRESS(rdev))
{
/* can't listen again */
rdev->mio->errnum = MIO_EPERM;
mio_seterrbfmt (mio, MIO_EPERM, "operation in progress. disallowed to listen again");
return -1;
}
if (!IS_STATEFUL(rdev))
{
dev->mio->errnum = MIO_ENOCAPA;
mio_seterrbfmt (mio, MIO_EPERM, "disallowed to listen on stateless device");
return -1;
}
x = listen (rdev->sck, lstn->backlogs);
if (x == -1)
{
mio_seterrwithsyserr (rdev->mio, 0, errno);
mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -1188,15 +1206,17 @@ static mio_dev_mth_t dev_mth_clisck =
static int harvest_outgoing_connection (mio_dev_sck_t* rdev)
{
mio_t* mio = rdev->mio;
int errcode;
mio_scklen_t len;
MIO_ASSERT (rdev->mio, !(rdev->state & MIO_DEV_SCK_CONNECTED));
MIO_ASSERT (mio, !(rdev->state & MIO_DEV_SCK_CONNECTED));
len = MIO_SIZEOF(errcode);
if (getsockopt(rdev->sck, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len) == -1)
{
mio_seterrwithsyserr (rdev->mio, 0, errno);
mio_seterrbfmtwithsyserr (mio, 0, errno, "unable to get SO_ERROR");
return -1;
}
else if (errcode == 0)
@ -1208,8 +1228,8 @@ static int harvest_outgoing_connection (mio_dev_sck_t* rdev)
if (rdev->tmrjob_index != MIO_TMRIDX_INVALID)
{
mio_deltmrjob (rdev->mio, rdev->tmrjob_index);
MIO_ASSERT (rdev->mio, rdev->tmrjob_index == MIO_TMRIDX_INVALID);
mio_deltmrjob (mio, rdev->tmrjob_index);
MIO_ASSERT (mio, rdev->tmrjob_index == MIO_TMRIDX_INVALID);
}
addrlen = MIO_SIZEOF(localaddr);
@ -1218,7 +1238,7 @@ static int harvest_outgoing_connection (mio_dev_sck_t* rdev)
if (mio_dev_watch((mio_dev_t*)rdev, MIO_DEV_WATCH_RENEW, 0) <= -1)
{
/* watcher update failure. it's critical */
mio_stop (rdev->mio, MIO_STOPREQ_WATCHER_ERROR);
mio_stop (mio, MIO_STOPREQ_WATCHER_ERROR);
return -1;
}
@ -1226,7 +1246,7 @@ static int harvest_outgoing_connection (mio_dev_sck_t* rdev)
if (rdev->ssl_ctx)
{
int x;
MIO_ASSERT (!rdev->ssl); /* must not be SSL-connected yet */
MIO_ASSERT (mio, !rdev->ssl); /* must not be SSL-connected yet */
x = connect_ssl (rdev);
if (x <= -1) return -1;
@ -1235,7 +1255,7 @@ static int harvest_outgoing_connection (mio_dev_sck_t* rdev)
/* underlying socket connected but not SSL-connected */
MIO_DEV_SCK_SET_PROGRESS (rdev, MIO_DEV_SCK_CONNECTING_SSL);
MIO_ASSERT (rdev->tmrjob_index == MIO_TMRIDX_INVALID);
MIO_ASSERT (mio, rdev->tmrjob_index == MIO_TMRIDX_INVALID);
/* rdev->tmout has been set to the deadline of the connect task
* when the CONNECT IOCTL command has been executed. use the
@ -1272,7 +1292,7 @@ static int harvest_outgoing_connection (mio_dev_sck_t* rdev)
}
else
{
mio_seterrwithsyserr (rdev->mio, 0, errcode);
mio_seterrwithsyserr (mio, 0, errcode);
return -1;
}
}
@ -1300,7 +1320,7 @@ static int accept_incoming_connection (mio_dev_sck_t* rdev)
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0;
if (errno == EINTR) return 0; /* if interrupted by a signal, treat it as if it's EINPROGRESS */
mio_seterrwithsyserr (rdev->mio, 0, errno);
mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -1319,7 +1339,7 @@ static int accept_incoming_connection (mio_dev_sck_t* rdev)
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0;
if (errno == EINTR) return 0; /* if interrupted by a signal, treat it as if it's EINPROGRESS */
mio_seterrwithsyserr (rdev->mio, 0, errno);
mio_seterrwithsyserr (mio, 0, errno);
return -1;
}
@ -1329,7 +1349,7 @@ accept_done:
* instead of MIO_SIZEOF(mio_dev_sck_t). therefore, the
* extension area as big as that of the master sck device
* is created in the client sck device */
clidev = (mio_dev_sck_t*)mio_makedev(rdev->mio, rdev->dev_size, &dev_mth_clisck, rdev->dev_evcb, &clisck);
clidev = (mio_dev_sck_t*)mio_makedev(mio, rdev->dev_size, &dev_mth_clisck, rdev->dev_evcb, &clisck);
if (!clidev)
{
close (clisck);
@ -1350,12 +1370,12 @@ accept_done:
* the address of the local socket. In this case, it should
* be same as the result of getsockname(). */
addrlen = MIO_SIZEOF(clidev->orgdstaddr);
if (getsockopt (clisck, SOL_IP, SO_ORIGINAL_DST, &clidev->orgdstaddr, &addrlen) == -1) clidev->orgdstaddr = rdev->localaddr;
if (getsockopt(clisck, SOL_IP, SO_ORIGINAL_DST, &clidev->orgdstaddr, &addrlen) == -1) clidev->orgdstaddr = rdev->localaddr;
#else
clidev->orgdstaddr = rdev->localaddr;
#endif
if (!mio_equalsckaddrs (rdev->mio, &clidev->orgdstaddr, &clidev->localaddr))
if (!mio_equalsckaddrs (mio, &clidev->orgdstaddr, &clidev->localaddr))
{
clidev->state |= MIO_DEV_SCK_INTERCEPTED;
}
@ -1419,6 +1439,7 @@ accept_done:
static int dev_evcb_sck_ready_stateful (mio_dev_t* dev, int events)
{
mio_t* mio = dev->mio;
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
if (events & MIO_DEV_EVENT_ERR)
@ -1427,17 +1448,17 @@ static int dev_evcb_sck_ready_stateful (mio_dev_t* dev, int events)
mio_scklen_t len;
len = MIO_SIZEOF(errcode);
if (getsockopt (rdev->sck, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len) == -1)
if (getsockopt(rdev->sck, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len) == -1)
{
/* the error number is set to the socket error code.
* errno resulting from getsockopt() doesn't reflect the actual
* socket error. so errno is not used to set the error number.
* instead, the generic device error MIO_EDEVERRR is used */
rdev->mio->errnum = MIO_EDEVERR;
mio_seterrbfmt (mio, MIO_EDEVERR, "device error - unable to get SO_ERROR");
}
else
{
mio_seterrwithsyserr (rdev->mio, 0, errcode);
mio_seterrwithsyserr (mio, 0, errcode);
}
return -1;
}
@ -1449,19 +1470,19 @@ static int dev_evcb_sck_ready_stateful (mio_dev_t* dev, int events)
if (events & MIO_DEV_EVENT_HUP)
{
/* device hang-up */
rdev->mio->errnum = MIO_EDEVHUP;
mio_seterrnum (mio, MIO_EDEVHUP);
return -1;
}
else if (events & (MIO_DEV_EVENT_PRI | MIO_DEV_EVENT_IN))
{
/* invalid event masks. generic device error */
rdev->mio->errnum = MIO_EDEVERR;
mio_seterrbfmt (mio, MIO_EDEVERR, "device error - invalid event mask");
return -1;
}
else if (events & MIO_DEV_EVENT_OUT)
{
/* when connected, the socket becomes writable */
return harvest_outgoing_connection (rdev);
return harvest_outgoing_connection(rdev);
}
else
{
@ -1473,20 +1494,20 @@ static int dev_evcb_sck_ready_stateful (mio_dev_t* dev, int events)
if (events & MIO_DEV_EVENT_HUP)
{
/* device hang-up */
rdev->mio->errnum = MIO_EDEVHUP;
mio_seterrnum (mio, MIO_EDEVHUP);
return -1;
}
else if (events & MIO_DEV_EVENT_PRI)
{
/* invalid event masks. generic device error */
rdev->mio->errnum = MIO_EDEVERR;
mio_seterrbfmt (mio, MIO_EDEVERR, "device error - invalid event mask");
return -1;
}
else if (events & (MIO_DEV_EVENT_IN | MIO_DEV_EVENT_OUT))
{
int x;
x = connect_ssl (rdev);
x = connect_ssl(rdev);
if (x <= -1) return -1;
if (x == 0) return 0; /* not SSL-Connected */
@ -1505,7 +1526,7 @@ static int dev_evcb_sck_ready_stateful (mio_dev_t* dev, int events)
return 0; /* success. no actual I/O yet */
}
#else
rdev->mio->errnum = MIO_EINTERN;
mio_seterrnum (mio, MIO_EINTERN);
return -1;
#endif
@ -1514,12 +1535,12 @@ static int dev_evcb_sck_ready_stateful (mio_dev_t* dev, int events)
if (events & MIO_DEV_EVENT_HUP)
{
/* device hang-up */
rdev->mio->errnum = MIO_EDEVHUP;
mio_seterrnum (mio, MIO_EDEVHUP);
return -1;
}
else if (events & (MIO_DEV_EVENT_PRI | MIO_DEV_EVENT_OUT))
{
rdev->mio->errnum = MIO_EDEVERR;
mio_seterrbfmt (mio, MIO_EDEVERR, "device error - invalid event mask");
return -1;
}
else if (events & MIO_DEV_EVENT_IN)
@ -1536,19 +1557,19 @@ static int dev_evcb_sck_ready_stateful (mio_dev_t* dev, int events)
if (events & MIO_DEV_EVENT_HUP)
{
/* device hang-up */
rdev->mio->errnum = MIO_EDEVHUP;
mio_seterrnum (mio, MIO_EDEVHUP);
return -1;
}
else if (events & MIO_DEV_EVENT_PRI)
{
/* invalid event masks. generic device error */
rdev->mio->errnum = MIO_EDEVERR;
mio_seterrbfmt (mio, MIO_EDEVERR, "device error - invalid event mask");
return -1;
}
else if (events & (MIO_DEV_EVENT_IN | MIO_DEV_EVENT_OUT))
{
int x;
x = accept_ssl (rdev);
x = accept_ssl(rdev);
if (x <= -1) return -1;
if (x <= 0) return 0; /* not SSL-accepted yet */
@ -1569,7 +1590,7 @@ static int dev_evcb_sck_ready_stateful (mio_dev_t* dev, int events)
return 0; /* no reading or writing yet */
}
#else
rdev->mio->errnum = MIO_EINTERN;
mio_seterrnum (mio, MIO_EINTERN);
return -1;
#endif
@ -1583,7 +1604,7 @@ static int dev_evcb_sck_ready_stateful (mio_dev_t* dev, int events)
return 1;
}
rdev->mio->errnum = MIO_EDEVHUP;
mio_seterrnum (mio, MIO_EDEVHUP);
return -1;
}
@ -1593,6 +1614,7 @@ static int dev_evcb_sck_ready_stateful (mio_dev_t* dev, int events)
static int dev_evcb_sck_ready_stateless (mio_dev_t* dev, int events)
{
mio_t* mio = dev->mio;
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
if (events & MIO_DEV_EVENT_ERR)
@ -1607,7 +1629,7 @@ static int dev_evcb_sck_ready_stateless (mio_dev_t* dev, int events)
* errno resulting from getsockopt() doesn't reflect the actual
* socket error. so errno is not used to set the error number.
* instead, the generic device error MIO_EDEVERRR is used */
rdev->mio->errnum = MIO_EDEVERR;
mio_seterrbfmt (mio, MIO_EDEVERR, "device error - unable to get SO_ERROR");
}
else
{
@ -1617,7 +1639,7 @@ static int dev_evcb_sck_ready_stateless (mio_dev_t* dev, int events)
}
else if (events & MIO_DEV_EVENT_HUP)
{
rdev->mio->errnum = MIO_EDEVHUP;
mio_seterrnum (mio, MIO_EDEVHUP);
return -1;
}
@ -1627,25 +1649,25 @@ static int dev_evcb_sck_ready_stateless (mio_dev_t* dev, int events)
static int dev_evcb_sck_on_read_stateful (mio_dev_t* dev, const void* data, mio_iolen_t dlen, const mio_devaddr_t* srcaddr)
{
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
return rdev->on_read (rdev, data, dlen, MIO_NULL);
return rdev->on_read(rdev, data, dlen, MIO_NULL);
}
static int dev_evcb_sck_on_write_stateful (mio_dev_t* dev, mio_iolen_t wrlen, void* wrctx, const mio_devaddr_t* dstaddr)
{
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
return rdev->on_write (rdev, wrlen, wrctx, MIO_NULL);
return rdev->on_write(rdev, wrlen, wrctx, MIO_NULL);
}
static int dev_evcb_sck_on_read_stateless (mio_dev_t* dev, const void* data, mio_iolen_t dlen, const mio_devaddr_t* srcaddr)
{
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
return rdev->on_read (rdev, data, dlen, srcaddr->ptr);
return rdev->on_read(rdev, data, dlen, srcaddr->ptr);
}
static int dev_evcb_sck_on_write_stateless (mio_dev_t* dev, mio_iolen_t wrlen, void* wrctx, const mio_devaddr_t* dstaddr)
{
mio_dev_sck_t* rdev = (mio_dev_sck_t*)dev;
return rdev->on_write (rdev, wrlen, wrctx, dstaddr->ptr);
return rdev->on_write(rdev, wrlen, wrctx, dstaddr->ptr);
}
static mio_dev_evcb_t dev_sck_event_callbacks_stateful =
@ -1670,7 +1692,7 @@ mio_dev_sck_t* mio_dev_sck_make (mio_t* mio, mio_oow_t xtnsize, const mio_dev_sc
if (info->type < 0 && info->type >= MIO_COUNTOF(sck_type_map))
{
mio->errnum = MIO_EINVAL;
mio_seterrnum (mio, MIO_EINVAL);
return MIO_NULL;
}

View File

@ -105,12 +105,12 @@ int mio_init (mio_t* mio, mio_mmgr_t* mmgr, mio_cmgr_t* cmgr, mio_oow_t tmrcapa)
if (!mio->log.ptr) goto oops;
/* inititalize the system-side logging */
mio_sys_initlog (mio);
if (mio_sys_initlog (mio) <= -1) goto oops;
sys_log_inited = 1;
/* intialize the multiplexer object */
if (mio_sys_initmux(mio) <= -1) goto oops;
sys_mux_inited = 0;
sys_mux_inited = 1;
/* initialize the timer object */
if (tmrcapa <= 0) tmrcapa = 1;
@ -150,7 +150,7 @@ void mio_fini (mio_t* mio)
while ((cwq = mio->cwqfl[i]))
{
mio->cwqfl[i] = cwq->next;
MIO_MMGR_FREE (mio->mmgr, cwq);
mio_freemem (mio, cwq);
}
}
@ -201,10 +201,12 @@ void mio_fini (mio_t* mio)
/* purge scheduled timer jobs and kill the timer */
mio_cleartmrjobs (mio);
MIO_MMGR_FREE (mio->mmgr, mio->tmr.jobs);
mio_freemem (mio, mio->tmr.jobs);
mio_sys_finimux (mio); /* close the multiplexer */
mio_sys_finilog (mio); /* close the system logger */
mio_freemem (mio, mio->log.ptr);
}
int mio_setoption (mio_t* mio, mio_option_t id, const void* value)
@ -224,7 +226,6 @@ int mio_setoption (mio_t* mio, mio_option_t id, const void* value)
return 0;
}
einval:
mio_seterrnum (mio, MIO_EINVAL);
return -1;
}
@ -358,7 +359,7 @@ static MIO_INLINE void handle_event (mio_t* mio, mio_dev_t* dev, int events, int
unlink_wq (mio, q);
y = dev->dev_evcb->on_write(dev, q->olen, q->ctx, &q->dstaddr);
MIO_MMGR_FREE (mio->mmgr, q);
mio_freemem (mio, q);
if (y <= -1)
{
@ -375,7 +376,7 @@ static MIO_INLINE void handle_event (mio_t* mio, mio_dev_t* dev, int events, int
{
q = MIO_WQ_HEAD(&dev->wq);
unlink_wq (mio, q);
MIO_MMGR_FREE (dev->mio->mmgr, q);
mio_freemem (mio, q);
}
break;
}
@ -563,7 +564,7 @@ static MIO_INLINE int __exec (mio_t* mio)
else
{
/* TODO: more reuse of objects of different size? */
MIO_MMGR_FREE (mio->mmgr, cwq);
mio_freemem (mio, cwq);
}
}
@ -640,14 +641,9 @@ mio_dev_t* mio_makedev (mio_t* mio, mio_oow_t dev_size, mio_dev_mth_t* dev_mth,
return MIO_NULL;
}
dev = MIO_MMGR_ALLOC(mio->mmgr, dev_size);
if (!dev)
{
mio->errnum = MIO_ESYSMEM;
return MIO_NULL;
}
dev = mio_callocmem(mio, dev_size);
if (!dev) return MIO_NULL;
MIO_MEMSET (dev, 0, dev_size);
dev->mio = mio;
dev->dev_size = dev_size;
/* default capability. dev->dev_mth->make() can change this.
@ -661,10 +657,10 @@ mio_dev_t* mio_makedev (mio_t* mio, mio_oow_t dev_size, mio_dev_mth_t* dev_mth,
dev->cw_count = 0;
/* call the callback function first */
mio->errnum = MIO_ENOERR;
mio_seterrnum (mio, MIO_ENOERR);
if (dev->dev_mth->make(dev, make_ctx) <= -1)
{
if (mio->errnum == MIO_ENOERR) mio->errnum = MIO_EDEVMAKE;
if (mio->errnum == MIO_ENOERR) mio_seterrnum (mio, MIO_EDEVMAKE);
goto oops;
}
@ -723,18 +719,17 @@ oops_after_make:
}
oops:
MIO_MMGR_FREE (mio->mmgr, dev);
mio_freemem (mio, dev);
return MIO_NULL;
}
static int kill_and_free_device (mio_dev_t* dev, int force)
{
mio_t* mio;
mio_t* mio = dev->mio;
MIO_ASSERT (mio, !(dev->dev_capa & MIO_DEV_CAPA_ACTIVE));
MIO_ASSERT (mio, !(dev->dev_capa & MIO_DEV_CAPA_HALTED));
mio = dev->mio;
if (dev->dev_mth->kill(dev, force) <= -1)
{
@ -757,7 +752,7 @@ free_device:
dev->dev_capa &= ~MIO_DEV_CAPA_ZOMBIE;
}
MIO_MMGR_FREE (mio->mmgr, dev);
mio_freemem (mio, dev);
return 0;
}
@ -833,7 +828,7 @@ void mio_killdev (mio_t* mio, mio_dev_t* dev)
if (cwq->dev == dev)
{
MIO_CWQ_UNLINK (cwq);
MIO_MMGR_FREE (mio->mmgr, cwq);
mio_freemem (mio, cwq);
}
cwq = next;
}
@ -845,7 +840,7 @@ void mio_killdev (mio_t* mio, mio_dev_t* dev)
mio_wq_t* q;
q = MIO_WQ_HEAD(&dev->wq);
unlink_wq (mio, q);
MIO_MMGR_FREE (mio->mmgr, q);
mio_freemem (mio, q);
}
if (dev->dev_capa & MIO_DEV_CAPA_HALTED)
@ -888,12 +883,10 @@ kill_device:
void mio_dev_halt (mio_dev_t* dev)
{
mio_t* mio = dev->mio;
if (dev->dev_capa & MIO_DEV_CAPA_ACTIVE)
{
mio_t* mio;
mio = dev->mio;
/* delink the device object from the active device list */
UNLINK_DEVICE_FROM_LIST (&mio->actdev, dev);
dev->dev_capa &= ~MIO_DEV_CAPA_ACTIVE;
@ -906,9 +899,15 @@ void mio_dev_halt (mio_dev_t* dev)
int mio_dev_ioctl (mio_dev_t* dev, int cmd, void* arg)
{
if (dev->dev_mth->ioctl) return dev->dev_mth->ioctl (dev, cmd, arg);
dev->mio->errnum = MIO_ENOIMPL; /* TODO: different error code ? */
mio_t* mio = dev->mio;
if (MIO_UNLIKELY(!dev->dev_mth->ioctl))
{
mio_seterrnum (mio, MIO_ENOIMPL); /* TODO: different error code ? */
return -1;
}
return dev->dev_mth->ioctl(dev, cmd, arg);
}
int mio_dev_watch (mio_dev_t* dev, mio_dev_watch_cmd_t cmd, int events)
@ -1108,13 +1107,14 @@ static void on_write_timeout (mio_t* mio, const mio_ntime_t* now, mio_tmrjob_t*
MIO_ASSERT (mio, q->tmridx == MIO_TMRIDX_INVALID);
MIO_WQ_UNLINK(q);
MIO_MMGR_FREE (mio->mmgr, q);
mio_freemem (mio, q);
if (x <= -1) mio_dev_halt (dev);
}
static int __dev_write (mio_dev_t* dev, const void* data, mio_iolen_t len, const mio_ntime_t* tmout, void* wrctx, const mio_devaddr_t* dstaddr)
{
mio_t* mio = dev->mio;
const mio_uint8_t* uptr;
mio_iolen_t urem, ulen;
mio_wq_t* q;
@ -1124,7 +1124,7 @@ static int __dev_write (mio_dev_t* dev, const void* data, mio_iolen_t len, const
if (dev->dev_capa & MIO_DEV_CAPA_OUT_CLOSED)
{
dev->mio->errnum = MIO_ENOCAPA;
mio_seterrbfmt (mio, MIO_ENOCAPA, "unable to write to closed device");
return -1;
}
@ -1181,7 +1181,7 @@ static int __dev_write (mio_dev_t* dev, const void* data, mio_iolen_t len, const
{
ulen = urem;
x = dev->dev_mth->write (dev, data, &ulen, dstaddr);
x = dev->dev_mth->write(dev, data, &ulen, dstaddr);
if (x <= -1) return -1;
else if (x == 0) goto enqueue_data;
@ -1204,12 +1204,8 @@ enqueue_data:
}
/* queue the remaining data*/
q = (mio_wq_t*)MIO_MMGR_ALLOC(dev->mio->mmgr, MIO_SIZEOF(*q) + (dstaddr? dstaddr->len: 0) + urem);
if (!q)
{
dev->mio->errnum = MIO_ESYSMEM;
return -1;
}
q = (mio_wq_t*)mio_allocmem(mio, MIO_SIZEOF(*q) + (dstaddr? dstaddr->len: 0) + urem);
if (!q) return -1;
q->tmridx = MIO_TMRIDX_INVALID;
q->dev = dev;
@ -1242,10 +1238,10 @@ enqueue_data:
tmrjob.handler = on_write_timeout;
tmrjob.idxptr = &q->tmridx;
q->tmridx = mio_instmrjob(dev->mio, &tmrjob);
q->tmridx = mio_instmrjob(mio, &tmrjob);
if (q->tmridx == MIO_TMRIDX_INVALID)
{
MIO_MMGR_FREE (dev->mio->mmgr, q);
mio_freemem (mio, q);
return -1;
}
}
@ -1256,8 +1252,8 @@ enqueue_data:
/* if output is not being watched, arrange to do so */
if (mio_dev_watch(dev, MIO_DEV_WATCH_RENEW, 0) <= -1)
{
unlink_wq (dev->mio, q);
MIO_MMGR_FREE (dev->mio->mmgr, q);
unlink_wq (mio, q);
mio_freemem (mio, q);
return -1;
}
}
@ -1274,7 +1270,7 @@ enqueue_completed_write:
cwq_extra_aligned = MIO_ALIGN_POW2(cwq_extra_aligned, MIO_CWQFL_ALIGN);
cwqfl_index = cwq_extra_aligned / MIO_CWQFL_SIZE;
if (cwqfl_index < MIO_COUNTOF(dev->mio->cwqfl) && dev->mio->cwqfl[cwqfl_index])
if (cwqfl_index < MIO_COUNTOF(mio->cwqfl) && mio->cwqfl[cwqfl_index])
{
/* take an available cwq object from the free cwq list */
cwq = dev->mio->cwqfl[cwqfl_index];
@ -1282,12 +1278,8 @@ enqueue_completed_write:
}
else
{
cwq = (mio_cwq_t*)MIO_MMGR_ALLOC(dev->mio->mmgr, MIO_SIZEOF(*cwq) + cwq_extra_aligned);
if (!cwq)
{
dev->mio->errnum = MIO_ESYSMEM;
return -1;
}
cwq = (mio_cwq_t*)mio_allocmem(mio, MIO_SIZEOF(*cwq) + cwq_extra_aligned);
if (!cwq) return -1;
}
MIO_MEMSET (cwq, 0, MIO_SIZEOF(*cwq));
@ -1335,7 +1327,7 @@ int mio_makesyshndasync (mio_t* mio, mio_syshnd_t hnd)
return 0;
#else
mio->errnum = MIO_ENOIMPL;
mio_seterrnum (mio, MIO_ENOIMPL);
return -1;
#endif
}

View File

@ -976,6 +976,31 @@ MIO_EXPORT mio_bch_t* mio_dupbchars (
mio_oow_t bcslen
);
/* =========================================================================
* MIO VM LOGGING
* ========================================================================= */
MIO_EXPORT mio_ooi_t mio_logbfmt (
mio_t* mio,
mio_bitmask_t mask,
const mio_bch_t* fmt,
...
);
MIO_EXPORT mio_ooi_t mio_logufmt (
mio_t* mio,
mio_bitmask_t mask,
const mio_uch_t* fmt,
...
);
#if defined(MIO_OOCH_IS_UCH)
# define mio_logoofmt mio_logufmt
#else
# define mio_logoofmt mio_logbfmt
#endif
/* =========================================================================
* MISCELLANEOUS HELPER FUNCTIONS
* ========================================================================= */

View File

@ -344,7 +344,7 @@ TODO
const char_t* stmp = p;
unsigned int index;
do p++; while (p < end);
if (mio_nwifwcsntoindex (stmp, p - stmp, &index) <= -1) return -1;
if (mio_nwifwcsntoindex(stmp, p - stmp, &index) <= -1) return -1;
nwad->in6.sin6_scope_id = index;
#endif
}

View File

@ -71,6 +71,8 @@
# include <sys/types.h>
# include <unistd.h>
# include <errno.h>
# include <signal.h>
# include <stdlib.h>
#endif
#if defined(MIO_BUILD_RELEASE)

View File

@ -81,8 +81,6 @@
struct mio_sys_log_t
{
struct
{
int fd;
int fd_flag; /* bitwise OR'ed fo logfd_flag_t bits */
@ -91,11 +89,10 @@ struct mio_sys_log_t
mio_bch_t buf[4096];
mio_oow_t len;
} out;
} log;
};
typedef mio_sys_log_t xtn_t;
#define GET_XTN(mio) (&(mio)->sys.log)
#define GET_XTN(mio) ((mio)->sys.log)
enum logfd_flag_t
@ -140,27 +137,27 @@ static int write_all (int fd, const mio_bch_t* ptr, mio_oow_t len)
static int write_log (mio_t* mio, int fd, const mio_bch_t* ptr, mio_oow_t len)
{
xtn_t* xtn = GET_XTN(mio);
mio_sys_log_t* log = mio->sys.log;
while (len > 0)
{
if (xtn->log.out.len > 0)
if (log->out.len > 0)
{
mio_oow_t rcapa, cplen;
rcapa = MIO_COUNTOF(xtn->log.out.buf) - xtn->log.out.len;
rcapa = MIO_COUNTOF(log->out.buf) - log->out.len;
cplen = (len >= rcapa)? rcapa: len;
MIO_MEMCPY (&xtn->log.out.buf[xtn->log.out.len], ptr, cplen);
xtn->log.out.len += cplen;
MIO_MEMCPY (&log->out.buf[log->out.len], ptr, cplen);
log->out.len += cplen;
ptr += cplen;
len -= cplen;
if (xtn->log.out.len >= MIO_COUNTOF(xtn->log.out.buf))
if (log->out.len >= MIO_COUNTOF(log->out.buf))
{
int n;
n = write_all(fd, xtn->log.out.buf, xtn->log.out.len);
xtn->log.out.len = 0;
n = write_all(fd, log->out.buf, log->out.len);
log->out.len = 0;
if (n <= -1) return -1;
}
}
@ -168,7 +165,7 @@ static int write_log (mio_t* mio, int fd, const mio_bch_t* ptr, mio_oow_t len)
{
mio_oow_t rcapa;
rcapa = MIO_COUNTOF(xtn->log.out.buf);
rcapa = MIO_COUNTOF(log->out.buf);
if (len >= rcapa)
{
if (write_all(fd, ptr, rcapa) <= -1) return -1;
@ -177,8 +174,8 @@ static int write_log (mio_t* mio, int fd, const mio_bch_t* ptr, mio_oow_t len)
}
else
{
MIO_MEMCPY (xtn->log.out.buf, ptr, len);
xtn->log.out.len += len;
MIO_MEMCPY (log->out.buf, ptr, len);
log->out.len += len;
ptr += len;
len -= len;
@ -191,37 +188,31 @@ static int write_log (mio_t* mio, int fd, const mio_bch_t* ptr, mio_oow_t len)
static void flush_log (mio_t* mio, int fd)
{
xtn_t* xtn = GET_XTN(mio);
if (xtn->log.out.len > 0)
mio_sys_log_t* log = mio->sys.log;
if (log->out.len > 0)
{
write_all (fd, xtn->log.out.buf, xtn->log.out.len);
xtn->log.out.len = 0;
write_all (fd, log->out.buf, log->out.len);
log->out.len = 0;
}
}
void mio_sys_writelog (mio_t* mio, mio_bitmask_t mask, const mio_ooch_t* msg, mio_oow_t len)
{
xtn_t* xtn = GET_XTN(mio);
mio_sys_log_t* log = mio->sys.log;
mio_bch_t buf[256];
mio_oow_t ucslen, bcslen, msgidx;
int n, logfd;
if (mask & MIO_LOG_STDERR)
{
/* the messages that go to STDERR don't get masked out */
logfd = 2;
}
else
{
#if 0
if (!(xtn->log.mask & mask & ~MIO_LOG_ALL_LEVELS)) return; /* check log types */
if (!(xtn->log.mask & mask & ~MIO_LOG_ALL_TYPES)) return; /* check log levels */
#endif
if (mask & MIO_LOG_STDOUT) logfd = 1;
else
{
logfd = xtn->log.fd;
logfd = log->fd;
if (logfd <= -1) return;
}
}
@ -285,7 +276,7 @@ void mio_sys_writelog (mio_t* mio, mio_bitmask_t mask, const mio_ooch_t* msg, mi
write_log (mio, logfd, ts, tslen);
}
if (logfd == xtn->log.fd && (xtn->log.fd_flag & LOGFD_TTY))
if (logfd == log->fd && (log->fd_flag & LOGFD_TTY))
{
if (mask & MIO_LOG_FATAL) write_log (mio, logfd, "\x1B[1;31m", 7);
else if (mask & MIO_LOG_ERROR) write_log (mio, logfd, "\x1B[1;32m", 7);
@ -330,7 +321,7 @@ void mio_sys_writelog (mio_t* mio, mio_bitmask_t mask, const mio_ooch_t* msg, mi
write_log (mio, logfd, msg, len);
#endif
if (logfd == xtn->log.fd && (xtn->log.fd_flag & LOGFD_TTY))
if (logfd == log->fd && (log->fd_flag & LOGFD_TTY))
{
if (mask & (MIO_LOG_FATAL | MIO_LOG_ERROR | MIO_LOG_WARN)) write_log (mio, logfd, "\x1B[0m", 4);
}
@ -338,51 +329,51 @@ void mio_sys_writelog (mio_t* mio, mio_bitmask_t mask, const mio_ooch_t* msg, mi
flush_log (mio, logfd);
}
static MIO_INLINE void reset_log_to_default (xtn_t* xtn)
int mio_sys_initlog (mio_t* mio)
{
#if defined(ENABLE_LOG_INITIALLY)
xtn->log.fd = 2;
xtn->log.fd_flag = 0;
#if defined(HAVE_ISATTY)
if (isatty(xtn->log.fd)) xtn->log.fd_flag |= LOGFD_TTY;
#endif
#else
xtn->log.fd = -1;
xtn->log.fd_flag = 0;
#endif
}
void mio_sys_initlog (mio_t* mio)
{
xtn_t* xtn = GET_XTN(mio);
mio_sys_log_t* log;
mio_bitmask_t logmask;
mio_oow_t pathlen;
/*mio_oow_t pathlen;*/
log = (mio_sys_log_t*)mio_callocmem(mio, MIO_SIZEOF(*log));
if (!log) return -1;
/* TODO: */
#define LOG_FILE "/dev/stderr"
xtn->log.fd = open(LOG_FILE, O_CREAT | O_WRONLY | O_APPEND , 0644);
if (xtn->log.fd == -1)
log->fd = open(LOG_FILE, O_CREAT | O_WRONLY | O_APPEND , 0644);
if (log->fd == -1)
{
/*mio_seterrbfmtwithsyserr (mio, 0, errno, "cannot open log file %hs", LOG_FILE);*/
xtn->log.fd = 2;
xtn->log.fd_flag = 0;
log->fd = 2;
log->fd_flag = 0;
}
else
{
xtn->log.fd_flag |= LOGFD_OPENED_HERE;
log->fd_flag |= LOGFD_OPENED_HERE;
}
#if defined(HAVE_ISATTY)
if (isatty(xtn->log.fd)) xtn->log.fd_flag |= LOGFD_TTY;
if (isatty(log->fd)) log->fd_flag |= LOGFD_TTY;
#endif
logmask = MIO_LOG_ALL_TYPES | MIO_LOG_ALL_LEVELS;
mio_setoption (mio, MIO_LOG_MASK, &logmask);
mio->sys.log = log;
return 0;
}
void mio_sys_finilog (mio_t* mio)
{
xtn_t* xtn = GET_XTN(mio);
if ((xtn->log.fd_flag & LOGFD_OPENED_HERE) && xtn->log.fd >= 0) close (xtn->log.fd);
reset_log_to_default (xtn);
mio_sys_log_t* log = mio->sys.log;
if ((log->fd_flag & LOGFD_OPENED_HERE) && log->fd >= 0)
{
close (log->fd);
log->fd = -1;
log->fd_flag = 0;
}
mio_freemem (mio, log);
mio->sys.log = MIO_NULL;
}

View File

@ -86,11 +86,10 @@ void mio_sys_finimux (mio_t* mio)
int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_capa)
{
mio_t* mio;
mio_t* mio = dev->mio;
mio_sys_mux_t* mux;
mio_oow_t idx;
mio = dev->mio;
mux = (mio_sys_mux_t*)mio->sys.mux;
if (hnd >= mux->map.capa)
@ -372,9 +371,10 @@ int mio_sys_waitmux (mio_t* mio, const mio_ntime_t* tmout, mio_sys_mux_evtcb_t e
event_handler (mio, dev, events, rdhup);
}
#else
# error NO SUPPORTED MULTIPLEXER
#endif
return 0;
}

View File

@ -139,12 +139,8 @@ mio_tmridx_t mio_instmrjob (mio_t* mio, const mio_tmrjob_t* job)
MIO_ASSERT (mio, mio->tmr.capa >= 1);
new_capa = mio->tmr.capa * 2;
tmp = (mio_tmrjob_t*)MIO_MMGR_REALLOC (mio->mmgr, mio->tmr.jobs, new_capa * MIO_SIZEOF(*tmp));
if (tmp == MIO_NULL)
{
mio->errnum = MIO_ESYSMEM;
return MIO_TMRIDX_INVALID;
}
tmp = (mio_tmrjob_t*)mio_reallocmem(mio, mio->tmr.jobs, new_capa * MIO_SIZEOF(*tmp));
if (!tmp) return MIO_TMRIDX_INVALID;
mio->tmr.jobs = tmp;
mio->tmr.capa = new_capa;
@ -153,7 +149,7 @@ mio_tmridx_t mio_instmrjob (mio_t* mio, const mio_tmrjob_t* job)
mio->tmr.size = mio->tmr.size + 1;
mio->tmr.jobs[index] = *job;
if (mio->tmr.jobs[index].idxptr) *mio->tmr.jobs[index].idxptr = index;
return sift_up (mio, index, 0);
return sift_up(mio, index, 0);
}
mio_tmridx_t mio_updtmrjob (mio_t* mio, mio_tmridx_t index, const mio_tmrjob_t* job)
@ -196,7 +192,7 @@ int mio_gettmrtmout (mio_t* mio, const mio_ntime_t* tm, mio_ntime_t* tmout)
/* time-out can't be calculated when there's no job scheduled */
if (mio->tmr.size <= 0)
{
mio->errnum = MIO_ENOENT;
mio_seterrbfmt (mio, MIO_ENOENT, "unable to compute timeout as no job is scheduled");
return -1;
}
@ -214,7 +210,7 @@ mio_tmrjob_t* mio_gettmrjob (mio_t* mio, mio_tmridx_t index)
{
if (index < 0 || index >= mio->tmr.size)
{
mio->errnum = MIO_ENOENT;
mio_seterrbfmt (mio, MIO_ENOENT, "unable to get timer job as the given index is out of range");
return MIO_NULL;
}
@ -225,7 +221,7 @@ int mio_gettmrjobdeadline (mio_t* mio, mio_tmridx_t index, mio_ntime_t* deadline
{
if (index < 0 || index >= mio->tmr.size)
{
mio->errnum = MIO_ENOENT;
mio_seterrbfmt (mio, MIO_ENOENT, "unable to get timer job deadline as the given index is out of range");
return -1;
}

View File

@ -39,12 +39,8 @@ mio_bch_t* mio_mbsdup (mio_t* mio, const mio_bch_t* src)
while (*dst != MIO_MT('\0')) dst++;
len = dst - src;
dst = MIO_MMGR_ALLOC (mio->mmgr, (len + 1) * MIO_SIZEOF(*src));
if (!dst)
{
mio->errnum = MIO_ESYSMEM;
return MIO_NULL;
}
dst = mio_allocmem(mio, (len + 1) * MIO_SIZEOF(*src));
if (!dst) return MIO_NULL;
MIO_MEMCPY (dst, src, (len + 1) * MIO_SIZEOF(*src));
return dst;