renamed stio to mio in source files

This commit is contained in:
2018-12-12 13:15:54 +00:00
parent daf5143ba3
commit 14dc22fd0e
41 changed files with 14130 additions and 11491 deletions

View File

@ -1,2 +1,2 @@
all:
cc -g -I. -Wall -o stio main.c stio.c stio-tcp.c stio-udp.c stio-sck.c
cc -g -I. -Wall -o mio main.c mio.c mio-tcp.c mio-udp.c mio-sck.c

View File

@ -20,39 +20,39 @@ LIBADD_LIB_COMMON = $(LIBM) $(LIBLTDL)
#pkgbindir = $(bindir)
include_HEADERS = \
stio-cfg.h \
stio-cmn.h \
stio-pro.h \
stio-sck.h \
stio.h
mio-cfg.h \
mio-cmn.h \
mio-pro.h \
mio-sck.h \
mio.h
lib_LTLIBRARIES = libstio.la
libstio_la_SOURCES = \
stio-prv.h \
stio.c \
stio-pro.c \
stio-sck.c \
stio-tim.c \
stio-tmr.c \
stio-utl.c
libstio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
libstio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
libstio_la_LIBADD = $(LIBADD_LIB_COMMON) $(SSL_LIBS)
lib_LTLIBRARIES = libmio.la
libmio_la_SOURCES = \
mio-prv.h \
mio.c \
mio-pro.c \
mio-sck.c \
mio-tim.c \
mio-tmr.c \
mio-utl.c
libmio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
libmio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
libmio_la_LIBADD = $(LIBADD_LIB_COMMON) $(SSL_LIBS)
bin_PROGRAMS = stio
stio_SOURCES = main.c
stio_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
stio_LDFLAGS = $(LDFLAGS_LIB_COMMON)
stio_LDADD = $(LIBADD_LIB_COMMON) -lstio
bin_PROGRAMS = mio
mio_SOURCES = main.c
mio_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
mio_LDFLAGS = $(LDFLAGS_LIB_COMMON)
mio_LDADD = $(LIBADD_LIB_COMMON) -lmio
install-data-hook:
@echo "#ifndef _STIO_CFG_H_" > "$(DESTDIR)$(includedir)/stio-cfg.h"
@echo "#define _STIO_CFG_H_" >> "$(DESTDIR)$(includedir)/stio-cfg.h"
@$(EGREP) "#define[ ]+STIO_" "$(abs_builddir)/stio-cfg.h" >> "$(DESTDIR)$(includedir)/stio-cfg.h"
@echo "#endif" >> "$(DESTDIR)$(includedir)/stio-cfg.h"
@$(RM) "$(DESTDIR)$(includedir)/stio-cfg.h.in"
@$(SED) 's|/\*#define STIO_HAVE_CFG_H\*/|#define STIO_HAVE_CFG_H|' "$(srcdir)/stio-cmn.h" > "$(DESTDIR)$(includedir)/stio-cmn.h"
@echo "#ifndef _MIO_CFG_H_" > "$(DESTDIR)$(includedir)/mio-cfg.h"
@echo "#define _MIO_CFG_H_" >> "$(DESTDIR)$(includedir)/mio-cfg.h"
@$(EGREP) "#define[ ]+MIO_" "$(abs_builddir)/mio-cfg.h" >> "$(DESTDIR)$(includedir)/mio-cfg.h"
@echo "#endif" >> "$(DESTDIR)$(includedir)/mio-cfg.h"
@$(RM) "$(DESTDIR)$(includedir)/mio-cfg.h.in"
@$(SED) 's|/\*#define MIO_HAVE_CFG_H\*/|#define MIO_HAVE_CFG_H|' "$(srcdir)/mio-cmn.h" > "$(DESTDIR)$(includedir)/mio-cmn.h"
uninstall-hook:
@$(RM) "$(DESTDIR)$(includedir)/stio-cfg.h"
@$(RM) "$(DESTDIR)$(includedir)/mio-cfg.h"

View File

@ -1,9 +1,8 @@
# Makefile.in generated by automake 1.11.6 from Makefile.am.
# Makefile.in generated by automake 1.15 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
# Foundation, Inc.
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@ -18,23 +17,61 @@
VPATH = @srcdir@
am__make_dryrun = \
{ \
am__dry=no; \
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
| grep '^AM OK$$' >/dev/null || am__dry=yes;; \
*) \
for am__flg in $$MAKEFLAGS; do \
case $$am__flg in \
*=*|--*) ;; \
*n*) am__dry=yes; break;; \
esac; \
done;; \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
test $$am__dry = yes; \
}
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@ -53,10 +90,8 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
bin_PROGRAMS = stio$(EXEEXT)
bin_PROGRAMS = mio$(EXEEXT)
subdir = lib
DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/stio-cfg.h.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_sign.m4 \
$(top_srcdir)/m4/ax_cxx_namespace.m4 \
@ -66,8 +101,10 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_sign.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(include_HEADERS) \
$(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = stio-cfg.h
CONFIG_HEADER = mio-cfg.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@ -102,24 +139,37 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 =
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
libstio_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
am_libstio_la_OBJECTS = libstio_la-stio.lo libstio_la-stio-pro.lo \
libstio_la-stio-sck.lo libstio_la-stio-tim.lo \
libstio_la-stio-tmr.lo libstio_la-stio-utl.lo
libstio_la_OBJECTS = $(am_libstio_la_OBJECTS)
libmio_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
am_libmio_la_OBJECTS = libmio_la-mio.lo libmio_la-mio-pro.lo \
libmio_la-mio-sck.lo libmio_la-mio-tim.lo libmio_la-mio-tmr.lo \
libmio_la-mio-utl.lo
libmio_la_OBJECTS = $(am_libmio_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
libstio_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
am__v_lt_1 =
libmio_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libstio_la_LDFLAGS) $(LDFLAGS) -o $@
$(libmio_la_LDFLAGS) $(LDFLAGS) -o $@
PROGRAMS = $(bin_PROGRAMS)
am_stio_OBJECTS = stio-main.$(OBJEXT)
stio_OBJECTS = $(am_stio_OBJECTS)
stio_DEPENDENCIES = $(am__DEPENDENCIES_2)
stio_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
am_mio_OBJECTS = mio-main.$(OBJEXT)
mio_OBJECTS = $(am_mio_OBJECTS)
mio_DEPENDENCIES = $(am__DEPENDENCIES_2)
mio_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(stio_LDFLAGS) $(LDFLAGS) -o $@
$(mio_LDFLAGS) $(LDFLAGS) -o $@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES =
depcomp = $(SHELL) $(top_srcdir)/ac/depcomp
am__depfiles_maybe = depfiles
@ -132,30 +182,46 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
SOURCES = $(libstio_la_SOURCES) $(stio_SOURCES)
DIST_SOURCES = $(libstio_la_SOURCES) $(stio_SOURCES)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libmio_la_SOURCES) $(mio_SOURCES)
DIST_SOURCES = $(libmio_la_SOURCES) $(mio_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
HEADERS = $(include_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
$(LISP)mio-cfg.h.in
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/mio-cfg.h.in \
$(top_srcdir)/ac/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@ -181,7 +247,6 @@ DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@ -205,8 +270,23 @@ LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MIO_PROJECT_AUTHOR = @MIO_PROJECT_AUTHOR@
MIO_PROJECT_URL = @MIO_PROJECT_URL@
MIO_SIZEOF_CHAR = @MIO_SIZEOF_CHAR@
MIO_SIZEOF_DOUBLE = @MIO_SIZEOF_DOUBLE@
MIO_SIZEOF_FLOAT = @MIO_SIZEOF_FLOAT@
MIO_SIZEOF_INT = @MIO_SIZEOF_INT@
MIO_SIZEOF_LONG = @MIO_SIZEOF_LONG@
MIO_SIZEOF_LONG_DOUBLE = @MIO_SIZEOF_LONG_DOUBLE@
MIO_SIZEOF_LONG_LONG = @MIO_SIZEOF_LONG_LONG@
MIO_SIZEOF_OFF64_T = @MIO_SIZEOF_OFF64_T@
MIO_SIZEOF_OFF_T = @MIO_SIZEOF_OFF_T@
MIO_SIZEOF_SHORT = @MIO_SIZEOF_SHORT@
MIO_SIZEOF_VOID_P = @MIO_SIZEOF_VOID_P@
MIO_SIZEOF_WCHAR_T = @MIO_SIZEOF_WCHAR_T@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
@ -227,30 +307,13 @@ PACKAGE_VERSION_PATCH = @PACKAGE_VERSION_PATCH@
PATH_SEPARATOR = @PATH_SEPARATOR@
QUADMATH_LIBS = @QUADMATH_LIBS@
RANLIB = @RANLIB@
RM = @RM@
RMDIR = @RMDIR@
SED = @SED@
SENDFILE_LIBS = @SENDFILE_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCKET_LIBS = @SOCKET_LIBS@
SSL_LIBS = @SSL_LIBS@
STIO_PROJECT_AUTHOR = @STIO_PROJECT_AUTHOR@
STIO_PROJECT_URL = @STIO_PROJECT_URL@
STIO_SIZEOF_CHAR = @STIO_SIZEOF_CHAR@
STIO_SIZEOF_DOUBLE = @STIO_SIZEOF_DOUBLE@
STIO_SIZEOF_FLOAT = @STIO_SIZEOF_FLOAT@
STIO_SIZEOF_INT = @STIO_SIZEOF_INT@
STIO_SIZEOF_LONG = @STIO_SIZEOF_LONG@
STIO_SIZEOF_LONG_DOUBLE = @STIO_SIZEOF_LONG_DOUBLE@
STIO_SIZEOF_LONG_LONG = @STIO_SIZEOF_LONG_LONG@
STIO_SIZEOF_OFF64_T = @STIO_SIZEOF_OFF64_T@
STIO_SIZEOF_OFF_T = @STIO_SIZEOF_OFF_T@
STIO_SIZEOF_SHORT = @STIO_SIZEOF_SHORT@
STIO_SIZEOF_VOID_P = @STIO_SIZEOF_VOID_P@
STIO_SIZEOF_WCHAR_T = @STIO_SIZEOF_WCHAR_T@
STRIP = @STRIP@
TRUE = @TRUE@
UNICOWS_LIBS = @UNICOWS_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
@ -298,6 +361,7 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@ -325,30 +389,30 @@ LIBADD_LIB_COMMON = $(LIBM) $(LIBLTDL)
#pkglibdir = $(libdir)
#pkgbindir = $(bindir)
include_HEADERS = \
stio-cfg.h \
stio-cmn.h \
stio-pro.h \
stio-sck.h \
stio.h
mio-cfg.h \
mio-cmn.h \
mio-pro.h \
mio-sck.h \
mio.h
lib_LTLIBRARIES = libstio.la
libstio_la_SOURCES = \
stio-prv.h \
stio.c \
stio-pro.c \
stio-sck.c \
stio-tim.c \
stio-tmr.c \
stio-utl.c
lib_LTLIBRARIES = libmio.la
libmio_la_SOURCES = \
mio-prv.h \
mio.c \
mio-pro.c \
mio-sck.c \
mio-tim.c \
mio-tmr.c \
mio-utl.c
libstio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
libstio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
libstio_la_LIBADD = $(LIBADD_LIB_COMMON) $(SSL_LIBS)
stio_SOURCES = main.c
stio_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
stio_LDFLAGS = $(LDFLAGS_LIB_COMMON)
stio_LDADD = $(LIBADD_LIB_COMMON) -lstio
all: stio-cfg.h
libmio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
libmio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
libmio_la_LIBADD = $(LIBADD_LIB_COMMON) $(SSL_LIBS)
mio_SOURCES = main.c
mio_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
mio_LDFLAGS = $(LDFLAGS_LIB_COMMON)
mio_LDADD = $(LIBADD_LIB_COMMON) -lmio
all: mio-cfg.h
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
@ -365,7 +429,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign lib/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@ -384,20 +447,21 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
stio-cfg.h: stamp-h1
@if test ! -f $@; then rm -f stamp-h1; else :; fi
@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
mio-cfg.h: stamp-h1
@test -f $@ || rm -f stamp-h1
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
stamp-h1: $(srcdir)/stio-cfg.h.in $(top_builddir)/config.status
stamp-h1: $(srcdir)/mio-cfg.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status lib/stio-cfg.h
$(srcdir)/stio-cfg.h.in: $(am__configure_deps)
cd $(top_builddir) && $(SHELL) ./config.status lib/mio-cfg.h
$(srcdir)/mio-cfg.h.in: $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f stio-cfg.h stamp-h1
-rm -f mio-cfg.h stamp-h1
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
@ -424,14 +488,17 @@ uninstall-libLTLIBRARIES:
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libstio.la: $(libstio_la_OBJECTS) $(libstio_la_DEPENDENCIES) $(EXTRA_libstio_la_DEPENDENCIES)
$(AM_V_CCLD)$(libstio_la_LINK) -rpath $(libdir) $(libstio_la_OBJECTS) $(libstio_la_LIBADD) $(LIBS)
@list='$(lib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
libmio.la: $(libmio_la_OBJECTS) $(libmio_la_DEPENDENCIES) $(EXTRA_libmio_la_DEPENDENCIES)
$(AM_V_CCLD)$(libmio_la_LINK) -rpath $(libdir) $(libmio_la_OBJECTS) $(libmio_la_LIBADD) $(LIBS)
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
@ -441,10 +508,12 @@ install-binPROGRAMS: $(bin_PROGRAMS)
fi; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
while read p p1; do if test -f $$p || test -f $$p1; \
then echo "$$p"; echo "$$p"; else :; fi; \
while read p p1; do if test -f $$p \
|| test -f $$p1 \
; then echo "$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
sed -e 'p;s,.*/,,;n;h' \
-e 's|.*|.|' \
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
@ -465,7 +534,8 @@ uninstall-binPROGRAMS:
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-e 's/$$/$(EXEEXT)/' `; \
-e 's/$$/$(EXEEXT)/' \
`; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(bindir)" && rm -f $$files
@ -478,9 +548,10 @@ clean-binPROGRAMS:
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
stio$(EXEEXT): $(stio_OBJECTS) $(stio_DEPENDENCIES) $(EXTRA_stio_DEPENDENCIES)
@rm -f stio$(EXEEXT)
$(AM_V_CCLD)$(stio_LINK) $(stio_OBJECTS) $(stio_LDADD) $(LIBS)
mio$(EXEEXT): $(mio_OBJECTS) $(mio_DEPENDENCIES) $(EXTRA_mio_DEPENDENCIES)
@rm -f mio$(EXEEXT)
$(AM_V_CCLD)$(mio_LINK) $(mio_OBJECTS) $(mio_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@ -488,90 +559,93 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-pro.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-sck.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-tim.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-tmr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-utl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stio-main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio-pro.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio-sck.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio-tim.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio-tmr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio-utl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mio-main.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
libstio_la-stio.lo: stio.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libstio_la-stio.lo -MD -MP -MF $(DEPDIR)/libstio_la-stio.Tpo -c -o libstio_la-stio.lo `test -f 'stio.c' || echo '$(srcdir)/'`stio.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstio_la-stio.Tpo $(DEPDIR)/libstio_la-stio.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stio.c' object='libstio_la-stio.lo' libtool=yes @AMDEPBACKSLASH@
libmio_la-mio.lo: mio.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-mio.lo -MD -MP -MF $(DEPDIR)/libmio_la-mio.Tpo -c -o libmio_la-mio.lo `test -f 'mio.c' || echo '$(srcdir)/'`mio.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-mio.Tpo $(DEPDIR)/libmio_la-mio.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mio.c' object='libmio_la-mio.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libstio_la-stio.lo `test -f 'stio.c' || echo '$(srcdir)/'`stio.c
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-mio.lo `test -f 'mio.c' || echo '$(srcdir)/'`mio.c
libstio_la-stio-pro.lo: stio-pro.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libstio_la-stio-pro.lo -MD -MP -MF $(DEPDIR)/libstio_la-stio-pro.Tpo -c -o libstio_la-stio-pro.lo `test -f 'stio-pro.c' || echo '$(srcdir)/'`stio-pro.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstio_la-stio-pro.Tpo $(DEPDIR)/libstio_la-stio-pro.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stio-pro.c' object='libstio_la-stio-pro.lo' libtool=yes @AMDEPBACKSLASH@
libmio_la-mio-pro.lo: mio-pro.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-mio-pro.lo -MD -MP -MF $(DEPDIR)/libmio_la-mio-pro.Tpo -c -o libmio_la-mio-pro.lo `test -f 'mio-pro.c' || echo '$(srcdir)/'`mio-pro.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-mio-pro.Tpo $(DEPDIR)/libmio_la-mio-pro.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mio-pro.c' object='libmio_la-mio-pro.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libstio_la-stio-pro.lo `test -f 'stio-pro.c' || echo '$(srcdir)/'`stio-pro.c
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-mio-pro.lo `test -f 'mio-pro.c' || echo '$(srcdir)/'`mio-pro.c
libstio_la-stio-sck.lo: stio-sck.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libstio_la-stio-sck.lo -MD -MP -MF $(DEPDIR)/libstio_la-stio-sck.Tpo -c -o libstio_la-stio-sck.lo `test -f 'stio-sck.c' || echo '$(srcdir)/'`stio-sck.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstio_la-stio-sck.Tpo $(DEPDIR)/libstio_la-stio-sck.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stio-sck.c' object='libstio_la-stio-sck.lo' libtool=yes @AMDEPBACKSLASH@
libmio_la-mio-sck.lo: mio-sck.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-mio-sck.lo -MD -MP -MF $(DEPDIR)/libmio_la-mio-sck.Tpo -c -o libmio_la-mio-sck.lo `test -f 'mio-sck.c' || echo '$(srcdir)/'`mio-sck.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-mio-sck.Tpo $(DEPDIR)/libmio_la-mio-sck.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mio-sck.c' object='libmio_la-mio-sck.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libstio_la-stio-sck.lo `test -f 'stio-sck.c' || echo '$(srcdir)/'`stio-sck.c
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-mio-sck.lo `test -f 'mio-sck.c' || echo '$(srcdir)/'`mio-sck.c
libstio_la-stio-tim.lo: stio-tim.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libstio_la-stio-tim.lo -MD -MP -MF $(DEPDIR)/libstio_la-stio-tim.Tpo -c -o libstio_la-stio-tim.lo `test -f 'stio-tim.c' || echo '$(srcdir)/'`stio-tim.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstio_la-stio-tim.Tpo $(DEPDIR)/libstio_la-stio-tim.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stio-tim.c' object='libstio_la-stio-tim.lo' libtool=yes @AMDEPBACKSLASH@
libmio_la-mio-tim.lo: mio-tim.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-mio-tim.lo -MD -MP -MF $(DEPDIR)/libmio_la-mio-tim.Tpo -c -o libmio_la-mio-tim.lo `test -f 'mio-tim.c' || echo '$(srcdir)/'`mio-tim.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-mio-tim.Tpo $(DEPDIR)/libmio_la-mio-tim.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mio-tim.c' object='libmio_la-mio-tim.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libstio_la-stio-tim.lo `test -f 'stio-tim.c' || echo '$(srcdir)/'`stio-tim.c
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-mio-tim.lo `test -f 'mio-tim.c' || echo '$(srcdir)/'`mio-tim.c
libstio_la-stio-tmr.lo: stio-tmr.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libstio_la-stio-tmr.lo -MD -MP -MF $(DEPDIR)/libstio_la-stio-tmr.Tpo -c -o libstio_la-stio-tmr.lo `test -f 'stio-tmr.c' || echo '$(srcdir)/'`stio-tmr.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstio_la-stio-tmr.Tpo $(DEPDIR)/libstio_la-stio-tmr.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stio-tmr.c' object='libstio_la-stio-tmr.lo' libtool=yes @AMDEPBACKSLASH@
libmio_la-mio-tmr.lo: mio-tmr.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-mio-tmr.lo -MD -MP -MF $(DEPDIR)/libmio_la-mio-tmr.Tpo -c -o libmio_la-mio-tmr.lo `test -f 'mio-tmr.c' || echo '$(srcdir)/'`mio-tmr.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-mio-tmr.Tpo $(DEPDIR)/libmio_la-mio-tmr.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mio-tmr.c' object='libmio_la-mio-tmr.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libstio_la-stio-tmr.lo `test -f 'stio-tmr.c' || echo '$(srcdir)/'`stio-tmr.c
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-mio-tmr.lo `test -f 'mio-tmr.c' || echo '$(srcdir)/'`mio-tmr.c
libstio_la-stio-utl.lo: stio-utl.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libstio_la-stio-utl.lo -MD -MP -MF $(DEPDIR)/libstio_la-stio-utl.Tpo -c -o libstio_la-stio-utl.lo `test -f 'stio-utl.c' || echo '$(srcdir)/'`stio-utl.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstio_la-stio-utl.Tpo $(DEPDIR)/libstio_la-stio-utl.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stio-utl.c' object='libstio_la-stio-utl.lo' libtool=yes @AMDEPBACKSLASH@
libmio_la-mio-utl.lo: mio-utl.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-mio-utl.lo -MD -MP -MF $(DEPDIR)/libmio_la-mio-utl.Tpo -c -o libmio_la-mio-utl.lo `test -f 'mio-utl.c' || echo '$(srcdir)/'`mio-utl.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-mio-utl.Tpo $(DEPDIR)/libmio_la-mio-utl.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mio-utl.c' object='libmio_la-mio-utl.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libstio_la-stio-utl.lo `test -f 'stio-utl.c' || echo '$(srcdir)/'`stio-utl.c
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-mio-utl.lo `test -f 'mio-utl.c' || echo '$(srcdir)/'`mio-utl.c
stio-main.o: main.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stio-main.o -MD -MP -MF $(DEPDIR)/stio-main.Tpo -c -o stio-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stio-main.Tpo $(DEPDIR)/stio-main.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='stio-main.o' libtool=no @AMDEPBACKSLASH@
mio-main.o: main.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mio-main.o -MD -MP -MF $(DEPDIR)/mio-main.Tpo -c -o mio-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mio-main.Tpo $(DEPDIR)/mio-main.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='mio-main.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stio-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mio-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
stio-main.obj: main.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stio-main.obj -MD -MP -MF $(DEPDIR)/stio-main.Tpo -c -o stio-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stio-main.Tpo $(DEPDIR)/stio-main.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='stio-main.obj' libtool=no @AMDEPBACKSLASH@
mio-main.obj: main.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mio-main.obj -MD -MP -MF $(DEPDIR)/mio-main.Tpo -c -o mio-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mio-main.Tpo $(DEPDIR)/mio-main.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='mio-main.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stio-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mio-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
mostlyclean-libtool:
-rm -f *.lo
@ -600,26 +674,15 @@ uninstall-includeHEADERS:
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
TAGS: $(HEADERS) $(SOURCES) stio-cfg.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) stio-cfg.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
@ -631,15 +694,11 @@ TAGS: $(HEADERS) $(SOURCES) stio-cfg.h.in $(TAGS_DEPENDENCIES) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) stio-cfg.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) stio-cfg.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
@ -648,6 +707,21 @@ GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
@ -684,7 +758,7 @@ distdir: $(DISTFILES)
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) stio-cfg.h
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) mio-cfg.h
install-binPROGRAMS: install-libLTLIBRARIES
installdirs:
@ -797,9 +871,10 @@ uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS \
$(MAKE) $(AM_MAKEFLAGS) uninstall-hook
.MAKE: all install-am install-data-am install-strip uninstall-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
clean-generic clean-libLTLIBRARIES clean-libtool ctags \
distclean distclean-compile distclean-generic distclean-hdr \
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
clean-libtool cscopelist-am ctags ctags-am distclean \
distclean-compile distclean-generic distclean-hdr \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-binPROGRAMS \
install-data install-data-am install-data-hook install-dvi \
@ -810,21 +885,23 @@ uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-binPROGRAMS \
tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \
uninstall-hook uninstall-includeHEADERS \
uninstall-libLTLIBRARIES
.PRECIOUS: Makefile
install-data-hook:
@echo "#ifndef _STIO_CFG_H_" > "$(DESTDIR)$(includedir)/stio-cfg.h"
@echo "#define _STIO_CFG_H_" >> "$(DESTDIR)$(includedir)/stio-cfg.h"
@$(EGREP) "#define[ ]+STIO_" "$(abs_builddir)/stio-cfg.h" >> "$(DESTDIR)$(includedir)/stio-cfg.h"
@echo "#endif" >> "$(DESTDIR)$(includedir)/stio-cfg.h"
@$(RM) "$(DESTDIR)$(includedir)/stio-cfg.h.in"
@$(SED) 's|/\*#define STIO_HAVE_CFG_H\*/|#define STIO_HAVE_CFG_H|' "$(srcdir)/stio-cmn.h" > "$(DESTDIR)$(includedir)/stio-cmn.h"
@echo "#ifndef _MIO_CFG_H_" > "$(DESTDIR)$(includedir)/mio-cfg.h"
@echo "#define _MIO_CFG_H_" >> "$(DESTDIR)$(includedir)/mio-cfg.h"
@$(EGREP) "#define[ ]+MIO_" "$(abs_builddir)/mio-cfg.h" >> "$(DESTDIR)$(includedir)/mio-cfg.h"
@echo "#endif" >> "$(DESTDIR)$(includedir)/mio-cfg.h"
@$(RM) "$(DESTDIR)$(includedir)/mio-cfg.h.in"
@$(SED) 's|/\*#define MIO_HAVE_CFG_H\*/|#define MIO_HAVE_CFG_H|' "$(srcdir)/mio-cmn.h" > "$(DESTDIR)$(includedir)/mio-cmn.h"
uninstall-hook:
@$(RM) "$(DESTDIR)$(includedir)/stio-cfg.h"
@$(RM) "$(DESTDIR)$(includedir)/mio-cfg.h"
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.

View File

@ -25,9 +25,9 @@
*/
#include <stio.h>
#include <stio-sck.h>
#include <stio-pro.h>
#include <mio.h>
#include <mio-sck.h>
#include <mio-pro.h>
#include <stdlib.h>
#include <string.h>
@ -56,21 +56,21 @@
struct mmgr_stat_t
{
stio_size_t total_count;
mio_size_t total_count;
};
typedef struct mmgr_stat_t mmgr_stat_t;
static mmgr_stat_t mmgr_stat;
static void* mmgr_alloc (stio_mmgr_t* mmgr, stio_size_t size)
static void* mmgr_alloc (mio_mmgr_t* mmgr, mio_size_t size)
{
void* x;
if (((mmgr_stat_t*)mmgr->ctx)->total_count > 300)
{
printf ("CRITICAL ERROR ---> too many heap chunks...\n");
return STIO_NULL;
return MIO_NULL;
}
x = malloc (size);
@ -78,19 +78,19 @@ printf ("CRITICAL ERROR ---> too many heap chunks...\n");
return x;
}
static void* mmgr_realloc (stio_mmgr_t* mmgr, void* ptr, stio_size_t size)
static void* mmgr_realloc (mio_mmgr_t* mmgr, void* ptr, mio_size_t size)
{
return realloc (ptr, size);
}
static void mmgr_free (stio_mmgr_t* mmgr, void* ptr)
static void mmgr_free (mio_mmgr_t* mmgr, void* ptr)
{
((mmgr_stat_t*)mmgr->ctx)->total_count--;
return free (ptr);
}
static stio_mmgr_t mmgr =
static mio_mmgr_t mmgr =
{
mmgr_alloc,
mmgr_realloc,
@ -122,31 +122,31 @@ struct tcp_server_t
};
typedef struct tcp_server_t tcp_server_t;
static void tcp_sck_on_disconnect (stio_dev_sck_t* tcp)
static void tcp_sck_on_disconnect (mio_dev_sck_t* tcp)
{
switch (STIO_DEV_SCK_GET_PROGRESS(tcp))
switch (MIO_DEV_SCK_GET_PROGRESS(tcp))
{
case STIO_DEV_SCK_CONNECTING:
case MIO_DEV_SCK_CONNECTING:
printf ("OUTGOING SESSION DISCONNECTED - FAILED TO CONNECT (%d) TO REMOTE SERVER\n", (int)tcp->sck);
break;
case STIO_DEV_SCK_CONNECTING_SSL:
case MIO_DEV_SCK_CONNECTING_SSL:
printf ("OUTGOING SESSION DISCONNECTED - FAILED TO SSL-CONNECT (%d) TO REMOTE SERVER\n", (int)tcp->sck);
break;
case STIO_DEV_SCK_LISTENING:
case MIO_DEV_SCK_LISTENING:
printf ("SHUTTING DOWN THE SERVER SOCKET(%d)...\n", (int)tcp->sck);
break;
case STIO_DEV_SCK_CONNECTED:
case MIO_DEV_SCK_CONNECTED:
printf ("OUTGOING CLIENT CONNECTION GOT TORN DOWN(%d).......\n", (int)tcp->sck);
break;
case STIO_DEV_SCK_ACCEPTING_SSL:
case MIO_DEV_SCK_ACCEPTING_SSL:
printf ("INCOMING SSL-ACCEPT GOT DISCONNECTED(%d) ....\n", (int)tcp->sck);
break;
case STIO_DEV_SCK_ACCEPTED:
case MIO_DEV_SCK_ACCEPTED:
printf ("INCOMING CLIENT BEING SERVED GOT DISCONNECTED(%d).......\n", (int)tcp->sck);
break;
@ -155,44 +155,44 @@ static void tcp_sck_on_disconnect (stio_dev_sck_t* tcp)
break;
}
}
static int tcp_sck_on_connect (stio_dev_sck_t* tcp)
static int tcp_sck_on_connect (mio_dev_sck_t* tcp)
{
stio_sckfam_t fam;
stio_scklen_t len;
stio_mchar_t buf1[128], buf2[128];
mio_sckfam_t fam;
mio_scklen_t len;
mio_mchar_t buf1[128], buf2[128];
memset (buf1, 0, STIO_SIZEOF(buf1));
memset (buf2, 0, STIO_SIZEOF(buf2));
memset (buf1, 0, MIO_SIZEOF(buf1));
memset (buf2, 0, MIO_SIZEOF(buf2));
stio_getsckaddrinfo (tcp->stio, &tcp->localaddr, &len, &fam);
inet_ntop (fam, tcp->localaddr.data, buf1, STIO_COUNTOF(buf1));
mio_getsckaddrinfo (tcp->mio, &tcp->localaddr, &len, &fam);
inet_ntop (fam, tcp->localaddr.data, buf1, MIO_COUNTOF(buf1));
stio_getsckaddrinfo (tcp->stio, &tcp->remoteaddr, &len, &fam);
inet_ntop (fam, tcp->remoteaddr.data, buf2, STIO_COUNTOF(buf2));
mio_getsckaddrinfo (tcp->mio, &tcp->remoteaddr, &len, &fam);
inet_ntop (fam, tcp->remoteaddr.data, buf2, MIO_COUNTOF(buf2));
if (tcp->state & STIO_DEV_SCK_CONNECTED)
if (tcp->state & MIO_DEV_SCK_CONNECTED)
{
printf ("device connected to a remote server... LOCAL %s:%d REMOTE %s:%d.", buf1, stio_getsckaddrport(&tcp->localaddr), buf2, stio_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 & STIO_DEV_SCK_ACCEPTED)
else if (tcp->state & MIO_DEV_SCK_ACCEPTED)
{
printf ("device accepted client device... .LOCAL %s:%d REMOTE %s:%d\n", buf1, stio_getsckaddrport(&tcp->localaddr), buf2, stio_getsckaddrport(&tcp->remoteaddr));
printf ("device accepted client device... .LOCAL %s:%d REMOTE %s:%d\n", buf1, mio_getsckaddrport(&tcp->localaddr), buf2, mio_getsckaddrport(&tcp->remoteaddr));
}
return stio_dev_sck_write (tcp, "hello", 5, STIO_NULL, STIO_NULL);
return mio_dev_sck_write (tcp, "hello", 5, MIO_NULL, MIO_NULL);
}
static int tcp_sck_on_write (stio_dev_sck_t* tcp, stio_iolen_t wrlen, void* wrctx, const stio_sckaddr_t* dstaddr)
static int tcp_sck_on_write (mio_dev_sck_t* tcp, mio_iolen_t wrlen, void* wrctx, const mio_sckaddr_t* dstaddr)
{
tcp_server_t* ts;
if (wrlen <= -1)
{
printf ("SEDING TIMED OUT...........\n");
stio_dev_sck_halt(tcp);
mio_dev_sck_halt(tcp);
}
else
{
@ -200,17 +200,17 @@ else
printf (">>> SENT MESSAGE %d of length %ld\n", ts->tally, (long int)wrlen);
ts->tally++;
// if (ts->tally >= 2) stio_dev_sck_halt (tcp);
// if (ts->tally >= 2) mio_dev_sck_halt (tcp);
printf ("ENABLING READING..............................\n");
stio_dev_sck_read (tcp, 1);
mio_dev_sck_read (tcp, 1);
//stio_dev_sck_timedread (tcp, 1, 1000);
//mio_dev_sck_timedread (tcp, 1, 1000);
}
return 0;
}
static int tcp_sck_on_read (stio_dev_sck_t* tcp, const void* buf, stio_iolen_t len, const stio_sckaddr_t* srcaddr)
static int tcp_sck_on_read (mio_dev_sck_t* tcp, const void* buf, mio_iolen_t len, const mio_sckaddr_t* srcaddr)
{
int n;
@ -218,22 +218,22 @@ static int tcp_sck_on_read (stio_dev_sck_t* tcp, const void* buf, stio_iolen_t l
{
printf ("STREAM DEVICE: EOF RECEIVED...\n");
/* no outstanding request. but EOF */
stio_dev_sck_halt (tcp);
mio_dev_sck_halt (tcp);
return 0;
}
printf ("on read %d\n", (int)len);
{
stio_ntime_t tmout;
mio_ntime_t tmout;
static char a ='A';
char* xxx = malloc (1000000);
memset (xxx, a++ ,1000000);
//return stio_dev_sck_write (tcp, "HELLO", 5, STIO_NULL);
stio_inittime (&tmout, 5, 0);
n = stio_dev_sck_timedwrite (tcp, xxx, 1000000, &tmout, STIO_NULL, STIO_NULL);
//return mio_dev_sck_write (tcp, "HELLO", 5, MIO_NULL);
mio_inittime (&tmout, 5, 0);
n = mio_dev_sck_timedwrite (tcp, xxx, 1000000, &tmout, MIO_NULL, MIO_NULL);
free (xxx);
@ -242,10 +242,10 @@ free (xxx);
printf ("DISABLING READING..............................\n");
stio_dev_sck_read (tcp, 0);
mio_dev_sck_read (tcp, 0);
/* post the write finisher */
n = stio_dev_sck_write (tcp, STIO_NULL, 0, STIO_NULL, STIO_NULL);
n = mio_dev_sck_write (tcp, MIO_NULL, 0, MIO_NULL, MIO_NULL);
if (n <= -1) return -1;
return 0;
@ -255,19 +255,19 @@ printf ("DISABLING READING..............................\n");
/* ========================================================================= */
static void pro_on_close (stio_dev_pro_t* dev, stio_dev_pro_sid_t sid)
static void pro_on_close (mio_dev_pro_t* dev, mio_dev_pro_sid_t sid)
{
printf (">>>>>>>>>>>>> ON CLOSE OF SLAVE %d.\n", sid);
}
static int pro_on_read (stio_dev_pro_t* dev, const void* data, stio_iolen_t dlen, stio_dev_pro_sid_t sid)
static int pro_on_read (mio_dev_pro_t* dev, const void* data, mio_iolen_t dlen, mio_dev_pro_sid_t sid)
{
printf ("PROCESS READ DATA on SLAVE[%d]... [%.*s]\n", (int)sid, (int)dlen, (char*)data);
return 0;
}
static int pro_on_write (stio_dev_pro_t* dev, stio_iolen_t wrlen, void* wrctx)
static int pro_on_write (mio_dev_pro_t* dev, mio_iolen_t wrlen, void* wrctx)
{
printf ("PROCESS WROTE DATA...\n");
return 0;
@ -275,16 +275,16 @@ printf ("PROCESS WROTE DATA...\n");
/* ========================================================================= */
static int arp_sck_on_read (stio_dev_sck_t* dev, const void* data, stio_iolen_t dlen, const stio_sckaddr_t* srcaddr)
static int arp_sck_on_read (mio_dev_sck_t* dev, const void* data, mio_iolen_t dlen, const mio_sckaddr_t* srcaddr)
{
stio_etharp_pkt_t* eap;
mio_etharp_pkt_t* eap;
if (dlen < STIO_SIZEOF(*eap)) return 0; /* drop */
if (dlen < MIO_SIZEOF(*eap)) return 0; /* drop */
eap = (stio_etharp_pkt_t*)data;
eap = (mio_etharp_pkt_t*)data;
printf ("ARP ON IFINDEX %d OPCODE: %d", stio_getsckaddrifindex(srcaddr), ntohs(eap->arphdr.opcode));
printf ("ARP ON IFINDEX %d OPCODE: %d", mio_getsckaddrifindex(srcaddr), ntohs(eap->arphdr.opcode));
printf (" SHA: %02X:%02X:%02X:%02X:%02X:%02X", eap->arppld.sha[0], eap->arppld.sha[1], eap->arppld.sha[2], eap->arppld.sha[3], eap->arppld.sha[4], eap->arppld.sha[5]);
printf (" SPA: %d.%d.%d.%d", eap->arppld.spa[0], eap->arppld.spa[1], eap->arppld.spa[2], eap->arppld.spa[3]);
@ -294,56 +294,56 @@ static int arp_sck_on_read (stio_dev_sck_t* dev, const void* data, stio_iolen_t
return 0;
}
static int arp_sck_on_write (stio_dev_sck_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_sckaddr_t* dstaddr)
static int arp_sck_on_write (mio_dev_sck_t* dev, mio_iolen_t wrlen, void* wrctx, const mio_sckaddr_t* dstaddr)
{
return 0;
}
static void arp_sck_on_disconnect (stio_dev_sck_t* dev)
static void arp_sck_on_disconnect (mio_dev_sck_t* dev)
{
printf ("SHUTTING DOWN ARP SOCKET %d...\n", dev->sck);
}
static int setup_arp_tester (stio_t* stio)
static int setup_arp_tester (mio_t* mio)
{
stio_sckaddr_t ethdst;
stio_etharp_pkt_t etharp;
stio_dev_sck_make_t sck_make;
stio_dev_sck_t* sck;
mio_sckaddr_t ethdst;
mio_etharp_pkt_t etharp;
mio_dev_sck_make_t sck_make;
mio_dev_sck_t* sck;
memset (&sck_make, 0, STIO_SIZEOF(sck_make));
sck_make.type = STIO_DEV_SCK_ARP;
//sck_make.type = STIO_DEV_SCK_ARP_DGRAM;
memset (&sck_make, 0, MIO_SIZEOF(sck_make));
sck_make.type = MIO_DEV_SCK_ARP;
//sck_make.type = MIO_DEV_SCK_ARP_DGRAM;
sck_make.on_write = arp_sck_on_write;
sck_make.on_read = arp_sck_on_read;
sck_make.on_disconnect = arp_sck_on_disconnect;
sck = stio_dev_sck_make (stio, 0, &sck_make);
sck = mio_dev_sck_make (mio, 0, &sck_make);
if (!sck)
{
printf ("Cannot make socket device\n");
return -1;
}
//stio_sckaddr_initforeth (&ethdst, if_nametoindex("enp0s25.3"), (stio_ethaddr_t*)"\xFF\xFF\xFF\xFF\xFF\xFF");
stio_sckaddr_initforeth (&ethdst, if_nametoindex("enp0s25.3"), (stio_ethaddr_t*)"\xAA\xBB\xFF\xCC\xDD\xFF");
//mio_sckaddr_initforeth (&ethdst, if_nametoindex("enp0s25.3"), (mio_ethaddr_t*)"\xFF\xFF\xFF\xFF\xFF\xFF");
mio_sckaddr_initforeth (&ethdst, if_nametoindex("enp0s25.3"), (mio_ethaddr_t*)"\xAA\xBB\xFF\xCC\xDD\xFF");
memset (&etharp, 0, sizeof(etharp));
memcpy (etharp.ethhdr.source, "\xB8\x6B\x23\x9C\x10\x76", STIO_ETHADDR_LEN);
//memcpy (etharp.ethhdr.dest, "\xFF\xFF\xFF\xFF\xFF\xFF", STIO_ETHADDR_LEN);
memcpy (etharp.ethhdr.dest, "\xAA\xBB\xFF\xCC\xDD\xFF", STIO_ETHADDR_LEN);
etharp.ethhdr.proto = STIO_CONST_HTON16(STIO_ETHHDR_PROTO_ARP);
memcpy (etharp.ethhdr.source, "\xB8\x6B\x23\x9C\x10\x76", MIO_ETHADDR_LEN);
//memcpy (etharp.ethhdr.dest, "\xFF\xFF\xFF\xFF\xFF\xFF", MIO_ETHADDR_LEN);
memcpy (etharp.ethhdr.dest, "\xAA\xBB\xFF\xCC\xDD\xFF", MIO_ETHADDR_LEN);
etharp.ethhdr.proto = MIO_CONST_HTON16(MIO_ETHHDR_PROTO_ARP);
etharp.arphdr.htype = STIO_CONST_HTON16(STIO_ARPHDR_HTYPE_ETH);
etharp.arphdr.ptype = STIO_CONST_HTON16(STIO_ARPHDR_PTYPE_IP4);
etharp.arphdr.hlen = STIO_ETHADDR_LEN;
etharp.arphdr.plen = STIO_IP4ADDR_LEN;
etharp.arphdr.opcode = STIO_CONST_HTON16(STIO_ARPHDR_OPCODE_REQUEST);
etharp.arphdr.htype = MIO_CONST_HTON16(MIO_ARPHDR_HTYPE_ETH);
etharp.arphdr.ptype = MIO_CONST_HTON16(MIO_ARPHDR_PTYPE_IP4);
etharp.arphdr.hlen = MIO_ETHADDR_LEN;
etharp.arphdr.plen = MIO_IP4ADDR_LEN;
etharp.arphdr.opcode = MIO_CONST_HTON16(MIO_ARPHDR_OPCODE_REQUEST);
memcpy (etharp.arppld.sha, "\xB8\x6B\x23\x9C\x10\x76", STIO_ETHADDR_LEN);
memcpy (etharp.arppld.sha, "\xB8\x6B\x23\x9C\x10\x76", MIO_ETHADDR_LEN);
if (stio_dev_sck_write (sck, &etharp, sizeof(etharp), NULL, &ethdst) <= -1)
//if (stio_dev_sck_write (sck, &etharp.arphdr, sizeof(etharp) - sizeof(etharp.ethhdr), NULL, &ethaddr) <= -1)
if (mio_dev_sck_write (sck, &etharp, sizeof(etharp), NULL, &ethdst) <= -1)
//if (mio_dev_sck_write (sck, &etharp.arphdr, sizeof(etharp) - sizeof(etharp.ethhdr), NULL, &ethaddr) <= -1)
{
printf ("CANNOT WRITE ARP...\n");
}
@ -356,50 +356,50 @@ static int setup_arp_tester (stio_t* stio)
struct icmpxtn_t
{
stio_uint16_t icmp_seq;
stio_tmridx_t tmout_jobidx;
mio_uint16_t icmp_seq;
mio_tmridx_t tmout_jobidx;
int reply_received;
};
typedef struct icmpxtn_t icmpxtn_t;
static int schedule_icmp_wait (stio_dev_sck_t* dev);
static int schedule_icmp_wait (mio_dev_sck_t* dev);
static void send_icmp (stio_dev_sck_t* dev, stio_uint16_t seq)
static void send_icmp (mio_dev_sck_t* dev, mio_uint16_t seq)
{
stio_sckaddr_t dstaddr;
stio_ip4addr_t ia;
stio_icmphdr_t* icmphdr;
stio_uint8_t buf[512];
mio_sckaddr_t dstaddr;
mio_ip4addr_t ia;
mio_icmphdr_t* icmphdr;
mio_uint8_t buf[512];
inet_pton (AF_INET, "192.168.1.131", &ia);
stio_sckaddr_initforip4 (&dstaddr, 0, &ia);
mio_sckaddr_initforip4 (&dstaddr, 0, &ia);
memset(buf, 0, STIO_SIZEOF(buf));
icmphdr = (stio_icmphdr_t*)buf;
icmphdr->type = STIO_ICMP_ECHO_REQUEST;
icmphdr->u.echo.id = STIO_CONST_HTON16(100);
icmphdr->u.echo.seq = stio_hton16(seq);
memset(buf, 0, MIO_SIZEOF(buf));
icmphdr = (mio_icmphdr_t*)buf;
icmphdr->type = MIO_ICMP_ECHO_REQUEST;
icmphdr->u.echo.id = MIO_CONST_HTON16(100);
icmphdr->u.echo.seq = mio_hton16(seq);
memset (&buf[STIO_SIZEOF(*icmphdr)], 'A', STIO_SIZEOF(buf) - STIO_SIZEOF(*icmphdr));
icmphdr->checksum = stio_checksumip (icmphdr, STIO_SIZEOF(buf));
memset (&buf[MIO_SIZEOF(*icmphdr)], 'A', MIO_SIZEOF(buf) - MIO_SIZEOF(*icmphdr));
icmphdr->checksum = mio_checksumip (icmphdr, MIO_SIZEOF(buf));
if (stio_dev_sck_write (dev, buf, STIO_SIZEOF(buf), NULL, &dstaddr) <= -1)
if (mio_dev_sck_write (dev, buf, MIO_SIZEOF(buf), NULL, &dstaddr) <= -1)
{
printf ("CANNOT WRITE ICMP...\n");
stio_dev_sck_halt (dev);
mio_dev_sck_halt (dev);
}
if (schedule_icmp_wait (dev) <= -1)
{
printf ("CANNOT SCHEDULE ICMP WAIT...\n");
stio_dev_sck_halt (dev);
mio_dev_sck_halt (dev);
}
}
static void on_icmp_due (stio_t* stio, const stio_ntime_t* now, stio_tmrjob_t* tmrjob)
static void on_icmp_due (mio_t* mio, const mio_ntime_t* now, mio_tmrjob_t* tmrjob)
{
stio_dev_sck_t* dev;
mio_dev_sck_t* dev;
icmpxtn_t* icmpxtn;
dev = tmrjob->ctx;
@ -413,64 +413,64 @@ static void on_icmp_due (stio_t* stio, const stio_ntime_t* now, stio_tmrjob_t* t
send_icmp (dev, ++icmpxtn->icmp_seq);
}
static int schedule_icmp_wait (stio_dev_sck_t* dev)
static int schedule_icmp_wait (mio_dev_sck_t* dev)
{
icmpxtn_t* icmpxtn;
stio_tmrjob_t tmrjob;
stio_ntime_t fire_after;
mio_tmrjob_t tmrjob;
mio_ntime_t fire_after;
icmpxtn = (icmpxtn_t*)(dev + 1);
stio_inittime (&fire_after, 2, 0);
mio_inittime (&fire_after, 2, 0);
memset (&tmrjob, 0, STIO_SIZEOF(tmrjob));
memset (&tmrjob, 0, MIO_SIZEOF(tmrjob));
tmrjob.ctx = dev;
stio_gettime (&tmrjob.when);
stio_addtime (&tmrjob.when, &fire_after, &tmrjob.when);
mio_gettime (&tmrjob.when);
mio_addtime (&tmrjob.when, &fire_after, &tmrjob.when);
tmrjob.handler = on_icmp_due;
tmrjob.idxptr = &icmpxtn->tmout_jobidx;
assert (icmpxtn->tmout_jobidx == STIO_TMRIDX_INVALID);
assert (icmpxtn->tmout_jobidx == MIO_TMRIDX_INVALID);
return (stio_instmrjob (dev->stio, &tmrjob) == STIO_TMRIDX_INVALID)? -1: 0;
return (mio_instmrjob (dev->mio, &tmrjob) == MIO_TMRIDX_INVALID)? -1: 0;
}
static int icmp_sck_on_read (stio_dev_sck_t* dev, const void* data, stio_iolen_t dlen, const stio_sckaddr_t* srcaddr)
static int icmp_sck_on_read (mio_dev_sck_t* dev, const void* data, mio_iolen_t dlen, const mio_sckaddr_t* srcaddr)
{
icmpxtn_t* icmpxtn;
stio_iphdr_t* iphdr;
stio_icmphdr_t* icmphdr;
mio_iphdr_t* iphdr;
mio_icmphdr_t* icmphdr;
/* when received, the data contains the IP header.. */
icmpxtn = (icmpxtn_t*)(dev + 1);
if (dlen < STIO_SIZEOF(*iphdr) + STIO_SIZEOF(*icmphdr))
if (dlen < MIO_SIZEOF(*iphdr) + MIO_SIZEOF(*icmphdr))
{
printf ("INVALID ICMP PACKET.. TOO SHORT...%d\n", (int)dlen);
}
else
{
/* TODO: consider IP options... */
iphdr = (stio_iphdr_t*)data;
iphdr = (mio_iphdr_t*)data;
if (iphdr->ihl * 4 + STIO_SIZEOF(*icmphdr) > dlen)
if (iphdr->ihl * 4 + MIO_SIZEOF(*icmphdr) > dlen)
{
printf ("INVALID ICMP PACKET.. WRONG IHL...%d\n", (int)iphdr->ihl * 4);
}
else
{
icmphdr = (stio_icmphdr_t*)((stio_uint8_t*)data + (iphdr->ihl * 4));
icmphdr = (mio_icmphdr_t*)((mio_uint8_t*)data + (iphdr->ihl * 4));
/* TODO: check srcaddr against target */
if (icmphdr->type == STIO_ICMP_ECHO_REPLY &&
stio_ntoh16(icmphdr->u.echo.seq) == icmpxtn->icmp_seq) /* TODO: more check.. echo.id.. */
if (icmphdr->type == MIO_ICMP_ECHO_REPLY &&
mio_ntoh16(icmphdr->u.echo.seq) == icmpxtn->icmp_seq) /* TODO: more check.. echo.id.. */
{
icmpxtn->reply_received = 1;
printf ("ICMP REPLY RECEIVED...ID %d SEQ %d\n", (int)stio_ntoh16(icmphdr->u.echo.id), (int)stio_ntoh16(icmphdr->u.echo.seq));
printf ("ICMP REPLY RECEIVED...ID %d SEQ %d\n", (int)mio_ntoh16(icmphdr->u.echo.id), (int)mio_ntoh16(icmphdr->u.echo.seq));
}
else
{
printf ("GARBAGE ICMP PACKET...LEN %d SEQ %d,%d\n", (int)dlen, (int)icmpxtn->icmp_seq, (int)stio_ntoh16(icmphdr->u.echo.seq));
printf ("GARBAGE ICMP PACKET...LEN %d SEQ %d,%d\n", (int)dlen, (int)icmpxtn->icmp_seq, (int)mio_ntoh16(icmphdr->u.echo.seq));
}
}
}
@ -478,7 +478,7 @@ static int icmp_sck_on_read (stio_dev_sck_t* dev, const void* data, stio_iolen_t
}
static int icmp_sck_on_write (stio_dev_sck_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_sckaddr_t* dstaddr)
static int icmp_sck_on_write (mio_dev_sck_t* dev, mio_iolen_t wrlen, void* wrctx, const mio_sckaddr_t* dstaddr)
{
/*icmpxtn_t* icmpxtn;
@ -487,34 +487,34 @@ static int icmp_sck_on_write (stio_dev_sck_t* dev, stio_iolen_t wrlen, void* wrc
return 0;
}
static void icmp_sck_on_disconnect (stio_dev_sck_t* dev)
static void icmp_sck_on_disconnect (mio_dev_sck_t* dev)
{
icmpxtn_t* icmpxtn;
icmpxtn = (icmpxtn_t*)(dev + 1);
printf ("SHUTTING DOWN ICMP SOCKET %d...\n", dev->sck);
if (icmpxtn->tmout_jobidx != STIO_TMRIDX_INVALID)
if (icmpxtn->tmout_jobidx != MIO_TMRIDX_INVALID)
{
stio_deltmrjob (dev->stio, icmpxtn->tmout_jobidx);
icmpxtn->tmout_jobidx = STIO_TMRIDX_INVALID;
mio_deltmrjob (dev->mio, icmpxtn->tmout_jobidx);
icmpxtn->tmout_jobidx = MIO_TMRIDX_INVALID;
}
}
static int setup_ping4_tester (stio_t* stio)
static int setup_ping4_tester (mio_t* mio)
{
stio_dev_sck_make_t sck_make;
stio_dev_sck_t* sck;
mio_dev_sck_make_t sck_make;
mio_dev_sck_t* sck;
icmpxtn_t* icmpxtn;
memset (&sck_make, 0, STIO_SIZEOF(sck_make));
sck_make.type = STIO_DEV_SCK_ICMP4;
memset (&sck_make, 0, MIO_SIZEOF(sck_make));
sck_make.type = MIO_DEV_SCK_ICMP4;
sck_make.on_write = icmp_sck_on_write;
sck_make.on_read = icmp_sck_on_read;
sck_make.on_disconnect = icmp_sck_on_disconnect;
sck = stio_dev_sck_make (stio, STIO_SIZEOF(icmpxtn_t), &sck_make);
sck = mio_dev_sck_make (mio, MIO_SIZEOF(icmpxtn_t), &sck_make);
if (!sck)
{
printf ("Cannot make ICMP4 socket device\n");
@ -522,10 +522,10 @@ static int setup_ping4_tester (stio_t* stio)
}
icmpxtn = (icmpxtn_t*)(sck + 1);
icmpxtn->tmout_jobidx = STIO_TMRIDX_INVALID;
icmpxtn->tmout_jobidx = MIO_TMRIDX_INVALID;
icmpxtn->icmp_seq = 0;
/*TODO: stio_dev_sck_setbroadcast (sck, 1);*/
/*TODO: mio_dev_sck_setbroadcast (sck, 1);*/
send_icmp (sck, ++icmpxtn->icmp_seq);
@ -535,25 +535,25 @@ static int setup_ping4_tester (stio_t* stio)
/* ========================================================================= */
static stio_t* g_stio;
static mio_t* g_mio;
static void handle_signal (int sig)
{
if (g_stio) stio_stop (g_stio, STIO_STOPREQ_TERMINATION);
if (g_mio) mio_stop (g_mio, MIO_STOPREQ_TERMINATION);
}
int main ()
{
int i;
stio_t* stio;
stio_dev_sck_t* tcp[3];
mio_t* mio;
mio_dev_sck_t* tcp[3];
struct sigaction sigact;
stio_dev_sck_connect_t tcp_conn;
stio_dev_sck_listen_t tcp_lstn;
stio_dev_sck_bind_t tcp_bind;
stio_dev_sck_make_t tcp_make;
mio_dev_sck_connect_t tcp_conn;
mio_dev_sck_listen_t tcp_lstn;
mio_dev_sck_bind_t tcp_bind;
mio_dev_sck_make_t tcp_make;
tcp_server_t* ts;
@ -562,35 +562,35 @@ int main ()
SSL_library_init ();
#endif
stio = stio_open (&mmgr, 0, 512, STIO_NULL);
if (!stio)
mio = mio_open (&mmgr, 0, 512, MIO_NULL);
if (!mio)
{
printf ("Cannot open stio\n");
printf ("Cannot open mio\n");
return -1;
}
g_stio = stio;
g_mio = mio;
memset (&sigact, 0, STIO_SIZEOF(sigact));
memset (&sigact, 0, MIO_SIZEOF(sigact));
sigact.sa_flags = SA_RESTART;
sigact.sa_handler = handle_signal;
sigaction (SIGINT, &sigact, STIO_NULL);
sigaction (SIGINT, &sigact, MIO_NULL);
memset (&sigact, 0, STIO_SIZEOF(sigact));
memset (&sigact, 0, MIO_SIZEOF(sigact));
sigact.sa_handler = SIG_IGN;
sigaction (SIGPIPE, &sigact, STIO_NULL);
sigaction (SIGPIPE, &sigact, MIO_NULL);
/*
memset (&sigact, 0, STIO_SIZEOF(sigact));
memset (&sigact, 0, MIO_SIZEOF(sigact));
sigact.sa_handler = SIG_IGN;
sigaction (SIGCHLD, &sigact, STIO_NULL);
sigaction (SIGCHLD, &sigact, MIO_NULL);
*/
/*memset (&sin, 0, STIO_SIZEOF(sin));
/*memset (&sin, 0, MIO_SIZEOF(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(1234); */
/*
udp = (stio_dev_udp_t*)stio_makedev (stio, STIO_SIZEOF(*udp), &udp_mth, &udp_evcb, &sin);
udp = (mio_dev_udp_t*)mio_makedev (mio, MIO_SIZEOF(*udp), &udp_mth, &udp_evcb, &sin);
if (!udp)
{
printf ("Cannot make udp\n");
@ -598,12 +598,12 @@ int main ()
}
*/
memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make));
tcp_make.type = STIO_DEV_SCK_TCP4;
memset (&tcp_make, 0, MIO_SIZEOF(&tcp_make));
tcp_make.type = MIO_DEV_SCK_TCP4;
tcp_make.on_write = tcp_sck_on_write;
tcp_make.on_read = tcp_sck_on_read;
tcp_make.on_disconnect = tcp_sck_on_disconnect;
tcp[0] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make);
tcp[0] = mio_dev_sck_make (mio, MIO_SIZEOF(tcp_server_t), &tcp_make);
if (!tcp[0])
{
printf ("Cannot make tcp\n");
@ -614,29 +614,29 @@ int main ()
ts->tally = 0;
memset (&tcp_conn, 0, STIO_SIZEOF(tcp_conn));
memset (&tcp_conn, 0, MIO_SIZEOF(tcp_conn));
{
in_addr_t ia = inet_addr("192.168.1.119");
stio_sckaddr_initforip4 (&tcp_conn.remoteaddr, 9999, (stio_ip4addr_t*)&ia);
mio_sckaddr_initforip4 (&tcp_conn.remoteaddr, 9999, (mio_ip4addr_t*)&ia);
}
stio_inittime (&tcp_conn.connect_tmout, 5, 0);
mio_inittime (&tcp_conn.connect_tmout, 5, 0);
tcp_conn.on_connect = tcp_sck_on_connect;
tcp_conn.options = STIO_DEV_SCK_CONNECT_SSL;
if (stio_dev_sck_connect (tcp[0], &tcp_conn) <= -1)
tcp_conn.options = MIO_DEV_SCK_CONNECT_SSL;
if (mio_dev_sck_connect (tcp[0], &tcp_conn) <= -1)
{
printf ("stio_dev_sck_connect() failed....\n");
printf ("mio_dev_sck_connect() failed....\n");
/* carry on regardless of failure */
}
/* -------------------------------------------------------------- */
memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make));
tcp_make.type = STIO_DEV_SCK_TCP4;
memset (&tcp_make, 0, MIO_SIZEOF(&tcp_make));
tcp_make.type = MIO_DEV_SCK_TCP4;
tcp_make.on_write = tcp_sck_on_write;
tcp_make.on_read = tcp_sck_on_read;
tcp_make.on_disconnect = tcp_sck_on_disconnect;
tcp[1] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make);
tcp[1] = mio_dev_sck_make (mio, MIO_SIZEOF(tcp_server_t), &tcp_make);
if (!tcp[1])
{
printf ("Cannot make tcp\n");
@ -645,33 +645,33 @@ int main ()
ts = (tcp_server_t*)(tcp[1] + 1);
ts->tally = 0;
memset (&tcp_bind, 0, STIO_SIZEOF(tcp_bind));
stio_sckaddr_initforip4 (&tcp_bind.localaddr, 1234, STIO_NULL);
tcp_bind.options = STIO_DEV_SCK_BIND_REUSEADDR;
memset (&tcp_bind, 0, MIO_SIZEOF(tcp_bind));
mio_sckaddr_initforip4 (&tcp_bind.localaddr, 1234, MIO_NULL);
tcp_bind.options = MIO_DEV_SCK_BIND_REUSEADDR;
if (stio_dev_sck_bind (tcp[1],&tcp_bind) <= -1)
if (mio_dev_sck_bind (tcp[1],&tcp_bind) <= -1)
{
printf ("stio_dev_sck_bind() failed....\n");
printf ("mio_dev_sck_bind() failed....\n");
goto oops;
}
tcp_lstn.backlogs = 100;
tcp_lstn.on_connect = tcp_sck_on_connect;
if (stio_dev_sck_listen (tcp[1], &tcp_lstn) <= -1)
if (mio_dev_sck_listen (tcp[1], &tcp_lstn) <= -1)
{
printf ("stio_dev_sck_listen() failed....\n");
printf ("mio_dev_sck_listen() failed....\n");
goto oops;
}
/* -------------------------------------------------------------- */
memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make));
tcp_make.type = STIO_DEV_SCK_TCP4;
memset (&tcp_make, 0, MIO_SIZEOF(&tcp_make));
tcp_make.type = MIO_DEV_SCK_TCP4;
tcp_make.on_write = tcp_sck_on_write;
tcp_make.on_read = tcp_sck_on_read;
tcp_make.on_disconnect = tcp_sck_on_disconnect;
tcp[2] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make);
tcp[2] = mio_dev_sck_make (mio, MIO_SIZEOF(tcp_server_t), &tcp_make);
if (!tcp[2])
{
printf ("Cannot make tcp\n");
@ -680,40 +680,40 @@ int main ()
ts = (tcp_server_t*)(tcp[2] + 1);
ts->tally = 0;
memset (&tcp_bind, 0, STIO_SIZEOF(tcp_bind));
stio_sckaddr_initforip4 (&tcp_bind.localaddr, 1235, STIO_NULL);
tcp_bind.options = STIO_DEV_SCK_BIND_REUSEADDR | /*STIO_DEV_SCK_BIND_REUSEPORT |*/ STIO_DEV_SCK_BIND_SSL;
tcp_bind.ssl_certfile = STIO_MT("localhost.crt");
tcp_bind.ssl_keyfile = STIO_MT("localhost.key");
stio_inittime (&tcp_bind.accept_tmout, 5, 1);
memset (&tcp_bind, 0, MIO_SIZEOF(tcp_bind));
mio_sckaddr_initforip4 (&tcp_bind.localaddr, 1235, MIO_NULL);
tcp_bind.options = MIO_DEV_SCK_BIND_REUSEADDR | /*MIO_DEV_SCK_BIND_REUSEPORT |*/ MIO_DEV_SCK_BIND_SSL;
tcp_bind.ssl_certfile = MIO_MT("localhost.crt");
tcp_bind.ssl_keyfile = MIO_MT("localhost.key");
mio_inittime (&tcp_bind.accept_tmout, 5, 1);
if (stio_dev_sck_bind (tcp[2],&tcp_bind) <= -1)
if (mio_dev_sck_bind (tcp[2],&tcp_bind) <= -1)
{
printf ("stio_dev_sck_bind() failed....\n");
printf ("mio_dev_sck_bind() failed....\n");
goto oops;
}
tcp_lstn.backlogs = 100;
tcp_lstn.on_connect = tcp_sck_on_connect;
if (stio_dev_sck_listen (tcp[2], &tcp_lstn) <= -1)
if (mio_dev_sck_listen (tcp[2], &tcp_lstn) <= -1)
{
printf ("stio_dev_sck_listen() failed....\n");
printf ("mio_dev_sck_listen() failed....\n");
goto oops;
}
//stio_dev_sck_sendfile (tcp[2], fd, offset, count);
//mio_dev_sck_sendfile (tcp[2], fd, offset, count);
if (setup_arp_tester(stio) <= -1) goto oops;
if (setup_ping4_tester(stio) <= -1) goto oops;
if (setup_arp_tester(mio) <= -1) goto oops;
if (setup_ping4_tester(mio) <= -1) goto oops;
for (i = 0; i < 5; i++)
{
stio_dev_pro_t* pro;
stio_dev_pro_make_t pro_make;
mio_dev_pro_t* pro;
mio_dev_pro_make_t pro_make;
memset (&pro_make, 0, STIO_SIZEOF(pro_make));
pro_make.flags = STIO_DEV_PRO_READOUT | STIO_DEV_PRO_READERR | STIO_DEV_PRO_WRITEIN /*| STIO_DEV_PRO_FORGET_CHILD*/;
memset (&pro_make, 0, MIO_SIZEOF(pro_make));
pro_make.flags = MIO_DEV_PRO_READOUT | MIO_DEV_PRO_READERR | MIO_DEV_PRO_WRITEIN /*| MIO_DEV_PRO_FORGET_CHILD*/;
//pro_make.cmd = "/bin/ls -laF /usr/bin";
//pro_make.cmd = "/bin/ls -laF";
pro_make.cmd = "./a";
@ -721,24 +721,24 @@ for (i = 0; i < 5; i++)
pro_make.on_write = pro_on_write;
pro_make.on_close = pro_on_close;
pro = stio_dev_pro_make (stio, 0, &pro_make);
pro = mio_dev_pro_make (mio, 0, &pro_make);
if (!pro)
{
printf ("CANNOT CREATE PROCESS PIPE\n");
goto oops;
}
stio_dev_pro_write (pro, "MY STIO LIBRARY\n", 16, STIO_NULL);
//stio_dev_pro_killchild (pro);
//stio_dev_pro_close (pro, STIO_DEV_PRO_IN);
//stio_dev_pro_close (pro, STIO_DEV_PRO_OUT);
//stio_dev_pro_close (pro, STIO_DEV_PRO_ERR);
mio_dev_pro_write (pro, "MY MIO LIBRARY\n", 16, MIO_NULL);
//mio_dev_pro_killchild (pro);
//mio_dev_pro_close (pro, MIO_DEV_PRO_IN);
//mio_dev_pro_close (pro, MIO_DEV_PRO_OUT);
//mio_dev_pro_close (pro, MIO_DEV_PRO_ERR);
}
stio_loop (stio);
mio_loop (mio);
g_stio = STIO_NULL;
stio_close (stio);
g_mio = MIO_NULL;
mio_close (mio);
#if defined(USE_SSL)
cleanup_openssl ();
#endif
@ -746,8 +746,8 @@ for (i = 0; i < 5; i++)
return 0;
oops:
g_stio = STIO_NULL;
stio_close (stio);
g_mio = MIO_NULL;
mio_close (mio);
#if defined(USE_SSL)
cleanup_openssl ();
#endif

569
mio/lib/mio-cmn.h Normal file
View File

@ -0,0 +1,569 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MIO_CMN_H_
#define _MIO_CMN_H_
/* WARNING: NEVER CHANGE/DELETE THE FOLLOWING MIO_HAVE_CFG_H DEFINITION.
* IT IS USED FOR DEPLOYMENT BY MAKEFILE.AM */
/*#define MIO_HAVE_CFG_H*/
#if defined(MIO_HAVE_CFG_H)
# include "mio-cfg.h"
#elif defined(_WIN32)
# include "mio-msw.h"
#elif defined(__OS2__)
# include "mio-os2.h"
#elif defined(__MSDOS__)
# include "mio-dos.h"
#elif defined(macintosh)
# include "mio-mac.h" /* class mac os */
#else
# error UNSUPPORTED SYSTEM
#endif
#if defined(EMSCRIPTEN)
# if defined(MIO_SIZEOF___INT128)
# undef MIO_SIZEOF___INT128
# define MIO_SIZEOF___INT128 0
# endif
# if defined(MIO_SIZEOF_LONG) && defined(MIO_SIZEOF_INT) && (MIO_SIZEOF_LONG > MIO_SIZEOF_INT)
/* autoconf doesn't seem to match actual emscripten */
# undef MIO_SIZEOF_LONG
# define MIO_SIZEOF_LONG MIO_SIZEOF_INT
# endif
#endif
/* =========================================================================
* PRIMITIVE TYPE DEFINTIONS
* ========================================================================= */
/* mio_int8_t */
#if defined(MIO_SIZEOF_CHAR) && (MIO_SIZEOF_CHAR == 1)
# define MIO_HAVE_UINT8_T
# define MIO_HAVE_INT8_T
typedef unsigned char mio_uint8_t;
typedef signed char mio_int8_t;
#elif defined(MIO_SIZEOF___INT8) && (MIO_SIZEOF___INT8 == 1)
# define MIO_HAVE_UINT8_T
# define MIO_HAVE_INT8_T
typedef unsigned __int8 mio_uint8_t;
typedef signed __int8 mio_int8_t;
#elif defined(MIO_SIZEOF___INT8_T) && (MIO_SIZEOF___INT8_T == 1)
# define MIO_HAVE_UINT8_T
# define MIO_HAVE_INT8_T
typedef unsigned __int8_t mio_uint8_t;
typedef signed __int8_t mio_int8_t;
#else
# define MIO_HAVE_UINT8_T
# define MIO_HAVE_INT8_T
typedef unsigned char mio_uint8_t;
typedef signed char mio_int8_t;
#endif
/* mio_int16_t */
#if defined(MIO_SIZEOF_SHORT) && (MIO_SIZEOF_SHORT == 2)
# define MIO_HAVE_UINT16_T
# define MIO_HAVE_INT16_T
typedef unsigned short int mio_uint16_t;
typedef signed short int mio_int16_t;
#elif defined(MIO_SIZEOF___INT16) && (MIO_SIZEOF___INT16 == 2)
# define MIO_HAVE_UINT16_T
# define MIO_HAVE_INT16_T
typedef unsigned __int16 mio_uint16_t;
typedef signed __int16 mio_int16_t;
#elif defined(MIO_SIZEOF___INT16_T) && (MIO_SIZEOF___INT16_T == 2)
# define MIO_HAVE_UINT16_T
# define MIO_HAVE_INT16_T
typedef unsigned __int16_t mio_uint16_t;
typedef signed __int16_t mio_int16_t;
#else
# define MIO_HAVE_UINT16_T
# define MIO_HAVE_INT16_T
typedef unsigned short int mio_uint16_t;
typedef signed short int mio_int16_t;
#endif
/* mio_int32_t */
#if defined(MIO_SIZEOF_INT) && (MIO_SIZEOF_INT == 4)
# define MIO_HAVE_UINT32_T
# define MIO_HAVE_INT32_T
typedef unsigned int mio_uint32_t;
typedef signed int mio_int32_t;
#elif defined(MIO_SIZEOF_LONG) && (MIO_SIZEOF_LONG == 4)
# define MIO_HAVE_UINT32_T
# define MIO_HAVE_INT32_T
typedef unsigned long mio_uint32_t;
typedef signed long mio_int32_t;
#elif defined(MIO_SIZEOF___INT32) && (MIO_SIZEOF___INT32 == 4)
# define MIO_HAVE_UINT32_T
# define MIO_HAVE_INT32_T
typedef unsigned __int32 mio_uint32_t;
typedef signed __int32 mio_int32_t;
#elif defined(MIO_SIZEOF___INT32_T) && (MIO_SIZEOF___INT32_T == 4)
# define MIO_HAVE_UINT32_T
# define MIO_HAVE_INT32_T
typedef unsigned __int32_t mio_uint32_t;
typedef signed __int32_t mio_int32_t;
#elif defined(__MSDOS__)
# define MIO_HAVE_UINT32_T
# define MIO_HAVE_INT32_T
typedef unsigned long int mio_uint32_t;
typedef signed long int mio_int32_t;
#else
# define MIO_HAVE_UINT32_T
# define MIO_HAVE_INT32_T
typedef unsigned int mio_uint32_t;
typedef signed int mio_int32_t;
#endif
/* mio_int64_t */
#if defined(MIO_SIZEOF_INT) && (MIO_SIZEOF_INT == 8)
# define MIO_HAVE_UINT64_T
# define MIO_HAVE_INT64_T
typedef unsigned int mio_uint64_t;
typedef signed int mio_int64_t;
#elif defined(MIO_SIZEOF_LONG) && (MIO_SIZEOF_LONG == 8)
# define MIO_HAVE_UINT64_T
# define MIO_HAVE_INT64_T
typedef unsigned long mio_uint64_t;
typedef signed long mio_int64_t;
#elif defined(MIO_SIZEOF_LONG_LONG) && (MIO_SIZEOF_LONG_LONG == 8)
# define MIO_HAVE_UINT64_T
# define MIO_HAVE_INT64_T
typedef unsigned long long mio_uint64_t;
typedef signed long long mio_int64_t;
#elif defined(MIO_SIZEOF___INT64) && (MIO_SIZEOF___INT64 == 8)
# define MIO_HAVE_UINT64_T
# define MIO_HAVE_INT64_T
typedef unsigned __int64 mio_uint64_t;
typedef signed __int64 mio_int64_t;
#elif defined(MIO_SIZEOF___INT64_T) && (MIO_SIZEOF___INT64_T == 8)
# define MIO_HAVE_UINT64_T
# define MIO_HAVE_INT64_T
typedef unsigned __int64_t mio_uint64_t;
typedef signed __int64_t mio_int64_t;
#elif defined(_WIN64) || defined(_WIN32)
# define MIO_HAVE_UINT64_T
# define MIO_HAVE_INT64_T
typedef unsigned __int64 mio_uint64_t;
typedef signed __int64 mio_int64_t;
#else
/* no 64-bit integer */
#endif
/* mio_int128_t */
#if defined(MIO_SIZEOF_INT) && (MIO_SIZEOF_INT == 16)
# define MIO_HAVE_UINT128_T
# define MIO_HAVE_INT128_T
typedef unsigned int mio_uint128_t;
typedef signed int mio_int128_t;
#elif defined(MIO_SIZEOF_LONG) && (MIO_SIZEOF_LONG == 16)
# define MIO_HAVE_UINT128_T
# define MIO_HAVE_INT128_T
typedef unsigned long mio_uint128_t;
typedef signed long mio_int128_t;
#elif defined(MIO_SIZEOF_LONG_LONG) && (MIO_SIZEOF_LONG_LONG == 16)
# define MIO_HAVE_UINT128_T
# define MIO_HAVE_INT128_T
typedef unsigned long long mio_uint128_t;
typedef signed long long mio_int128_t;
#elif defined(MIO_SIZEOF___INT128) && (MIO_SIZEOF___INT128 == 16)
# define MIO_HAVE_UINT128_T
# define MIO_HAVE_INT128_T
typedef unsigned __int128 mio_uint128_t;
typedef signed __int128 mio_int128_t;
#elif defined(MIO_SIZEOF___INT128_T) && (MIO_SIZEOF___INT128_T == 16)
# define MIO_HAVE_UINT128_T
# define MIO_HAVE_INT128_T
#if defined(__clang__)
typedef __uint128_t mio_uint128_t;
typedef __int128_t mio_int128_t;
#else
typedef unsigned __int128_t mio_uint128_t;
typedef signed __int128_t mio_int128_t;
#endif
#else
/* no 128-bit integer */
#endif
#if defined(MIO_HAVE_UINT8_T) && (MIO_SIZEOF_VOID_P == 1)
# error UNSUPPORTED POINTER SIZE
#elif defined(MIO_HAVE_UINT16_T) && (MIO_SIZEOF_VOID_P == 2)
typedef mio_uint16_t mio_uintptr_t;
typedef mio_int16_t mio_intptr_t;
typedef mio_uint8_t mio_ushortptr_t;
typedef mio_int8_t mio_shortptr_t;
#elif defined(MIO_HAVE_UINT32_T) && (MIO_SIZEOF_VOID_P == 4)
typedef mio_uint32_t mio_uintptr_t;
typedef mio_int32_t mio_intptr_t;
typedef mio_uint16_t mio_ushortptr_t;
typedef mio_int16_t mio_shortptr_t;
#elif defined(MIO_HAVE_UINT64_T) && (MIO_SIZEOF_VOID_P == 8)
typedef mio_uint64_t mio_uintptr_t;
typedef mio_int64_t mio_intptr_t;
typedef mio_uint32_t mio_ushortptr_t;
typedef mio_int32_t mio_shortptr_t;
#elif defined(MIO_HAVE_UINT128_T) && (MIO_SIZEOF_VOID_P == 16)
typedef mio_uint128_t mio_uintptr_t;
typedef mio_int128_t mio_intptr_t;
typedef mio_uint64_t mio_ushortptr_t;
typedef mio_int64_t mio_shortptr_t;
#else
# error UNKNOWN POINTER SIZE
#endif
#define MIO_SIZEOF_INTPTR_T MIO_SIZEOF_VOID_P
#define MIO_SIZEOF_UINTPTR_T MIO_SIZEOF_VOID_P
#define MIO_SIZEOF_SHORTPTR_T (MIO_SIZEOF_VOID_P / 2)
#define MIO_SIZEOF_USHORTPTR_T (MIO_SIZEOF_VOID_P / 2)
#if defined(MIO_HAVE_INT128_T)
# define MIO_SIZEOF_INTMAX_T 16
# define MIO_SIZEOF_UINTMAX_T 16
typedef mio_int128_t mio_intmax_t;
typedef mio_uint128_t mio_uintmax_t;
#elif defined(MIO_HAVE_INT64_T)
# define MIO_SIZEOF_INTMAX_T 8
# define MIO_SIZEOF_UINTMAX_T 8
typedef mio_int64_t mio_intmax_t;
typedef mio_uint64_t mio_uintmax_t;
#elif defined(MIO_HAVE_INT32_T)
# define MIO_SIZEOF_INTMAX_T 4
# define MIO_SIZEOF_UINTMAX_T 4
typedef mio_int32_t mio_intmax_t;
typedef mio_uint32_t mio_uintmax_t;
#elif defined(MIO_HAVE_INT16_T)
# define MIO_SIZEOF_INTMAX_T 2
# define MIO_SIZEOF_UINTMAX_T 2
typedef mio_int16_t mio_intmax_t;
typedef mio_uint16_t mio_uintmax_t;
#elif defined(MIO_HAVE_INT8_T)
# define MIO_SIZEOF_INTMAX_T 1
# define MIO_SIZEOF_UINTMAX_T 1
typedef mio_int8_t mio_intmax_t;
typedef mio_uint8_t mio_uintmax_t;
#else
# error UNKNOWN INTMAX SIZE
#endif
/* =========================================================================
* BASIC MIO TYPES
* =========================================================================*/
typedef mio_uint8_t mio_byte_t;
typedef mio_uintptr_t mio_size_t;
typedef char mio_mchar_t;
typedef int mio_mcint_t;
#define MIO_MT(x) (x)
/* =========================================================================
* PRIMITIVE MACROS
* ========================================================================= */
#define MIO_SIZEOF(x) (sizeof(x))
#define MIO_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
/**
* The MIO_OFFSETOF() macro returns the offset of a field from the beginning
* of a structure.
*/
#define MIO_OFFSETOF(type,member) ((mio_uintptr_t)&((type*)0)->member)
/**
* The MIO_ALIGNOF() macro returns the alignment size of a structure.
* Note that this macro may not work reliably depending on the type given.
*/
#define MIO_ALIGNOF(type) MIO_OFFSETOF(struct { mio_uint8_t d1; type d2; }, d2)
/*(sizeof(struct { mio_uint8_t d1; type d2; }) - sizeof(type))*/
/**
* Round up a positive integer to the nearest multiple of 'align'
*/
#define MIO_ALIGNTO(num,align) ((((num) + (align) - 1) / (align)) * (align))
#if 0
/**
* Round up a number, both positive and negative, to the nearest multiple of 'align'
*/
#define MIO_ALIGNTO(num,align) ((((num) + (num >= 0? 1: -1) * (align) - 1) / (align)) * (align))
#endif
/**
* Round up a positive integer to to the nearest multiple of 'align' which
* should be a multiple of a power of 2
*/
#define MIO_ALIGNTO_POW2(num,align) ((((num) + (align) - 1)) & ~((align) - 1))
#if defined(__cplusplus)
# if (__cplusplus >= 201103L) /* C++11 */
# define MIO_NULL nullptr
# else
# define MIO_NULL (0)
# endif
#else
# define MIO_NULL ((void*)0)
#endif
/* make a bit mask that can mask off low n bits */
#define MIO_LBMASK(type,n) (~(~((type)0) << (n)))
#define MIO_LBMASK_SAFE(type,n) (((n) < MIO_SIZEOF(type) * 8)? MIO_LBMASK(type,n): ~(type)0)
/* make a bit mask that can mask off hig n bits */
#define MIO_HBMASK(type,n) (~(~((type)0) >> (n)))
#define MIO_HBMASK_SAFE(type,n) (((n) < MIO_SIZEOF(type) * 8)? MIO_HBMASK(type,n): ~(type)0)
/* get 'length' bits starting from the bit at the 'offset' */
#define MIO_GETBITS(type,value,offset,length) \
((((type)(value)) >> (offset)) & MIO_LBMASK(type,length))
#define MIO_SETBITS(type,value,offset,length,bits) \
(value = (((type)(value)) | (((bits) & MIO_LBMASK(type,length)) << (offset))))
/**
* The MIO_BITS_MAX() macros calculates the maximum value that the 'nbits'
* bits of an unsigned integer of the given 'type' can hold.
* \code
* printf ("%u", MIO_BITS_MAX(unsigned int, 5));
* \endcode
*/
/*#define MIO_BITS_MAX(type,nbits) ((((type)1) << (nbits)) - 1)*/
#define MIO_BITS_MAX(type,nbits) ((~(type)0) >> (MIO_SIZEOF(type) * 8 - (nbits)))
/* =========================================================================
* MMGR
* ========================================================================= */
typedef struct mio_mmgr_t mio_mmgr_t;
/**
* allocate a memory chunk of the size \a n.
* \return pointer to a memory chunk on success, #MIO_NULL on failure.
*/
typedef void* (*mio_mmgr_alloc_t) (mio_mmgr_t* mmgr, mio_size_t n);
/**
* resize a memory chunk pointed to by \a ptr to the size \a n.
* \return pointer to a memory chunk on success, #MIO_NULL on failure.
*/
typedef void* (*mio_mmgr_realloc_t) (mio_mmgr_t* mmgr, void* ptr, mio_size_t n);
/**
* free a memory chunk pointed to by \a ptr.
*/
typedef void (*mio_mmgr_free_t) (mio_mmgr_t* mmgr, void* ptr);
/**
* The mio_mmgr_t type defines the memory management interface.
* As the type is merely a structure, it is just used as a single container
* for memory management functions with a pointer to user-defined data.
* The user-defined data pointer \a ctx is passed to each memory management
* function whenever it is called. You can allocate, reallocate, and free
* a memory chunk.
*
* For example, a mio_xxx_open() function accepts a pointer of the mio_mmgr_t
* type and the xxx object uses it to manage dynamic data within the object.
*/
struct mio_mmgr_t
{
mio_mmgr_alloc_t alloc; /**< allocation function */
mio_mmgr_realloc_t realloc; /**< resizing function */
mio_mmgr_free_t free; /**< disposal function */
void* ctx; /**< user-defined data pointer */
};
/**
* The MIO_MMGR_ALLOC() macro allocates a memory block of the \a size bytes
* using the \a mmgr memory manager.
*/
#define MIO_MMGR_ALLOC(mmgr,size) ((mmgr)->alloc(mmgr,size))
/**
* The MIO_MMGR_REALLOC() macro resizes a memory block pointed to by \a ptr
* to the \a size bytes using the \a mmgr memory manager.
*/
#define MIO_MMGR_REALLOC(mmgr,ptr,size) ((mmgr)->realloc(mmgr,ptr,size))
/**
* The MIO_MMGR_FREE() macro deallocates the memory block pointed to by \a ptr.
*/
#define MIO_MMGR_FREE(mmgr,ptr) ((mmgr)->free(mmgr,ptr))
/* =========================================================================
* MACROS THAT CHANGES THE BEHAVIORS OF THE C COMPILER/LINKER
* =========================================================================*/
#if defined(_WIN32) || (defined(__WATCOMC__) && !defined(__WINDOWS_386__))
# define MIO_IMPORT __declspec(dllimport)
# define MIO_EXPORT __declspec(dllexport)
# define MIO_PRIVATE
#elif defined(__GNUC__) && (__GNUC__>=4)
# define MIO_IMPORT __attribute__((visibility("default")))
# define MIO_EXPORT __attribute__((visibility("default")))
# define MIO_PRIVATE __attribute__((visibility("hidden")))
/*# define MIO_PRIVATE __attribute__((visibility("internal")))*/
#else
# define MIO_IMPORT
# define MIO_EXPORT
# define MIO_PRIVATE
#endif
#if defined(__STDC_VERSION__) && (__STDC_VERSION__>=199901L)
# define MIO_INLINE inline
# define MIO_HAVE_INLINE
#elif defined(__GNUC__) && defined(__GNUC_GNU_INLINE__)
/* gcc disables inline when -std=c89 or -ansi is used.
* so use __inline__ supported by gcc regardless of the options */
# define MIO_INLINE /*extern*/ __inline__
# define MIO_HAVE_INLINE
#else
# define MIO_INLINE
# undef MIO_HAVE_INLINE
#endif
/**
* The MIO_TYPE_IS_SIGNED() macro determines if a type is signed.
* \code
* printf ("%d\n", (int)MIO_TYPE_IS_SIGNED(int));
* printf ("%d\n", (int)MIO_TYPE_IS_SIGNED(unsigned int));
* \endcode
*/
#define MIO_TYPE_IS_SIGNED(type) (((type)0) > ((type)-1))
/**
* The MIO_TYPE_IS_SIGNED() macro determines if a type is unsigned.
* \code
* printf ("%d\n", MIO_TYPE_IS_UNSIGNED(int));
* printf ("%d\n", MIO_TYPE_IS_UNSIGNED(unsigned int));
* \endcode
*/
#define MIO_TYPE_IS_UNSIGNED(type) (((type)0) < ((type)-1))
#define MIO_TYPE_SIGNED_MAX(type) \
((type)~((type)1 << ((type)MIO_SIZEOF(type) * 8 - 1)))
#define MIO_TYPE_UNSIGNED_MAX(type) ((type)(~(type)0))
#define MIO_TYPE_SIGNED_MIN(type) \
((type)((type)1 << ((type)MIO_SIZEOF(type) * 8 - 1)))
#define MIO_TYPE_UNSIGNED_MIN(type) ((type)0)
#define MIO_TYPE_MAX(type) \
((MIO_TYPE_IS_SIGNED(type)? MIO_TYPE_SIGNED_MAX(type): MIO_TYPE_UNSIGNED_MAX(type)))
#define MIO_TYPE_MIN(type) \
((MIO_TYPE_IS_SIGNED(type)? MIO_TYPE_SIGNED_MIN(type): MIO_TYPE_UNSIGNED_MIN(type)))
/* =========================================================================
* COMPILER FEATURE TEST MACROS
* =========================================================================*/
#if defined(__has_builtin)
#if __has_builtin(__builtin_ctz)
#define MIO_HAVE_BUILTIN_CTZ
#endif
#if __has_builtin(__builtin_uadd_overflow)
#define MIO_HAVE_BUILTIN_UADD_OVERFLOW
#endif
#if __has_builtin(__builtin_uaddl_overflow)
#define MIO_HAVE_BUILTIN_UADDL_OVERFLOW
#endif
#if __has_builtin(__builtin_uaddll_overflow)
#define MIO_HAVE_BUILTIN_UADDLL_OVERFLOW
#endif
#if __has_builtin(__builtin_umul_overflow)
#define MIO_HAVE_BUILTIN_UMUL_OVERFLOW
#endif
#if __has_builtin(__builtin_umull_overflow)
#define MIO_HAVE_BUILTIN_UMULL_OVERFLOW
#endif
#if __has_builtin(__builtin_umulll_overflow)
#define MIO_HAVE_BUILTIN_UMULLL_OVERFLOW
#endif
#if __has_builtin(__builtin_sadd_overflow)
#define MIO_HAVE_BUILTIN_SADD_OVERFLOW
#endif
#if __has_builtin(__builtin_saddl_overflow)
#define MIO_HAVE_BUILTIN_SADDL_OVERFLOW
#endif
#if __has_builtin(__builtin_saddll_overflow)
#define MIO_HAVE_BUILTIN_SADDLL_OVERFLOW
#endif
#if __has_builtin(__builtin_smul_overflow)
#define MIO_HAVE_BUILTIN_SMUL_OVERFLOW
#endif
#if __has_builtin(__builtin_smull_overflow)
#define MIO_HAVE_BUILTIN_SMULL_OVERFLOW
#endif
#if __has_builtin(__builtin_smulll_overflow)
#define MIO_HAVE_BUILTIN_SMULLL_OVERFLOW
#endif
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#define MIO_HAVE_BUILTIN_CTZ
#endif
#if (__GNUC__ >= 5)
#define MIO_HAVE_BUILTIN_UADD_OVERFLOW
#define MIO_HAVE_BUILTIN_UADDL_OVERFLOW
#define MIO_HAVE_BUILTIN_UADDLL_OVERFLOW
#define MIO_HAVE_BUILTIN_UMUL_OVERFLOW
#define MIO_HAVE_BUILTIN_UMULL_OVERFLOW
#define MIO_HAVE_BUILTIN_UMULLL_OVERFLOW
#define MIO_HAVE_BUILTIN_SADD_OVERFLOW
#define MIO_HAVE_BUILTIN_SADDL_OVERFLOW
#define MIO_HAVE_BUILTIN_SADDLL_OVERFLOW
#define MIO_HAVE_BUILTIN_SMUL_OVERFLOW
#define MIO_HAVE_BUILTIN_SMULL_OVERFLOW
#define MIO_HAVE_BUILTIN_SMULLL_OVERFLOW
#endif
#endif
/*
#if !defined(__has_builtin)
#define __has_builtin(x) 0
#endif
#if !defined(__is_identifier)
#define __is_identifier(x) 0
#endif
#if !defined(__has_attribute)
#define __has_attribute(x) 0
#endif
*/
#endif

846
mio/lib/mio-pro.c Normal file
View File

@ -0,0 +1,846 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mio-pro.h"
#include "mio-prv.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>
/* ========================================================================= */
struct slave_info_t
{
mio_dev_pro_make_t* mi;
mio_syshnd_t pfd;
int dev_capa;
mio_dev_pro_sid_t id;
};
typedef struct slave_info_t slave_info_t;
static mio_dev_pro_slave_t* make_slave (mio_t* mio, slave_info_t* si);
/* ========================================================================= */
struct param_t
{
mio_mchar_t* mcmd;
mio_mchar_t* fixed_argv[4];
mio_mchar_t** argv;
};
typedef struct param_t param_t;
static void free_param (mio_t* mio, param_t* param)
{
if (param->argv && param->argv != param->fixed_argv)
MIO_MMGR_FREE (mio->mmgr, param->argv);
if (param->mcmd) MIO_MMGR_FREE (mio->mmgr, param->mcmd);
MIO_MEMSET (param, 0, MIO_SIZEOF(*param));
}
static int make_param (mio_t* mio, const mio_mchar_t* cmd, int flags, param_t* param)
{
int fcnt = 0;
mio_mchar_t* mcmd = MIO_NULL;
MIO_MEMSET (param, 0, MIO_SIZEOF(*param));
if (flags & MIO_DEV_PRO_SHELL)
{
mcmd = (mio_mchar_t*)cmd;
param->argv = param->fixed_argv;
param->argv[0] = MIO_MT("/bin/sh");
param->argv[1] = MIO_MT("-c");
param->argv[2] = mcmd;
param->argv[3] = MIO_NULL;
}
else
{
int i;
mio_mchar_t** argv;
mio_mchar_t* mcmdptr;
mcmd = mio_mbsdup (mio, cmd);
if (!mcmd) goto oops;
fcnt = mio_mbsspl (mcmd, MIO_MT(""), MIO_MT('\"'), MIO_MT('\"'), MIO_MT('\\'));
if (fcnt <= 0)
{
/* no field or an error */
mio->errnum = MIO_EINVAL;
goto oops;
}
if (fcnt < MIO_COUNTOF(param->fixed_argv))
{
param->argv = param->fixed_argv;
}
else
{
param->argv = MIO_MMGR_ALLOC (mio->mmgr, (fcnt + 1) * MIO_SIZEOF(argv[0]));
if (param->argv == MIO_NULL)
{
mio->errnum = MIO_ENOMEM;
goto oops;
}
}
mcmdptr = mcmd;
for (i = 0; i < fcnt; i++)
{
param->argv[i] = mcmdptr;
while (*mcmdptr != MIO_MT('\0')) mcmdptr++;
mcmdptr++;
}
param->argv[i] = MIO_NULL;
}
if (mcmd && mcmd != (mio_mchar_t*)cmd) param->mcmd = mcmd;
return 0;
oops:
if (mcmd && mcmd != cmd) MIO_MMGR_FREE (mio->mmgr, mcmd);
return -1;
}
static pid_t standard_fork_and_exec (mio_t* mio, int pfds[], int flags, param_t* param)
{
pid_t pid;
pid = fork ();
if (pid == -1)
{
mio->errnum = mio_syserrtoerrnum(errno);
return -1;
}
if (pid == 0)
{
/* slave process */
mio_syshnd_t devnull = MIO_SYSHND_INVALID;
/* TODO: close all uneeded fds */
if (flags & MIO_DEV_PRO_WRITEIN)
{
/* slave should read */
close (pfds[1]);
pfds[1] = MIO_SYSHND_INVALID;
/* let the pipe be standard input */
if (dup2 (pfds[0], 0) <= -1) goto slave_oops;
close (pfds[0]);
pfds[0] = MIO_SYSHND_INVALID;
}
if (flags & MIO_DEV_PRO_READOUT)
{
/* slave should write */
close (pfds[2]);
pfds[2] = MIO_SYSHND_INVALID;
if (dup2(pfds[3], 1) == -1) goto slave_oops;
if (flags & MIO_DEV_PRO_ERRTOOUT)
{
if (dup2(pfds[3], 2) == -1) goto slave_oops;
}
close (pfds[3]);
pfds[3] = MIO_SYSHND_INVALID;
}
if (flags & MIO_DEV_PRO_READERR)
{
close (pfds[4]);
pfds[4] = MIO_SYSHND_INVALID;
if (dup2(pfds[5], 2) == -1) goto slave_oops;
if (flags & MIO_DEV_PRO_OUTTOERR)
{
if (dup2(pfds[5], 1) == -1) goto slave_oops;
}
close (pfds[5]);
pfds[5] = MIO_SYSHND_INVALID;
}
if ((flags & MIO_DEV_PRO_INTONUL) ||
(flags & MIO_DEV_PRO_OUTTONUL) ||
(flags & MIO_DEV_PRO_ERRTONUL))
{
#if defined(O_LARGEFILE)
devnull = open (MIO_MT("/dev/null"), O_RDWR | O_LARGEFILE, 0);
#else
devnull = open (MIO_MT("/dev/null"), O_RDWR, 0);
#endif
if (devnull == MIO_SYSHND_INVALID) goto slave_oops;
}
execv (param->argv[0], param->argv);
/* if exec fails, free 'param' parameter which is an inherited pointer */
free_param (mio, param);
slave_oops:
if (devnull != MIO_SYSHND_INVALID) close(devnull);
_exit (128);
}
/* parent process */
return pid;
}
static int dev_pro_make_master (mio_dev_t* dev, void* ctx)
{
mio_dev_pro_t* rdev = (mio_dev_pro_t*)dev;
mio_dev_pro_make_t* info = (mio_dev_pro_make_t*)ctx;
mio_syshnd_t pfds[6];
int i, minidx = -1, maxidx = -1;
param_t param;
pid_t pid;
if (info->flags & MIO_DEV_PRO_WRITEIN)
{
if (pipe(&pfds[0]) == -1)
{
dev->mio->errnum = mio_syserrtoerrnum(errno);
goto oops;
}
minidx = 0; maxidx = 1;
}
if (info->flags & MIO_DEV_PRO_READOUT)
{
if (pipe(&pfds[2]) == -1)
{
dev->mio->errnum = mio_syserrtoerrnum(errno);
goto oops;
}
if (minidx == -1) minidx = 2;
maxidx = 3;
}
if (info->flags & MIO_DEV_PRO_READERR)
{
if (pipe(&pfds[4]) == -1)
{
dev->mio->errnum = mio_syserrtoerrnum(errno);
goto oops;
}
if (minidx == -1) minidx = 4;
maxidx = 5;
}
if (maxidx == -1)
{
dev->mio->errnum = MIO_EINVAL;
goto oops;
}
if (make_param (rdev->mio, info->cmd, info->flags, &param) <= -1) goto oops;
/* TODO: more advanced fork and exec .. */
pid = standard_fork_and_exec (rdev->mio, pfds, info->flags, &param);
if (pid <= -1)
{
free_param (rdev->mio, &param);
goto oops;
}
free_param (rdev->mio, &param);
rdev->child_pid = pid;
/* this is the parent process */
if (info->flags & MIO_DEV_PRO_WRITEIN)
{
/*
* 012345
* rw----
* X
* WRITE => 1
*/
close (pfds[0]);
pfds[0] = MIO_SYSHND_INVALID;
if (mio_makesyshndasync (dev->mio, pfds[1]) <= -1) goto oops;
}
if (info->flags & MIO_DEV_PRO_READOUT)
{
/*
* 012345
* --rw--
* X
* READ => 2
*/
close (pfds[3]);
pfds[3] = MIO_SYSHND_INVALID;
if (mio_makesyshndasync (dev->mio, pfds[2]) <= -1) goto oops;
}
if (info->flags & MIO_DEV_PRO_READERR)
{
/*
* 012345
* ----rw
* X
* READ => 4
*/
close (pfds[5]);
pfds[5] = MIO_SYSHND_INVALID;
if (mio_makesyshndasync (dev->mio, pfds[4]) <= -1) goto oops;
}
if (pfds[1] != MIO_SYSHND_INVALID)
{
/* hand over pfds[2] to the first slave device */
slave_info_t si;
si.mi = info;
si.pfd = pfds[1];
si.dev_capa = MIO_DEV_CAPA_OUT | MIO_DEV_CAPA_OUT_QUEUED | MIO_DEV_CAPA_STREAM;
si.id = MIO_DEV_PRO_IN;
rdev->slave[MIO_DEV_PRO_IN] = make_slave (dev->mio, &si);
if (!rdev->slave[MIO_DEV_PRO_IN]) goto oops;
pfds[1] = MIO_SYSHND_INVALID;
rdev->slave_count++;
}
if (pfds[2] != MIO_SYSHND_INVALID)
{
/* hand over pfds[2] to the first slave device */
slave_info_t si;
si.mi = info;
si.pfd = pfds[2];
si.dev_capa = MIO_DEV_CAPA_IN | MIO_DEV_CAPA_STREAM;
si.id = MIO_DEV_PRO_OUT;
rdev->slave[MIO_DEV_PRO_OUT] = make_slave (dev->mio, &si);
if (!rdev->slave[MIO_DEV_PRO_OUT]) goto oops;
pfds[2] = MIO_SYSHND_INVALID;
rdev->slave_count++;
}
if (pfds[4] != MIO_SYSHND_INVALID)
{
/* hand over pfds[4] to the second slave device */
slave_info_t si;
si.mi = info;
si.pfd = pfds[4];
si.dev_capa = MIO_DEV_CAPA_IN | MIO_DEV_CAPA_STREAM;
si.id = MIO_DEV_PRO_ERR;
rdev->slave[MIO_DEV_PRO_ERR] = make_slave (dev->mio, &si);
if (!rdev->slave[MIO_DEV_PRO_ERR]) goto oops;
pfds[4] = MIO_SYSHND_INVALID;
rdev->slave_count++;
}
for (i = 0; i < MIO_COUNTOF(rdev->slave); i++)
{
if (rdev->slave[i]) rdev->slave[i]->master = rdev;
}
rdev->dev_capa = MIO_DEV_CAPA_VIRTUAL; /* the master device doesn't perform I/O */
rdev->flags = info->flags;
rdev->on_read = info->on_read;
rdev->on_write = info->on_write;
rdev->on_close = info->on_close;
return 0;
oops:
for (i = minidx; i < maxidx; i++)
{
if (pfds[i] != MIO_SYSHND_INVALID) close (pfds[i]);
}
if (rdev->mcmd)
{
MIO_MMGR_FREE (rdev->mio->mmgr, rdev->mcmd);
free_param (rdev->mio, &param);
}
for (i = MIO_COUNTOF(rdev->slave); i > 0; )
{
i--;
if (rdev->slave[i])
{
mio_killdev (rdev->mio, (mio_dev_t*)rdev->slave[i]);
rdev->slave[i] = MIO_NULL;
}
}
rdev->slave_count = 0;
return -1;
}
static int dev_pro_make_slave (mio_dev_t* dev, void* ctx)
{
mio_dev_pro_slave_t* rdev = (mio_dev_pro_slave_t*)dev;
slave_info_t* si = (slave_info_t*)ctx;
rdev->dev_capa = si->dev_capa;
rdev->id = si->id;
rdev->pfd = si->pfd;
/* keep rdev->master to MIO_NULL. it's set to the right master
* device in dev_pro_make() */
return 0;
}
static int dev_pro_kill_master (mio_dev_t* dev, int force)
{
mio_dev_pro_t* rdev = (mio_dev_pro_t*)dev;
int i, status;
pid_t wpid;
if (rdev->slave_count > 0)
{
for (i = 0; i < MIO_COUNTOF(rdev->slave); i++)
{
if (rdev->slave[i])
{
mio_dev_pro_slave_t* sdev = rdev->slave[i];
/* nullify the pointer to the slave device
* before calling mio_killdev() on the slave device.
* the slave device can check this pointer to tell from
* self-initiated termination or master-driven termination */
rdev->slave[i] = MIO_NULL;
mio_killdev (rdev->mio, (mio_dev_t*)sdev);
}
}
}
if (rdev->child_pid >= 0)
{
if (!(rdev->flags & MIO_DEV_PRO_FORGET_CHILD))
{
int killed = 0;
await_child:
wpid = waitpid (rdev->child_pid, &status, WNOHANG);
if (wpid == 0)
{
if (force && !killed)
{
if (!(rdev->flags & MIO_DEV_PRO_FORGET_DIEHARD_CHILD))
{
kill (rdev->child_pid, SIGKILL);
killed = 1;
goto await_child;
}
}
else
{
/* child process is still alive */
rdev->mio->errnum = MIO_EAGAIN;
return -1; /* call me again */
}
}
/* wpid == rdev->child_pid => full success
* wpid == -1 && errno == ECHILD => no such process. it's waitpid()'ed by some other part of the program?
* other cases ==> can't really handle properly. forget it by returning success
* no need not worry about EINTR because errno can't have the value when WNOHANG is set.
*/
}
printf (">>>>>>>>>>>>>>>>>>> REAPED CHILD %d\n", (int)rdev->child_pid);
rdev->child_pid = -1;
}
if (rdev->on_close) rdev->on_close (rdev, MIO_DEV_PRO_MASTER);
return 0;
}
static int dev_pro_kill_slave (mio_dev_t* dev, int force)
{
mio_dev_pro_slave_t* rdev = (mio_dev_pro_slave_t*)dev;
if (rdev->master)
{
mio_dev_pro_t* master;
master = rdev->master;
rdev->master = MIO_NULL;
/* indicate EOF */
if (master->on_close) master->on_close (master, rdev->id);
MIO_ASSERT (master->slave_count > 0);
master->slave_count--;
if (master->slave[rdev->id])
{
/* this call is started by the slave device itself.
* if this is the last slave, kill the master also */
if (master->slave_count <= 0)
{
mio_killdev (rdev->mio, (mio_dev_t*)master);
/* the master pointer is not valid from this point onwards
* as the actual master device object is freed in mio_killdev() */
}
}
else
{
/* this call is initiated by this slave device itself.
* if it were by the master device, it would be MIO_NULL as
* nullified by the dev_pro_kill() */
master->slave[rdev->id] = MIO_NULL;
}
}
if (rdev->pfd != MIO_SYSHND_INVALID)
{
close (rdev->pfd);
rdev->pfd = MIO_SYSHND_INVALID;
}
return 0;
}
static int dev_pro_read_slave (mio_dev_t* dev, void* buf, mio_iolen_t* len, mio_devaddr_t* srcaddr)
{
mio_dev_pro_slave_t* pro = (mio_dev_pro_slave_t*)dev;
ssize_t x;
x = read (pro->pfd, buf, *len);
if (x <= -1)
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data available */
if (errno == EINTR) return 0;
pro->mio->errnum = mio_syserrtoerrnum(errno);
return -1;
}
*len = x;
return 1;
}
static int dev_pro_write_slave (mio_dev_t* dev, const void* data, mio_iolen_t* len, const mio_devaddr_t* dstaddr)
{
mio_dev_pro_slave_t* pro = (mio_dev_pro_slave_t*)dev;
ssize_t x;
x = write (pro->pfd, data, *len);
if (x <= -1)
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */
if (errno == EINTR) return 0;
pro->mio->errnum = mio_syserrtoerrnum(errno);
return -1;
}
*len = x;
return 1;
}
static mio_syshnd_t dev_pro_getsyshnd (mio_dev_t* dev)
{
return MIO_SYSHND_INVALID;
}
static mio_syshnd_t dev_pro_getsyshnd_slave (mio_dev_t* dev)
{
mio_dev_pro_slave_t* pro = (mio_dev_pro_slave_t*)dev;
return (mio_syshnd_t)pro->pfd;
}
static int dev_pro_ioctl (mio_dev_t* dev, int cmd, void* arg)
{
mio_dev_pro_t* rdev = (mio_dev_pro_t*)dev;
switch (cmd)
{
case MIO_DEV_PRO_CLOSE:
{
mio_dev_pro_sid_t sid = *(mio_dev_pro_sid_t*)arg;
if (sid < MIO_DEV_PRO_IN || sid > MIO_DEV_PRO_ERR)
{
rdev->mio->errnum = MIO_EINVAL;
return -1;
}
if (rdev->slave[sid])
{
/* unlike dev_pro_kill_master(), i don't nullify rdev->slave[sid].
* so i treat the closing ioctl as if it's a kill request
* initiated by the slave device itself. */
mio_killdev (rdev->mio, (mio_dev_t*)rdev->slave[sid]);
}
return 0;
}
case MIO_DEV_PRO_KILL_CHILD:
if (rdev->child_pid >= 0)
{
if (kill (rdev->child_pid, SIGKILL) == -1)
{
rdev->mio->errnum = mio_syserrtoerrnum(errno);
return -1;
}
}
return 0;
default:
dev->mio->errnum = MIO_EINVAL;
return -1;
}
}
static mio_dev_mth_t dev_pro_methods =
{
dev_pro_make_master,
dev_pro_kill_master,
dev_pro_getsyshnd,
MIO_NULL,
MIO_NULL,
dev_pro_ioctl
};
static mio_dev_mth_t dev_pro_methods_slave =
{
dev_pro_make_slave,
dev_pro_kill_slave,
dev_pro_getsyshnd_slave,
dev_pro_read_slave,
dev_pro_write_slave,
dev_pro_ioctl
};
/* ========================================================================= */
static int pro_ready (mio_dev_t* dev, int events)
{
/* virtual device. no I/O */
dev->mio->errnum = MIO_EINTERN;
return -1;
}
static int pro_on_read (mio_dev_t* dev, const void* data, mio_iolen_t len, const mio_devaddr_t* srcaddr)
{
/* virtual device. no I/O */
dev->mio->errnum = MIO_EINTERN;
return -1;
}
static int pro_on_write (mio_dev_t* dev, mio_iolen_t wrlen, void* wrctx, const mio_devaddr_t* dstaddr)
{
/* virtual device. no I/O */
dev->mio->errnum = MIO_EINTERN;
return -1;
}
static mio_dev_evcb_t dev_pro_event_callbacks =
{
pro_ready,
pro_on_read,
pro_on_write
};
/* ========================================================================= */
static int pro_ready_slave (mio_dev_t* dev, int events)
{
mio_dev_pro_t* pro = (mio_dev_pro_t*)dev;
if (events & MIO_DEV_EVENT_ERR)
{
pro->mio->errnum = MIO_EDEVERR;
return -1;
}
if (events & MIO_DEV_EVENT_HUP)
{
if (events & (MIO_DEV_EVENT_PRI | MIO_DEV_EVENT_IN | MIO_DEV_EVENT_OUT))
{
/* probably half-open? */
return 1;
}
pro->mio->errnum = MIO_EDEVHUP;
return -1;
}
return 1; /* the device is ok. carry on reading or writing */
}
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);
}
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);
}
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);
}
static mio_dev_evcb_t dev_pro_event_callbacks_slave_in =
{
pro_ready_slave,
MIO_NULL,
pro_on_write_slave
};
static mio_dev_evcb_t dev_pro_event_callbacks_slave_out =
{
pro_ready_slave,
pro_on_read_slave_out,
MIO_NULL
};
static mio_dev_evcb_t dev_pro_event_callbacks_slave_err =
{
pro_ready_slave,
pro_on_read_slave_err,
MIO_NULL
};
/* ========================================================================= */
static mio_dev_pro_slave_t* make_slave (mio_t* mio, slave_info_t* si)
{
switch (si->id)
{
case MIO_DEV_PRO_IN:
return (mio_dev_pro_slave_t*)mio_makedev (
mio, MIO_SIZEOF(mio_dev_pro_t),
&dev_pro_methods_slave, &dev_pro_event_callbacks_slave_in, si);
case MIO_DEV_PRO_OUT:
return (mio_dev_pro_slave_t*)mio_makedev (
mio, MIO_SIZEOF(mio_dev_pro_t),
&dev_pro_methods_slave, &dev_pro_event_callbacks_slave_out, si);
case MIO_DEV_PRO_ERR:
return (mio_dev_pro_slave_t*)mio_makedev (
mio, MIO_SIZEOF(mio_dev_pro_t),
&dev_pro_methods_slave, &dev_pro_event_callbacks_slave_err, si);
default:
mio->errnum = MIO_EINVAL;
return MIO_NULL;
}
}
mio_dev_pro_t* mio_dev_pro_make (mio_t* mio, mio_size_t xtnsize, const mio_dev_pro_make_t* info)
{
return (mio_dev_pro_t*)mio_makedev (
mio, MIO_SIZEOF(mio_dev_pro_t) + xtnsize,
&dev_pro_methods, &dev_pro_event_callbacks, (void*)info);
}
void mio_dev_pro_kill (mio_dev_pro_t* dev)
{
mio_killdev (dev->mio, (mio_dev_t*)dev);
}
int mio_dev_pro_write (mio_dev_pro_t* dev, const void* data, mio_iolen_t dlen, void* wrctx)
{
if (dev->slave[0])
{
return mio_dev_write ((mio_dev_t*)dev->slave[0], data, dlen, wrctx, MIO_NULL);
}
else
{
dev->mio->errnum = MIO_ENOCAPA; /* TODO: is it the right error number? */
return -1;
}
}
int mio_dev_pro_timedwrite (mio_dev_pro_t* dev, const void* data, mio_iolen_t dlen, const mio_ntime_t* tmout, void* wrctx)
{
if (dev->slave[0])
{
return mio_dev_timedwrite ((mio_dev_t*)dev->slave[0], data, dlen, tmout, wrctx, MIO_NULL);
}
else
{
dev->mio->errnum = 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);
}
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);
}
#if 0
mio_dev_pro_t* mio_dev_pro_getdev (mio_dev_pro_t* pro, mio_dev_pro_sid_t sid)
{
switch (type)
{
case MIO_DEV_PRO_IN:
return XXX;
case MIO_DEV_PRO_OUT:
return XXX;
case MIO_DEV_PRO_ERR:
return XXX;
}
pro->dev->mio = MIO_EINVAL;
return MIO_NULL;
}
#endif

164
mio/lib/mio-pro.h Normal file
View File

@ -0,0 +1,164 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MIO_PRO_H_
#define _MIO_PRO_H_
#include <mio.h>
enum mio_dev_pro_sid_t
{
MIO_DEV_PRO_MASTER = -1,
MIO_DEV_PRO_IN = 0,
MIO_DEV_PRO_OUT = 1,
MIO_DEV_PRO_ERR = 2
};
typedef enum mio_dev_pro_sid_t mio_dev_pro_sid_t;
typedef struct mio_dev_pro_t mio_dev_pro_t;
typedef struct mio_dev_pro_slave_t mio_dev_pro_slave_t;
typedef int (*mio_dev_pro_on_read_t) (mio_dev_pro_t* dev, const void* data, mio_iolen_t len, mio_dev_pro_sid_t sid);
typedef int (*mio_dev_pro_on_write_t) (mio_dev_pro_t* dev, mio_iolen_t wrlen, void* wrctx);
typedef void (*mio_dev_pro_on_close_t) (mio_dev_pro_t* dev, mio_dev_pro_sid_t sid);
struct mio_dev_pro_t
{
MIO_DEV_HEADERS;
int flags;
mio_intptr_t child_pid;
mio_dev_pro_slave_t* slave[3];
int slave_count;
mio_dev_pro_on_read_t on_read;
mio_dev_pro_on_write_t on_write;
mio_dev_pro_on_close_t on_close;
mio_mchar_t* mcmd;
};
struct mio_dev_pro_slave_t
{
MIO_DEV_HEADERS;
mio_dev_pro_sid_t id;
mio_syshnd_t pfd;
mio_dev_pro_t* master; /* parent device */
};
enum mio_dev_pro_make_flag_t
{
MIO_DEV_PRO_WRITEIN = (1 << 0),
MIO_DEV_PRO_READOUT = (1 << 1),
MIO_DEV_PRO_READERR = (1 << 2),
MIO_DEV_PRO_ERRTOOUT = (1 << 3),
MIO_DEV_PRO_OUTTOERR = (1 << 4),
MIO_DEV_PRO_INTONUL = (1 << 5),
MIO_DEV_PRO_OUTTONUL = (1 << 6),
MIO_DEV_PRO_ERRTONUL = (1 << 7),
STUO_DEV_PRO_DROPIN = (1 << 8),
STUO_DEV_PRO_DROPOUT = (1 << 9),
STUO_DEV_PRO_DROPERR = (1 << 10),
MIO_DEV_PRO_SHELL = (1 << 13),
/* perform no waitpid() on a child process upon device destruction.
* you should set this flag if your application has automatic child
* process reaping enabled. for instance, SIGCHLD is set to SIG_IGN
* on POSIX.1-2001 compliant systems */
MIO_DEV_PRO_FORGET_CHILD = (1 << 14),
MIO_DEV_PRO_FORGET_DIEHARD_CHILD = (1 << 15)
};
typedef enum mio_dev_pro_make_flag_t mio_dev_pro_make_flag_t;
typedef struct mio_dev_pro_make_t mio_dev_pro_make_t;
struct mio_dev_pro_make_t
{
int flags; /**< bitwise-ORed of mio_dev_pro_make_flag_t enumerators */
const void* cmd;
mio_dev_pro_on_write_t on_write; /* mandatory */
mio_dev_pro_on_read_t on_read; /* mandatory */
mio_dev_pro_on_close_t on_close; /* optional */
};
enum mio_dev_pro_ioctl_cmd_t
{
MIO_DEV_PRO_CLOSE,
MIO_DEV_PRO_KILL_CHILD
};
typedef enum mio_dev_pro_ioctl_cmd_t mio_dev_pro_ioctl_cmd_t;
#ifdef __cplusplus
extern "C" {
#endif
MIO_EXPORT mio_dev_pro_t* mio_dev_pro_make (
mio_t* mio,
mio_size_t xtnsize,
const mio_dev_pro_make_t* data
);
MIO_EXPORT void mio_dev_pro_kill (
mio_dev_pro_t* pro
);
MIO_EXPORT int mio_dev_pro_write (
mio_dev_pro_t* pro,
const void* data,
mio_iolen_t len,
void* wrctx
);
MIO_EXPORT int mio_dev_pro_timedwrite (
mio_dev_pro_t* pro,
const void* data,
mio_iolen_t len,
const mio_ntime_t* tmout,
void* wrctx
);
MIO_EXPORT int mio_dev_pro_close (
mio_dev_pro_t* pro,
mio_dev_pro_sid_t sid
);
MIO_EXPORT int mio_dev_pro_killchild (
mio_dev_pro_t* pro
);
#ifdef __cplusplus
}
#endif
#endif

204
mio/lib/mio-prv.h Normal file
View File

@ -0,0 +1,204 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MIO_PRV_H_
#define _MIO_PRV_H_
#include "mio.h"
/*TODO: redefine and remove these */
#include <assert.h>
#include <string.h>
#include <stdio.h>
/*TODO: redefine these */
#define MIO_MEMSET(dst,byte,count) memset(dst,byte,count)
#define MIO_MEMCPY(dst,src,count) memcpy(dst,src,count)
#define MIO_MEMMOVE(dst,src,count) memmove(dst,src,count)
#define MIO_MEMCMP(dst,src,count) memcmp(dst,src,count)
#define MIO_ASSERT assert
typedef struct mio_mux_t mio_mux_t;
struct mio_t
{
mio_mmgr_t* mmgr;
mio_errnum_t errnum;
mio_stopreq_t stopreq; /* stop request to abort mio_loop() */
struct
{
mio_dev_t* head;
mio_dev_t* tail;
} actdev; /* active devices */
struct
{
mio_dev_t* head;
mio_dev_t* tail;
} hltdev; /* halted devices */
struct
{
mio_dev_t* head;
mio_dev_t* tail;
} zmbdev; /* zombie devices */
mio_uint8_t bigbuf[65535]; /* TODO: make this dynamic depending on devices added. device may indicate a buffer size required??? */
unsigned int renew_watch: 1;
unsigned int in_exec: 1;
struct
{
mio_size_t capa;
mio_size_t size;
mio_tmrjob_t* jobs;
} tmr;
/* platform specific fields below */
#if defined(_WIN32)
HANDLE iocp;
#else
mio_mux_t* mux;
#endif
};
#define MIO_EPOCH_YEAR (1970)
#define MIO_EPOCH_MON (1)
#define MIO_EPOCH_DAY (1)
#define MIO_EPOCH_WDAY (4)
/* windows specific epoch time */
#define MIO_EPOCH_YEAR_WIN (1601)
#define MIO_EPOCH_MON_WIN (1)
#define MIO_EPOCH_DAY_WIN (1)
#define MIO_DAYS_PER_WEEK (7)
#define MIO_MONS_PER_YEAR (12)
#define MIO_HOURS_PER_DAY (24)
#define MIO_MINS_PER_HOUR (60)
#define MIO_MINS_PER_DAY (MIO_MINS_PER_HOUR*MIO_HOURS_PER_DAY)
#define MIO_SECS_PER_MIN (60)
#define MIO_SECS_PER_HOUR (MIO_SECS_PER_MIN*MIO_MINS_PER_HOUR)
#define MIO_SECS_PER_DAY (MIO_SECS_PER_MIN*MIO_MINS_PER_DAY)
#define MIO_MSECS_PER_SEC (1000)
#define MIO_MSECS_PER_MIN (MIO_MSECS_PER_SEC*MIO_SECS_PER_MIN)
#define MIO_MSECS_PER_HOUR (MIO_MSECS_PER_SEC*MIO_SECS_PER_HOUR)
#define MIO_MSECS_PER_DAY (MIO_MSECS_PER_SEC*MIO_SECS_PER_DAY)
#define MIO_USECS_PER_MSEC (1000)
#define MIO_NSECS_PER_USEC (1000)
#define MIO_NSECS_PER_MSEC (MIO_NSECS_PER_USEC*MIO_USECS_PER_MSEC)
#define MIO_USECS_PER_SEC (MIO_USECS_PER_MSEC*MIO_MSECS_PER_SEC)
#define MIO_NSECS_PER_SEC (MIO_NSECS_PER_USEC*MIO_USECS_PER_MSEC*MIO_MSECS_PER_SEC)
#define MIO_SECNSEC_TO_MSEC(sec,nsec) \
(((mio_intptr_t)(sec) * MIO_MSECS_PER_SEC) + ((mio_intptr_t)(nsec) / MIO_NSECS_PER_MSEC))
#define MIO_SECNSEC_TO_USEC(sec,nsec) \
(((mio_intptr_t)(sec) * MIO_USECS_PER_SEC) + ((mio_intptr_t)(nsec) / MIO_NSECS_PER_USEC))
#define MIO_SEC_TO_MSEC(sec) ((sec) * MIO_MSECS_PER_SEC)
#define MIO_MSEC_TO_SEC(sec) ((sec) / MIO_MSECS_PER_SEC)
#define MIO_USEC_TO_NSEC(usec) ((usec) * MIO_NSECS_PER_USEC)
#define MIO_NSEC_TO_USEC(nsec) ((nsec) / MIO_NSECS_PER_USEC)
#define MIO_MSEC_TO_NSEC(msec) ((msec) * MIO_NSECS_PER_MSEC)
#define MIO_NSEC_TO_MSEC(nsec) ((nsec) / MIO_NSECS_PER_MSEC)
#define MIO_SEC_TO_NSEC(sec) ((sec) * MIO_NSECS_PER_SEC)
#define MIO_NSEC_TO_SEC(nsec) ((nsec) / MIO_NSECS_PER_SEC)
#define MIO_SEC_TO_USEC(sec) ((sec) * MIO_USECS_PER_SEC)
#define MIO_USEC_TO_SEC(usec) ((usec) / MIO_USECS_PER_SEC)
#ifdef __cplusplus
extern "C" {
#endif
int mio_makesyshndasync (
mio_t* mio,
mio_syshnd_t hnd
);
mio_errnum_t mio_syserrtoerrnum (
int no
);
mio_mchar_t* mio_mbsdup (
mio_t* mio,
const mio_mchar_t* src
);
mio_size_t mio_mbscpy (
mio_mchar_t* buf,
const mio_mchar_t* str
);
int mio_mbsspltrn (
mio_mchar_t* s,
const mio_mchar_t* delim,
mio_mchar_t lquote,
mio_mchar_t rquote,
mio_mchar_t escape,
const mio_mchar_t* trset
);
int mio_mbsspl (
mio_mchar_t* s,
const mio_mchar_t* delim,
mio_mchar_t lquote,
mio_mchar_t rquote,
mio_mchar_t escape
);
void mio_cleartmrjobs (
mio_t* mio
);
void mio_firetmrjobs (
mio_t* mio,
const mio_ntime_t* tmbase,
mio_size_t* firecnt
);
int mio_gettmrtmout (
mio_t* mio,
const mio_ntime_t* tmbase,
mio_ntime_t* tmout
);
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

600
mio/lib/mio-sck.h Normal file
View File

@ -0,0 +1,600 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MIO_SCK_H_
#define _MIO_SCK_H_
#include <mio.h>
/* ========================================================================= */
/* TOOD: move these to a separte file */
#define MIO_ETHHDR_PROTO_IP4 0x0800
#define MIO_ETHHDR_PROTO_ARP 0x0806
#define MIO_ETHHDR_PROTO_8021Q 0x8100 /* 802.1Q VLAN */
#define MIO_ETHHDR_PROTO_IP6 0x86DD
#define MIO_ARPHDR_OPCODE_REQUEST 1
#define MIO_ARPHDR_OPCODE_REPLY 2
#define MIO_ARPHDR_HTYPE_ETH 0x0001
#define MIO_ARPHDR_PTYPE_IP4 0x0800
#define MIO_ETHADDR_LEN 6
#define MIO_IP4ADDR_LEN 4
#define MIO_IP6ADDR_LEN 16
#if defined(__GNUC__)
# define MIO_PACKED __attribute__((__packed__))
#else
# define MIO_PACKED
# MIO_PACK_PUSH pack(push)
# MIO_PACK_PUSH pack(push)
# MIO_PACK(x) pack(x)
#endif
#if defined(__GNUC__)
/* nothing */
#else
#pragma pack(push)
#pragma pack(1)
#endif
struct MIO_PACKED mio_ethaddr_t
{
mio_uint8_t v[MIO_ETHADDR_LEN];
};
typedef struct mio_ethaddr_t mio_ethaddr_t;
struct MIO_PACKED mio_ip4addr_t
{
mio_uint8_t v[MIO_IP4ADDR_LEN];
};
typedef struct mio_ip4addr_t mio_ip4addr_t;
struct MIO_PACKED mio_ip6addr_t
{
mio_uint8_t v[MIO_IP6ADDR_LEN];
};
typedef struct mio_ip6addr_t mio_ip6addr_t;
struct MIO_PACKED mio_ethhdr_t
{
mio_uint8_t dest[MIO_ETHADDR_LEN];
mio_uint8_t source[MIO_ETHADDR_LEN];
mio_uint16_t proto;
};
typedef struct mio_ethhdr_t mio_ethhdr_t;
struct MIO_PACKED mio_arphdr_t
{
mio_uint16_t htype; /* hardware type (ethernet: 0x0001) */
mio_uint16_t ptype; /* protocol type (ipv4: 0x0800) */
mio_uint8_t hlen; /* hardware address length (ethernet: 6) */
mio_uint8_t plen; /* protocol address length (ipv4 :4) */
mio_uint16_t opcode; /* operation code */
};
typedef struct mio_arphdr_t mio_arphdr_t;
/* arp payload for ipv4 over ethernet */
struct MIO_PACKED mio_etharp_t
{
mio_uint8_t sha[MIO_ETHADDR_LEN]; /* source hardware address */
mio_uint8_t spa[MIO_IP4ADDR_LEN]; /* source protocol address */
mio_uint8_t tha[MIO_ETHADDR_LEN]; /* target hardware address */
mio_uint8_t tpa[MIO_IP4ADDR_LEN]; /* target protocol address */
};
typedef struct mio_etharp_t mio_etharp_t;
struct MIO_PACKED mio_etharp_pkt_t
{
mio_ethhdr_t ethhdr;
mio_arphdr_t arphdr;
mio_etharp_t arppld;
};
typedef struct mio_etharp_pkt_t mio_etharp_pkt_t;
struct mio_iphdr_t
{
#if defined(MIO_ENDIAN_LITTLE)
mio_uint8_t ihl:4;
mio_uint8_t version:4;
#elif defined(MIO_ENDIAN_BIG)
mio_uint8_t version:4;
mio_uint8_t ihl:4;
#else
# UNSUPPORTED ENDIAN
#endif
mio_int8_t tos;
mio_int16_t tot_len;
mio_int16_t id;
mio_int16_t frag_off;
mio_int8_t ttl;
mio_int8_t protocol;
mio_int16_t check;
mio_int32_t saddr;
mio_int32_t daddr;
/*The options start here. */
};
typedef struct mio_iphdr_t mio_iphdr_t;
struct MIO_PACKED mio_icmphdr_t
{
mio_uint8_t type; /* message type */
mio_uint8_t code; /* subcode */
mio_uint16_t checksum;
union
{
struct
{
mio_uint16_t id;
mio_uint16_t seq;
} echo;
mio_uint32_t gateway;
struct
{
mio_uint16_t frag_unused;
mio_uint16_t mtu;
} frag; /* path mut discovery */
} u;
};
typedef struct mio_icmphdr_t mio_icmphdr_t;
#if defined(__GNUC__)
/* nothing */
#else
#pragma pack(pop)
#endif
/* ICMP types */
#define MIO_ICMP_ECHO_REPLY 0
#define MIO_ICMP_UNREACH 3 /* destination unreachable */
#define MIO_ICMP_SOURCE_QUENCE 4
#define MIO_ICMP_REDIRECT 5
#define MIO_ICMP_ECHO_REQUEST 8
#define MIO_ICMP_TIME_EXCEEDED 11
#define MIO_ICMP_PARAM_PROBLEM 12
#define MIO_ICMP_TIMESTAMP_REQUEST 13
#define MIO_ICMP_TIMESTAMP_REPLY 14
#define MIO_ICMP_INFO_REQUEST 15
#define MIO_ICMP_INFO_REPLY 16
#define MIO_ICMP_ADDR_MASK_REQUEST 17
#define MIO_ICMP_ADDR_MASK_REPLY 18
/* Subcode for MIO_ICMP_UNREACH */
#define MIO_ICMP_UNREACH_NET 0
#define MIO_ICMP_UNREACH_HOST 1
#define MIO_ICMP_UNREACH_PROTOCOL 2
#define MIO_ICMP_UNREACH_PORT 3
#define MIO_ICMP_UNREACH_FRAG_NEEDED 4
/* Subcode for MIO_ICMP_REDIRECT */
#define MIO_ICMP_REDIRECT_NET 0
#define MIO_ICMP_REDIRECT_HOST 1
#define MIO_ICMP_REDIRECT_NETTOS 2
#define MIO_ICMP_REDIRECT_HOSTTOS 3
/* Subcode for MIO_ICMP_TIME_EXCEEDED */
#define MIO_ICMP_TIME_EXCEEDED_TTL 0
#define MIO_ICMP_TIME_EXCEEDED_FRAGTIME 1
/* ========================================================================= */
typedef int mio_sckfam_t;
struct mio_sckaddr_t
{
mio_sckfam_t family;
mio_uint8_t data[128]; /* TODO: use the actual sockaddr size */
};
typedef struct mio_sckaddr_t mio_sckaddr_t;
#if (MIO_SIZEOF_SOCKLEN_T == MIO_SIZEOF_INT)
#if defined(MIO_SOCKLEN_T_IS_SIGNED)
typedef int mio_scklen_t;
#else
typedef unsigned int mio_scklen_t;
#endif
#elif (MIO_SIZEOF_SOCKLEN_T == MIO_SIZEOF_LONG)
#if defined(MIO_SOCKLEN_T_IS_SIGNED)
typedef long mio_scklen_t;
#else
typedef unsigned long mio_scklen_t;
#endif
#else
typedef int mio_scklen_t;
#endif
#if defined(_WIN32)
# define MIO_IOCP_KEY 1
/*
typedef HANDLE mio_syshnd_t;
typedef SOCKET mio_sckhnd_t;
# define MIO_SCKHND_INVALID (INVALID_SOCKET)
*/
typedef mio_uintptr_t qse_sckhnd_t;
# define MIO_SCKHND_INVALID (~(qse_sck_hnd_t)0)
#else
typedef int mio_sckhnd_t;
# define MIO_SCKHND_INVALID (-1)
#endif
/* ========================================================================= */
enum mio_dev_sck_ioctl_cmd_t
{
MIO_DEV_SCK_BIND,
MIO_DEV_SCK_CONNECT,
MIO_DEV_SCK_LISTEN
};
typedef enum mio_dev_sck_ioctl_cmd_t mio_dev_sck_ioctl_cmd_t;
#define MIO_DEV_SCK_SET_PROGRESS(dev,bit) do { \
(dev)->state &= ~MIO_DEV_SCK_ALL_PROGRESS_BITS; \
(dev)->state |= (bit); \
} while(0)
#define MIO_DEV_SCK_GET_PROGRESS(dev) ((dev)->state & MIO_DEV_SCK_ALL_PROGRESS_BITS)
enum mio_dev_sck_state_t
{
/* the following items(progress bits) are mutually exclusive */
MIO_DEV_SCK_CONNECTING = (1 << 0),
MIO_DEV_SCK_CONNECTING_SSL = (1 << 1),
MIO_DEV_SCK_CONNECTED = (1 << 2),
MIO_DEV_SCK_LISTENING = (1 << 3),
MIO_DEV_SCK_ACCEPTING_SSL = (1 << 4),
MIO_DEV_SCK_ACCEPTED = (1 << 5),
/* the following items can be bitwise-ORed with an exclusive item above */
MIO_DEV_SCK_INTERCEPTED = (1 << 15),
/* convenience bit masks */
MIO_DEV_SCK_ALL_PROGRESS_BITS = (MIO_DEV_SCK_CONNECTING |
MIO_DEV_SCK_CONNECTING_SSL |
MIO_DEV_SCK_CONNECTED |
MIO_DEV_SCK_LISTENING |
MIO_DEV_SCK_ACCEPTING_SSL |
MIO_DEV_SCK_ACCEPTED)
};
typedef enum mio_dev_sck_state_t mio_dev_sck_state_t;
typedef struct mio_dev_sck_t mio_dev_sck_t;
typedef int (*mio_dev_sck_on_read_t) (
mio_dev_sck_t* dev,
const void* data,
mio_iolen_t dlen,
const mio_sckaddr_t* srcaddr
);
typedef int (*mio_dev_sck_on_write_t) (
mio_dev_sck_t* dev,
mio_iolen_t wrlen,
void* wrctx,
const mio_sckaddr_t* dstaddr
);
typedef void (*mio_dev_sck_on_disconnect_t) (
mio_dev_sck_t* dev
);
typedef int (*mio_dev_sck_on_connect_t) (
mio_dev_sck_t* dev
);
enum mio_dev_sck_type_t
{
MIO_DEV_SCK_TCP4,
MIO_DEV_SCK_TCP6,
MIO_DEV_SCK_UPD4,
MIO_DEV_SCK_UDP6,
/* ARP at the ethernet layer */
MIO_DEV_SCK_ARP,
MIO_DEV_SCK_ARP_DGRAM,
/* ICMP at the IPv4 layer */
MIO_DEV_SCK_ICMP4,
/* ICMP at the IPv6 layer */
MIO_DEV_SCK_ICMP6
#if 0
MIO_DEV_SCK_RAW, /* raw L2-level packet */
#endif
};
typedef enum mio_dev_sck_type_t mio_dev_sck_type_t;
typedef struct mio_dev_sck_make_t mio_dev_sck_make_t;
struct mio_dev_sck_make_t
{
mio_dev_sck_type_t type;
mio_dev_sck_on_write_t on_write;
mio_dev_sck_on_read_t on_read;
mio_dev_sck_on_disconnect_t on_disconnect;
};
enum mio_dev_sck_bind_option_t
{
MIO_DEV_SCK_BIND_BROADCAST = (1 << 0),
MIO_DEV_SCK_BIND_REUSEADDR = (1 << 1),
MIO_DEV_SCK_BIND_REUSEPORT = (1 << 2),
MIO_DEV_SCK_BIND_TRANSPARENT = (1 << 3),
/* TODO: more options --- SO_RCVBUF, SO_SNDBUF, SO_RCVTIMEO, SO_SNDTIMEO, SO_KEEPALIVE */
/* BINDTODEVICE??? */
MIO_DEV_SCK_BIND_SSL = (1 << 15)
};
typedef enum mio_dev_sck_bind_option_t mio_dev_sck_bind_option_t;
typedef struct mio_dev_sck_bind_t mio_dev_sck_bind_t;
struct mio_dev_sck_bind_t
{
int options;
mio_sckaddr_t localaddr;
/* TODO: add device name for BIND_TO_DEVICE */
const mio_mchar_t* ssl_certfile;
const mio_mchar_t* ssl_keyfile;
mio_ntime_t accept_tmout;
};
enum mio_def_sck_connect_option_t
{
MIO_DEV_SCK_CONNECT_SSL = (1 << 15)
};
typedef enum mio_dev_sck_connect_option_t mio_dev_sck_connect_option_t;
typedef struct mio_dev_sck_connect_t mio_dev_sck_connect_t;
struct mio_dev_sck_connect_t
{
int options;
mio_sckaddr_t remoteaddr;
mio_ntime_t connect_tmout;
mio_dev_sck_on_connect_t on_connect;
};
typedef struct mio_dev_sck_listen_t mio_dev_sck_listen_t;
struct mio_dev_sck_listen_t
{
int backlogs;
mio_dev_sck_on_connect_t on_connect; /* optional, but new connections are dropped immediately without this */
};
typedef struct mio_dev_sck_accept_t mio_dev_sck_accept_t;
struct mio_dev_sck_accept_t
{
mio_syshnd_t sck;
/* TODO: add timeout */
mio_sckaddr_t remoteaddr;
};
struct mio_dev_sck_t
{
MIO_DEV_HEADERS;
mio_dev_sck_type_t type;
mio_sckhnd_t sck;
int state;
/* remote peer address for a stateful stream socket. valid if one of the
* followings is set in state:
* MIO_DEV_TCP_ACCEPTING_SSL
* MIO_DEV_TCP_ACCEPTED
* MIO_DEV_TCP_CONNECTED
* MIO_DEV_TCP_CONNECTING
* MIO_DEV_TCP_CONNECTING_SSL
*
* also used as a placeholder to store source address for
* a stateless socket */
mio_sckaddr_t remoteaddr;
/* local socket address */
mio_sckaddr_t localaddr;
/* original destination address */
mio_sckaddr_t orgdstaddr;
mio_dev_sck_on_write_t on_write;
mio_dev_sck_on_read_t on_read;
/* return 0 on succes, -1 on failure.
* called on a new tcp device for an accepted client or
* on a tcp device conntected to a remote server */
mio_dev_sck_on_connect_t on_connect;
mio_dev_sck_on_disconnect_t on_disconnect;
/* timer job index for handling
* - connect() timeout for a connecting socket.
* - SSL_accept() timeout for a socket accepting SSL */
mio_tmridx_t tmrjob_index;
/* connect timeout, ssl-connect timeout, ssl-accept timeout.
* it denotes timeout duration under some circumstances
* or an absolute expiry time under some other circumstances. */
mio_ntime_t tmout;
void* ssl_ctx;
void* ssl;
};
#ifdef __cplusplus
extern "C" {
#endif
MIO_EXPORT mio_sckhnd_t mio_openasyncsck (
mio_t* mio,
int domain,
int type,
int proto
);
MIO_EXPORT void mio_closeasyncsck (
mio_t* mio,
mio_sckhnd_t sck
);
MIO_EXPORT int mio_makesckasync (
mio_t* mio,
mio_sckhnd_t sck
);
MIO_EXPORT int mio_getsckaddrinfo (
mio_t* mio,
const mio_sckaddr_t* addr,
mio_scklen_t* len,
mio_sckfam_t* family
);
/*
* The mio_getsckaddrport() function returns the port number of a socket
* address in the host byte order. If the address doesn't support the port
* number, it returns 0.
*/
MIO_EXPORT mio_uint16_t mio_getsckaddrport (
const mio_sckaddr_t* addr
);
/*
* The mio_getsckaddrifindex() function returns an interface number.
* If the address doesn't support the interface number, it returns 0. */
MIO_EXPORT int mio_getsckaddrifindex (
const mio_sckaddr_t* addr
);
MIO_EXPORT void mio_sckaddr_initforip4 (
mio_sckaddr_t* sckaddr,
mio_uint16_t port,
mio_ip4addr_t* ip4addr
);
MIO_EXPORT void mio_sckaddr_initforip6 (
mio_sckaddr_t* sckaddr,
mio_uint16_t port,
mio_ip6addr_t* ip6addr
);
MIO_EXPORT void mio_sckaddr_initforeth (
mio_sckaddr_t* sckaddr,
int ifindex,
mio_ethaddr_t* ethaddr
);
/* ========================================================================= */
MIO_EXPORT mio_dev_sck_t* mio_dev_sck_make (
mio_t* mio,
mio_size_t xtnsize,
const mio_dev_sck_make_t* info
);
MIO_EXPORT int mio_dev_sck_bind (
mio_dev_sck_t* dev,
mio_dev_sck_bind_t* info
);
MIO_EXPORT int mio_dev_sck_connect (
mio_dev_sck_t* dev,
mio_dev_sck_connect_t* info
);
MIO_EXPORT int mio_dev_sck_listen (
mio_dev_sck_t* dev,
mio_dev_sck_listen_t* info
);
MIO_EXPORT int mio_dev_sck_write (
mio_dev_sck_t* dev,
const void* data,
mio_iolen_t len,
void* wrctx,
const mio_sckaddr_t* dstaddr
);
MIO_EXPORT int mio_dev_sck_timedwrite (
mio_dev_sck_t* dev,
const void* data,
mio_iolen_t len,
const mio_ntime_t* tmout,
void* wrctx,
const mio_sckaddr_t* dstaddr
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE void mio_dev_sck_halt (mio_dev_sck_t* sck)
{
mio_dev_halt ((mio_dev_t*)sck);
}
static MIO_INLINE int mio_dev_sck_read (mio_dev_sck_t* sck, int enabled)
{
return mio_dev_read ((mio_dev_t*)sck, enabled);
}
#else
#define mio_dev_sck_halt(sck) mio_dev_halt((mio_dev_t*)sck)
#define mio_dev_sck_read(sck,enabled) mio_dev_read((mio_dev_t*)sck, enabled)
#endif
MIO_EXPORT mio_uint16_t mio_checksumip (
const void* hdr,
mio_size_t len
);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -24,7 +24,7 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "stio-prv.h"
#include "mio-prv.h"
#if defined(_WIN32)
# include <windows.h>
@ -48,12 +48,12 @@
#endif
#if defined(_WIN32)
#define EPOCH_DIFF_YEARS (STIO_EPOCH_YEAR-STIO_EPOCH_YEAR_WIN)
#define EPOCH_DIFF_DAYS ((stio_intptr_t)EPOCH_DIFF_YEARS*365+EPOCH_DIFF_YEARS/4-3)
#define EPOCH_DIFF_SECS ((stio_intptr_t)EPOCH_DIFF_DAYS*24*60*60)
#define EPOCH_DIFF_YEARS (MIO_EPOCH_YEAR-MIO_EPOCH_YEAR_WIN)
#define EPOCH_DIFF_DAYS ((mio_intptr_t)EPOCH_DIFF_YEARS*365+EPOCH_DIFF_YEARS/4-3)
#define EPOCH_DIFF_SECS ((mio_intptr_t)EPOCH_DIFF_DAYS*24*60*60)
#endif
void stio_gettime (stio_ntime_t* t)
void mio_gettime (mio_ntime_t* t)
{
#if defined(_WIN32)
SYSTEMTIME st;
@ -72,13 +72,13 @@ void stio_gettime (stio_ntime_t* t)
li.HighPart = ft.dwHighDateTime;
/* li.QuadPart is in the 100-nanosecond intervals */
t->sec = (li.QuadPart / (STIO_NSECS_PER_SEC / 100)) - EPOCH_DIFF_SECS;
t->nsec = (li.QuadPart % (STIO_NSECS_PER_SEC / 100)) * 100;
t->sec = (li.QuadPart / (MIO_NSECS_PER_SEC / 100)) - EPOCH_DIFF_SECS;
t->nsec = (li.QuadPart % (MIO_NSECS_PER_SEC / 100)) * 100;
#elif defined(__OS2__)
DATETIME dt;
stio_btime_t bt;
mio_btime_t bt;
/* Can I use DosQuerySysInfo(QSV_TIME_LOW) and
* DosQuerySysInfo(QSV_TIME_HIGH) for this instead?
@ -88,7 +88,7 @@ void stio_gettime (stio_ntime_t* t)
DosGetDateTime (&dt);
/* DosGetDateTime() never fails. it always returns NO_ERROR */
bt.year = dt.year - STIO_BTIME_YEAR_BASE;
bt.year = dt.year - MIO_BTIME_YEAR_BASE;
bt.mon = dt.month - 1;
bt.mday = dt.day;
bt.hour = dt.hours;
@ -97,14 +97,14 @@ void stio_gettime (stio_ntime_t* t)
/*bt.msec = dt.hundredths * 10;*/
bt.isdst = -1; /* determine dst for me */
if (stio_timelocal (&bt, t) <= -1)
if (mio_timelocal (&bt, t) <= -1)
{
t->sec = time (STIO_NULL);
t->sec = time (MIO_NULL);
t->nsec = 0;
}
else
{
t->nsec = STIO_MSEC_TO_NSEC(dt.hundredths * 10);
t->nsec = MIO_MSEC_TO_NSEC(dt.hundredths * 10);
}
return 0;
@ -112,12 +112,12 @@ void stio_gettime (stio_ntime_t* t)
struct dostime_t dt;
struct dosdate_t dd;
stio_btime_t bt;
mio_btime_t bt;
_dos_gettime (&dt);
_dos_getdate (&dd);
bt.year = dd.year - STIO_BTIME_YEAR_BASE;
bt.year = dd.year - MIO_BTIME_YEAR_BASE;
bt.mon = dd.month - 1;
bt.mday = dd.day;
bt.hour = dt.hour;
@ -126,14 +126,14 @@ void stio_gettime (stio_ntime_t* t)
/*bt.msec = dt.hsecond * 10; */
bt.isdst = -1; /* determine dst for me */
if (stio_timelocal (&bt, t) <= -1)
if (mio_timelocal (&bt, t) <= -1)
{
t->sec = time (STIO_NULL);
t->sec = time (MIO_NULL);
t->nsec = 0;
}
else
{
t->nsec = STIO_MSEC_TO_NSEC(dt.hsecond * 10);
t->nsec = MIO_MSEC_TO_NSEC(dt.hsecond * 10);
}
#elif defined(macintosh)
@ -150,11 +150,11 @@ void stio_gettime (stio_ntime_t* t)
{
#if defined(HAVE_GETTIMEOFDAY)
struct timeval tv;
gettimeofday (&tv, STIO_NULL);
gettimeofday (&tv, MIO_NULL);
t->sec = tv.tv_sec;
t->nsec = STIO_USEC_TO_NSEC(tv.tv_usec);
t->nsec = MIO_USEC_TO_NSEC(tv.tv_usec);
#else
t->sec = time (STIO_NULL);
t->sec = time (MIO_NULL);
t->nsec = 0;
#endif
}
@ -164,35 +164,35 @@ void stio_gettime (stio_ntime_t* t)
#elif defined(HAVE_GETTIMEOFDAY)
struct timeval tv;
gettimeofday (&tv, STIO_NULL);
gettimeofday (&tv, MIO_NULL);
t->sec = tv.tv_sec;
t->nsec = STIO_USEC_TO_NSEC(tv.tv_usec);
t->nsec = MIO_USEC_TO_NSEC(tv.tv_usec);
#else
t->sec = time (STIO_NULL);
t->sec = time (MIO_NULL);
t->nsec = 0;
#endif
}
void stio_addtime (const stio_ntime_t* x, const stio_ntime_t* y, stio_ntime_t* z)
void mio_addtime (const mio_ntime_t* x, const mio_ntime_t* y, mio_ntime_t* z)
{
STIO_ASSERT (x->nsec >= 0 && x->nsec < STIO_NSECS_PER_SEC);
STIO_ASSERT (y->nsec >= 0 && y->nsec < STIO_NSECS_PER_SEC);
MIO_ASSERT (x->nsec >= 0 && x->nsec < MIO_NSECS_PER_SEC);
MIO_ASSERT (y->nsec >= 0 && y->nsec < MIO_NSECS_PER_SEC);
z->sec = x->sec + y->sec;
z->nsec = x->nsec + y->nsec;
if (z->nsec >= STIO_NSECS_PER_SEC)
if (z->nsec >= MIO_NSECS_PER_SEC)
{
z->sec = z->sec + 1;
z->nsec = z->nsec - STIO_NSECS_PER_SEC;
z->nsec = z->nsec - MIO_NSECS_PER_SEC;
}
}
void stio_subtime (const stio_ntime_t* x, const stio_ntime_t* y, stio_ntime_t* z)
void mio_subtime (const mio_ntime_t* x, const mio_ntime_t* y, mio_ntime_t* z)
{
STIO_ASSERT (x->nsec >= 0 && x->nsec < STIO_NSECS_PER_SEC);
STIO_ASSERT (y->nsec >= 0 && y->nsec < STIO_NSECS_PER_SEC);
MIO_ASSERT (x->nsec >= 0 && x->nsec < MIO_NSECS_PER_SEC);
MIO_ASSERT (y->nsec >= 0 && y->nsec < MIO_NSECS_PER_SEC);
z->sec = x->sec - y->sec;
z->nsec = x->nsec - y->nsec;
@ -200,6 +200,6 @@ void stio_subtime (const stio_ntime_t* x, const stio_ntime_t* y, stio_ntime_t* z
if (z->nsec < 0)
{
z->sec = z->sec - 1;
z->nsec = z->nsec + STIO_NSECS_PER_SEC;
z->nsec = z->nsec + MIO_NSECS_PER_SEC;
}
}

234
mio/lib/mio-tmr.c Normal file
View File

@ -0,0 +1,234 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mio-prv.h"
#define HEAP_PARENT(x) (((x) - 1) / 2)
#define HEAP_LEFT(x) ((x) * 2 + 1)
#define HEAP_RIGHT(x) ((x) * 2 + 2)
#define YOUNGER_THAN(x,y) (mio_cmptime(&(x)->when, &(y)->when) < 0)
void mio_cleartmrjobs (mio_t* mio)
{
while (mio->tmr.size > 0) mio_deltmrjob (mio, 0);
}
static mio_tmridx_t sift_up (mio_t* mio, mio_tmridx_t index, int notify)
{
mio_tmridx_t parent;
parent = HEAP_PARENT(index);
if (index > 0 && YOUNGER_THAN(&mio->tmr.jobs[index], &mio->tmr.jobs[parent]))
{
mio_tmrjob_t item;
item = mio->tmr.jobs[index];
do
{
/* move down the parent to my current position */
mio->tmr.jobs[index] = mio->tmr.jobs[parent];
if (mio->tmr.jobs[index].idxptr) *mio->tmr.jobs[index].idxptr = index;
/* traverse up */
index = parent;
parent = HEAP_PARENT(parent);
}
while (index > 0 && YOUNGER_THAN(&item, &mio->tmr.jobs[parent]));
mio->tmr.jobs[index] = item;
if (mio->tmr.jobs[index].idxptr) *mio->tmr.jobs[index].idxptr = index;
}
return index;
}
static mio_tmridx_t sift_down (mio_t* mio, mio_tmridx_t index, int notify)
{
mio_size_t base = mio->tmr.size / 2;
if (index < base) /* at least 1 child is under the 'index' position */
{
mio_tmrjob_t item;
item = mio->tmr.jobs[index];
do
{
mio_tmridx_t left, right, younger;
left = HEAP_LEFT(index);
right = HEAP_RIGHT(index);
if (right < mio->tmr.size && YOUNGER_THAN(&mio->tmr.jobs[right], &mio->tmr.jobs[left]))
{
younger = right;
}
else
{
younger = left;
}
if (YOUNGER_THAN(&item, &mio->tmr.jobs[younger])) break;
mio->tmr.jobs[index] = mio->tmr.jobs[younger];
if (mio->tmr.jobs[index].idxptr) *mio->tmr.jobs[index].idxptr = index;
index = younger;
}
while (index < base);
mio->tmr.jobs[index] = item;
if (mio->tmr.jobs[index].idxptr) *mio->tmr.jobs[index].idxptr = index;
}
return index;
}
void mio_deltmrjob (mio_t* mio, mio_tmridx_t index)
{
mio_tmrjob_t item;
MIO_ASSERT (index < mio->tmr.size);
item = mio->tmr.jobs[index];
if (mio->tmr.jobs[index].idxptr) *mio->tmr.jobs[index].idxptr = MIO_TMRIDX_INVALID;
mio->tmr.size = mio->tmr.size - 1;
if (mio->tmr.size > 0 && index != mio->tmr.size)
{
mio->tmr.jobs[index] = mio->tmr.jobs[mio->tmr.size];
if (mio->tmr.jobs[index].idxptr) *mio->tmr.jobs[index].idxptr = index;
YOUNGER_THAN(&mio->tmr.jobs[index], &item)? sift_up(mio, index, 1): sift_down(mio, index, 1);
}
}
mio_tmridx_t mio_instmrjob (mio_t* mio, const mio_tmrjob_t* job)
{
mio_tmridx_t index = mio->tmr.size;
if (index >= mio->tmr.capa)
{
mio_tmrjob_t* tmp;
mio_size_t new_capa;
MIO_ASSERT (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_ENOMEM;
return MIO_TMRIDX_INVALID;
}
mio->tmr.jobs = tmp;
mio->tmr.capa = new_capa;
}
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);
}
mio_tmridx_t mio_updtmrjob (mio_t* mio, mio_tmridx_t index, const mio_tmrjob_t* job)
{
mio_tmrjob_t item;
item = mio->tmr.jobs[index];
mio->tmr.jobs[index] = *job;
if (mio->tmr.jobs[index].idxptr) *mio->tmr.jobs[index].idxptr = index;
return YOUNGER_THAN(job, &item)? sift_up (mio, index, 0): sift_down (mio, index, 0);
}
void mio_firetmrjobs (mio_t* mio, const mio_ntime_t* tm, mio_size_t* firecnt)
{
mio_ntime_t now;
mio_tmrjob_t tmrjob;
mio_size_t count = 0;
/* if the current time is not specified, get it from the system */
if (tm) now = *tm;
else mio_gettime (&now);
while (mio->tmr.size > 0)
{
if (mio_cmptime(&mio->tmr.jobs[0].when, &now) > 0) break;
tmrjob = mio->tmr.jobs[0]; /* copy the scheduled job */
mio_deltmrjob (mio, 0); /* deschedule the job */
count++;
tmrjob.handler (mio, &now, &tmrjob); /* then fire the job */
}
if (firecnt) *firecnt = count;
}
int mio_gettmrtmout (mio_t* mio, const mio_ntime_t* tm, mio_ntime_t* tmout)
{
mio_ntime_t now;
/* time-out can't be calculated when there's no job scheduled */
if (mio->tmr.size <= 0)
{
mio->errnum = MIO_ENOENT;
return -1;
}
/* if the current time is not specified, get it from the system */
if (tm) now = *tm;
else mio_gettime (&now);
mio_subtime (&mio->tmr.jobs[0].when, &now, tmout);
if (tmout->sec < 0) mio_cleartime (tmout);
return 0;
}
mio_tmrjob_t* mio_gettmrjob (mio_t* mio, mio_tmridx_t index)
{
if (index < 0 || index >= mio->tmr.size)
{
mio->errnum = MIO_ENOENT;
return MIO_NULL;
}
return &mio->tmr.jobs[index];
}
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;
return -1;
}
*deadline = mio->tmr.jobs[index].when;
return 0;
}

524
mio/lib/mio-utl.c Normal file
View File

@ -0,0 +1,524 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mio-prv.h"
/* ========================================================================= */
#if defined(MIO_HAVE_UINT16_T)
mio_uint16_t mio_ntoh16 (mio_uint16_t x)
{
#if defined(MIO_ENDIAN_BIG)
return x;
#elif defined(MIO_ENDIAN_LITTLE)
mio_uint8_t* c = (mio_uint8_t*)&x;
return (mio_uint16_t)(
((mio_uint16_t)c[0] << 8) |
((mio_uint16_t)c[1] << 0));
#else
# error Unknown endian
#endif
}
mio_uint16_t mio_hton16 (mio_uint16_t x)
{
#if defined(MIO_ENDIAN_BIG)
return x;
#elif defined(MIO_ENDIAN_LITTLE)
mio_uint8_t* c = (mio_uint8_t*)&x;
return (mio_uint16_t)(
((mio_uint16_t)c[0] << 8) |
((mio_uint16_t)c[1] << 0));
#else
# error Unknown endian
#endif
}
#endif
/* ========================================================================= */
#if defined(MIO_HAVE_UINT32_T)
mio_uint32_t mio_ntoh32 (mio_uint32_t x)
{
#if defined(MIO_ENDIAN_BIG)
return x;
#elif defined(MIO_ENDIAN_LITTLE)
mio_uint8_t* c = (mio_uint8_t*)&x;
return (mio_uint32_t)(
((mio_uint32_t)c[0] << 24) |
((mio_uint32_t)c[1] << 16) |
((mio_uint32_t)c[2] << 8) |
((mio_uint32_t)c[3] << 0));
#else
# error Unknown endian
#endif
}
mio_uint32_t mio_hton32 (mio_uint32_t x)
{
#if defined(MIO_ENDIAN_BIG)
return x;
#elif defined(MIO_ENDIAN_LITTLE)
mio_uint8_t* c = (mio_uint8_t*)&x;
return (mio_uint32_t)(
((mio_uint32_t)c[0] << 24) |
((mio_uint32_t)c[1] << 16) |
((mio_uint32_t)c[2] << 8) |
((mio_uint32_t)c[3] << 0));
#else
# error Unknown endian
#endif
}
#endif
/* ========================================================================= */
#if defined(MIO_HAVE_UINT64_T)
mio_uint64_t mio_ntoh64 (mio_uint64_t x)
{
#if defined(MIO_ENDIAN_BIG)
return x;
#elif defined(MIO_ENDIAN_LITTLE)
mio_uint8_t* c = (mio_uint8_t*)&x;
return (mio_uint64_t)(
((mio_uint64_t)c[0] << 56) |
((mio_uint64_t)c[1] << 48) |
((mio_uint64_t)c[2] << 40) |
((mio_uint64_t)c[3] << 32) |
((mio_uint64_t)c[4] << 24) |
((mio_uint64_t)c[5] << 16) |
((mio_uint64_t)c[6] << 8) |
((mio_uint64_t)c[7] << 0));
#else
# error Unknown endian
#endif
}
mio_uint64_t mio_hton64 (mio_uint64_t x)
{
#if defined(MIO_ENDIAN_BIG)
return x;
#elif defined(MIO_ENDIAN_LITTLE)
mio_uint8_t* c = (mio_uint8_t*)&x;
return (mio_uint64_t)(
((mio_uint64_t)c[0] << 56) |
((mio_uint64_t)c[1] << 48) |
((mio_uint64_t)c[2] << 40) |
((mio_uint64_t)c[3] << 32) |
((mio_uint64_t)c[4] << 24) |
((mio_uint64_t)c[5] << 16) |
((mio_uint64_t)c[6] << 8) |
((mio_uint64_t)c[7] << 0));
#else
# error Unknown endian
#endif
}
#endif
/* ========================================================================= */
#if defined(MIO_HAVE_UINT128_T)
mio_uint128_t mio_ntoh128 (mio_uint128_t x)
{
#if defined(MIO_ENDIAN_BIG)
return x;
#elif defined(MIO_ENDIAN_LITTLE)
mio_uint8_t* c = (mio_uint8_t*)&x;
return (mio_uint128_t)(
((mio_uint128_t)c[0] << 120) |
((mio_uint128_t)c[1] << 112) |
((mio_uint128_t)c[2] << 104) |
((mio_uint128_t)c[3] << 96) |
((mio_uint128_t)c[4] << 88) |
((mio_uint128_t)c[5] << 80) |
((mio_uint128_t)c[6] << 72) |
((mio_uint128_t)c[7] << 64) |
((mio_uint128_t)c[8] << 56) |
((mio_uint128_t)c[9] << 48) |
((mio_uint128_t)c[10] << 40) |
((mio_uint128_t)c[11] << 32) |
((mio_uint128_t)c[12] << 24) |
((mio_uint128_t)c[13] << 16) |
((mio_uint128_t)c[14] << 8) |
((mio_uint128_t)c[15] << 0));
#else
# error Unknown endian
#endif
}
mio_uint128_t mio_hton128 (mio_uint128_t x)
{
#if defined(MIO_ENDIAN_BIG)
return x;
#elif defined(MIO_ENDIAN_LITTLE)
mio_uint8_t* c = (mio_uint8_t*)&x;
return (mio_uint128_t)(
((mio_uint128_t)c[0] << 120) |
((mio_uint128_t)c[1] << 112) |
((mio_uint128_t)c[2] << 104) |
((mio_uint128_t)c[3] << 96) |
((mio_uint128_t)c[4] << 88) |
((mio_uint128_t)c[5] << 80) |
((mio_uint128_t)c[6] << 72) |
((mio_uint128_t)c[7] << 64) |
((mio_uint128_t)c[8] << 56) |
((mio_uint128_t)c[9] << 48) |
((mio_uint128_t)c[10] << 40) |
((mio_uint128_t)c[11] << 32) |
((mio_uint128_t)c[12] << 24) |
((mio_uint128_t)c[13] << 16) |
((mio_uint128_t)c[14] << 8) |
((mio_uint128_t)c[15] << 0));
#else
# error Unknown endian
#endif
}
#endif
/* ========================================================================= */
#define IS_MSPACE(x) ((x) == MIO_MT(' ') || (x) == MIO_MT('\t') || (x) == MIO_MT('\n') || (x) == MIO_MT('\r'))
mio_mchar_t* mio_mbsdup (mio_t* mio, const mio_mchar_t* src)
{
mio_mchar_t* dst;
mio_size_t len;
dst = (mio_mchar_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_ENOMEM;
return MIO_NULL;
}
MIO_MEMCPY (dst, src, (len + 1) * MIO_SIZEOF(*src));
return dst;
}
mio_size_t mio_mbscpy (mio_mchar_t* buf, const mio_mchar_t* str)
{
mio_mchar_t* org = buf;
while ((*buf++ = *str++) != MIO_MT('\0'));
return buf - org - 1;
}
int mio_mbsspltrn (
mio_mchar_t* s, const mio_mchar_t* delim,
mio_mchar_t lquote, mio_mchar_t rquote,
mio_mchar_t escape, const mio_mchar_t* trset)
{
mio_mchar_t* p = s, *d;
mio_mchar_t* sp = MIO_NULL, * ep = MIO_NULL;
int delim_mode;
int cnt = 0;
if (delim == MIO_NULL) delim_mode = 0;
else
{
delim_mode = 1;
for (d = (mio_mchar_t*)delim; *d != MIO_MT('\0'); d++)
if (!IS_MSPACE(*d)) delim_mode = 2;
}
if (delim_mode == 0)
{
/* skip preceding space characters */
while (IS_MSPACE(*p)) p++;
/* when 0 is given as "delim", it has an effect of cutting
preceding and trailing space characters off "s". */
if (lquote != MIO_MT('\0') && *p == lquote)
{
mio_mbscpy (p, p + 1);
for (;;)
{
if (*p == MIO_MT('\0')) return -1;
if (escape != MIO_MT('\0') && *p == escape)
{
if (trset != MIO_NULL && p[1] != MIO_MT('\0'))
{
const mio_mchar_t* ep = trset;
while (*ep != MIO_MT('\0'))
{
if (p[1] == *ep++)
{
p[1] = *ep;
break;
}
}
}
mio_mbscpy (p, p + 1);
}
else
{
if (*p == rquote)
{
p++;
break;
}
}
if (sp == 0) sp = p;
ep = p;
p++;
}
while (IS_MSPACE(*p)) p++;
if (*p != MIO_MT('\0')) return -1;
if (sp == 0 && ep == 0) s[0] = MIO_MT('\0');
else
{
ep[1] = MIO_MT('\0');
if (s != (mio_mchar_t*)sp) mio_mbscpy (s, sp);
cnt++;
}
}
else
{
while (*p)
{
if (!IS_MSPACE(*p))
{
if (sp == 0) sp = p;
ep = p;
}
p++;
}
if (sp == 0 && ep == 0) s[0] = MIO_MT('\0');
else
{
ep[1] = MIO_MT('\0');
if (s != (mio_mchar_t*)sp) mio_mbscpy (s, sp);
cnt++;
}
}
}
else if (delim_mode == 1)
{
mio_mchar_t* o;
while (*p)
{
o = p;
while (IS_MSPACE(*p)) p++;
if (o != p) { mio_mbscpy (o, p); p = o; }
if (lquote != MIO_MT('\0') && *p == lquote)
{
mio_mbscpy (p, p + 1);
for (;;)
{
if (*p == MIO_MT('\0')) return -1;
if (escape != MIO_MT('\0') && *p == escape)
{
if (trset != MIO_NULL && p[1] != MIO_MT('\0'))
{
const mio_mchar_t* ep = trset;
while (*ep != MIO_MT('\0'))
{
if (p[1] == *ep++)
{
p[1] = *ep;
break;
}
}
}
mio_mbscpy (p, p + 1);
}
else
{
if (*p == rquote)
{
*p++ = MIO_MT('\0');
cnt++;
break;
}
}
p++;
}
}
else
{
o = p;
for (;;)
{
if (*p == MIO_MT('\0'))
{
if (o != p) cnt++;
break;
}
if (IS_MSPACE (*p))
{
*p++ = MIO_MT('\0');
cnt++;
break;
}
p++;
}
}
}
}
else /* if (delim_mode == 2) */
{
mio_mchar_t* o;
int ok;
while (*p != MIO_MT('\0'))
{
o = p;
while (IS_MSPACE(*p)) p++;
if (o != p) { mio_mbscpy (o, p); p = o; }
if (lquote != MIO_MT('\0') && *p == lquote)
{
mio_mbscpy (p, p + 1);
for (;;)
{
if (*p == MIO_MT('\0')) return -1;
if (escape != MIO_MT('\0') && *p == escape)
{
if (trset != MIO_NULL && p[1] != MIO_MT('\0'))
{
const mio_mchar_t* ep = trset;
while (*ep != MIO_MT('\0'))
{
if (p[1] == *ep++)
{
p[1] = *ep;
break;
}
}
}
mio_mbscpy (p, p + 1);
}
else
{
if (*p == rquote)
{
*p++ = MIO_MT('\0');
cnt++;
break;
}
}
p++;
}
ok = 0;
while (IS_MSPACE(*p)) p++;
if (*p == MIO_MT('\0')) ok = 1;
for (d = (mio_mchar_t*)delim; *d != MIO_MT('\0'); d++)
{
if (*p == *d)
{
ok = 1;
mio_mbscpy (p, p + 1);
break;
}
}
if (ok == 0) return -1;
}
else
{
o = p; sp = ep = 0;
for (;;)
{
if (*p == MIO_MT('\0'))
{
if (ep)
{
ep[1] = MIO_MT('\0');
p = &ep[1];
}
cnt++;
break;
}
for (d = (mio_mchar_t*)delim; *d != MIO_MT('\0'); d++)
{
if (*p == *d)
{
if (sp == MIO_NULL)
{
mio_mbscpy (o, p); p = o;
*p++ = MIO_MT('\0');
}
else
{
mio_mbscpy (&ep[1], p);
mio_mbscpy (o, sp);
o[ep - sp + 1] = MIO_MT('\0');
p = &o[ep - sp + 2];
}
cnt++;
/* last empty field after delim */
if (*p == MIO_MT('\0')) cnt++;
goto exit_point;
}
}
if (!IS_MSPACE (*p))
{
if (sp == MIO_NULL) sp = p;
ep = p;
}
p++;
}
exit_point:
;
}
}
}
return cnt;
}
int mio_mbsspl (
mio_mchar_t* s, const mio_mchar_t* delim,
mio_mchar_t lquote, mio_mchar_t rquote, mio_mchar_t escape)
{
return mio_mbsspltrn (s, delim, lquote, rquote, escape, MIO_NULL);
}

File diff suppressed because it is too large Load Diff

554
mio/lib/mio.h Normal file
View File

@ -0,0 +1,554 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MIO_H_
#define _MIO_H_
#include <mio-cmn.h>
/**
* The mio_ntime_t type defines a numeric time type expressed in the
* number of milliseconds since the Epoch (00:00:00 UTC, Jan 1, 1970).
*/
typedef struct mio_ntime_t mio_ntime_t;
struct mio_ntime_t
{
mio_intptr_t sec;
mio_int32_t nsec; /* nanoseconds */
};
#if defined(_WIN32)
typedef mio_uintptr_t qse_syshnd_t;
#define MIO_SYSHND_INVALID (~(mio_uintptr_t)0)
#else
typedef int mio_syshnd_t;
#define MIO_SYSHND_INVALID (-1)
#endif
typedef struct mio_devaddr_t mio_devaddr_t;
struct mio_devaddr_t
{
int len;
void* ptr;
};
#define MIO_CONST_SWAP16(x) \
((mio_uint16_t)((((mio_uint16_t)(x) & (mio_uint16_t)0x00ffU) << 8) | \
(((mio_uint16_t)(x) & (mio_uint16_t)0xff00U) >> 8) ))
#define MIO_CONST_SWAP32(x) \
((mio_uint32_t)((((mio_uint32_t)(x) & (mio_uint32_t)0x000000ffUL) << 24) | \
(((mio_uint32_t)(x) & (mio_uint32_t)0x0000ff00UL) << 8) | \
(((mio_uint32_t)(x) & (mio_uint32_t)0x00ff0000UL) >> 8) | \
(((mio_uint32_t)(x) & (mio_uint32_t)0xff000000UL) >> 24) ))
#if defined(MIO_ENDIAN_LITTLE)
# define MIO_CONST_NTOH16(x) MIO_CONST_SWAP16(x)
# define MIO_CONST_HTON16(x) MIO_CONST_SWAP16(x)
# define MIO_CONST_NTOH32(x) MIO_CONST_SWAP32(x)
# define MIO_CONST_HTON32(x) MIO_CONST_SWAP32(x)
#elif defined(MIO_ENDIAN_BIG)
# define MIO_CONST_NTOH16(x) (x)
# define MIO_CONST_HTON16(x) (x)
# define MIO_CONST_NTOH32(x) (x)
# define MIO_CONST_HTON32(x) (x)
#else
# error UNKNOWN ENDIAN
#endif
/* ========================================================================= */
typedef struct mio_t mio_t;
typedef struct mio_dev_t mio_dev_t;
typedef struct mio_dev_mth_t mio_dev_mth_t;
typedef struct mio_dev_evcb_t mio_dev_evcb_t;
typedef struct mio_wq_t mio_wq_t;
typedef mio_intptr_t mio_iolen_t; /* NOTE: this is a signed type */
enum mio_errnum_t
{
MIO_ENOERR,
MIO_ENOIMPL,
MIO_ESYSERR,
MIO_EINTERN,
MIO_ENOMEM,
MIO_EINVAL,
MIO_EEXIST,
MIO_ENOENT,
MIO_ENOSUP, /* not supported */
MIO_EMFILE, /* too many open files */
MIO_ENFILE,
MIO_EAGAIN,
MIO_ECONRF, /* connection refused */
MIO_ECONRS, /* connection reset */
MIO_ENOCAPA, /* no capability */
MIO_ETMOUT, /* timed out */
MIO_EPERM, /* operation not permitted */
MIO_EDEVMAKE,
MIO_EDEVERR,
MIO_EDEVHUP
};
typedef enum mio_errnum_t mio_errnum_t;
enum mio_stopreq_t
{
MIO_STOPREQ_NONE = 0,
MIO_STOPREQ_TERMINATION,
MIO_STOPREQ_WATCHER_ERROR
};
typedef enum mio_stopreq_t mio_stopreq_t;
/* ========================================================================= */
#define MIO_TMRIDX_INVALID ((mio_tmridx_t)-1)
typedef mio_size_t mio_tmridx_t;
typedef struct mio_tmrjob_t mio_tmrjob_t;
typedef void (*mio_tmrjob_handler_t) (
mio_t* mio,
const mio_ntime_t* now,
mio_tmrjob_t* tmrjob
);
struct mio_tmrjob_t
{
void* ctx;
mio_ntime_t when;
mio_tmrjob_handler_t handler;
mio_tmridx_t* idxptr; /* pointer to the index holder */
};
/* ========================================================================= */
struct mio_dev_mth_t
{
/* ------------------------------------------------------------------ */
/* mandatory. called in mio_makedev() */
int (*make) (mio_dev_t* dev, void* ctx);
/* ------------------------------------------------------------------ */
/* mandatory. called in mio_killdev(). also called in mio_makedev() upon
* failure after make() success.
*
* when 'force' is 0, the return value of -1 causes the device to be a
* zombie. the kill method is called periodically on a zombie device
* until the method returns 0.
*
* when 'force' is 1, the called should not return -1. If it does, the
* method is called once more only with the 'force' value of 2.
*
* when 'force' is 2, the device is destroyed regardless of the return value.
*/
int (*kill) (mio_dev_t* dev, int force);
/* ------------------------------------------------------------------ */
mio_syshnd_t (*getsyshnd) (mio_dev_t* dev); /* mandatory. called in mio_makedev() after successful make() */
/* ------------------------------------------------------------------ */
/* return -1 on failure, 0 if no data is availble, 1 otherwise.
* when returning 1, *len must be sent to the length of data read.
* if *len is set to 0, it's treated as EOF. */
int (*read) (mio_dev_t* dev, void* data, mio_iolen_t* len, mio_devaddr_t* srcaddr);
/* ------------------------------------------------------------------ */
int (*write) (mio_dev_t* dev, const void* data, mio_iolen_t* len, const mio_devaddr_t* dstaddr);
/* ------------------------------------------------------------------ */
int (*ioctl) (mio_dev_t* dev, int cmd, void* arg);
};
struct mio_dev_evcb_t
{
/* return -1 on failure. 0 or 1 on success.
* when 0 is returned, it doesn't attempt to perform actual I/O.
* when 1 is returned, it attempts to perform actual I/O. */
int (*ready) (mio_dev_t* dev, int events);
/* return -1 on failure, 0 or 1 on success.
* when 0 is returned, the main loop stops the attempt to read more data.
* when 1 is returned, the main loop attempts to read more data without*/
int (*on_read) (mio_dev_t* dev, const void* data, mio_iolen_t len, const mio_devaddr_t* srcaddr);
/* return -1 on failure, 0 on success.
* wrlen is the length of data written. it is the length of the originally
* posted writing request for a stream device. For a non stream device, it
* may be shorter than the originally posted length. */
int (*on_write) (mio_dev_t* dev, mio_iolen_t wrlen, void* wrctx, const mio_devaddr_t* dstaddr);
};
struct mio_wq_t
{
mio_wq_t* next;
mio_wq_t* prev;
mio_iolen_t olen; /* original data length */
mio_uint8_t* ptr; /* pointer to data */
mio_iolen_t len; /* remaining data length */
void* ctx;
mio_dev_t* dev; /* back-pointer to the device */
mio_tmridx_t tmridx;
mio_devaddr_t dstaddr;
};
#define MIO_WQ_INIT(wq) ((wq)->next = (wq)->prev = (wq))
#define MIO_WQ_TAIL(wq) ((wq)->prev)
#define MIO_WQ_HEAD(wq) ((wq)->next)
#define MIO_WQ_ISEMPTY(wq) (MIO_WQ_HEAD(wq) == (wq))
#define MIO_WQ_ISNODE(wq,x) ((wq) != (x))
#define MIO_WQ_ISHEAD(wq,x) (MIO_WQ_HEAD(wq) == (x))
#define MIO_WQ_ISTAIL(wq,x) (MIO_WQ_TAIL(wq) == (x))
#define MIO_WQ_NEXT(x) ((x)->next)
#define MIO_WQ_PREV(x) ((x)->prev)
#define MIO_WQ_LINK(p,x,n) do { \
mio_wq_t* pp = (p), * nn = (n); \
(x)->prev = (p); \
(x)->next = (n); \
nn->prev = (x); \
pp->next = (x); \
} while (0)
#define MIO_WQ_UNLINK(x) do { \
mio_wq_t* pp = (x)->prev, * nn = (x)->next; \
nn->prev = pp; pp->next = nn; \
} while (0)
#define MIO_WQ_REPL(o,n) do { \
mio_wq_t* oo = (o), * nn = (n); \
nn->next = oo->next; \
nn->next->prev = nn; \
nn->prev = oo->prev; \
nn->prev->next = nn; \
} while (0)
/* insert an item at the back of the queue */
/*#define MIO_WQ_ENQ(wq,x) MIO_WQ_LINK(MIO_WQ_TAIL(wq), x, MIO_WQ_TAIL(wq)->next)*/
#define MIO_WQ_ENQ(wq,x) MIO_WQ_LINK(MIO_WQ_TAIL(wq), x, wq)
/* remove an item in the front from the queue */
#define MIO_WQ_DEQ(wq) MIO_WQ_UNLINK(MIO_WQ_HEAD(wq))
#define MIO_DEV_HEADERS \
mio_t* mio; \
mio_size_t dev_size; \
int dev_capa; \
mio_dev_mth_t* dev_mth; \
mio_dev_evcb_t* dev_evcb; \
mio_wq_t wq; \
mio_dev_t* dev_prev; \
mio_dev_t* dev_next
struct mio_dev_t
{
MIO_DEV_HEADERS;
};
enum mio_dev_capa_t
{
MIO_DEV_CAPA_VIRTUAL = (1 << 0),
MIO_DEV_CAPA_IN = (1 << 1),
MIO_DEV_CAPA_OUT = (1 << 2),
/* #MIO_DEV_CAPA_PRI is meaningful only if #MIO_DEV_CAPA_IN is set */
MIO_DEV_CAPA_PRI = (1 << 3),
MIO_DEV_CAPA_STREAM = (1 << 4),
MIO_DEV_CAPA_OUT_QUEUED = (1 << 5),
/* internal use only. never set this bit to the dev_capa field */
MIO_DEV_CAPA_IN_DISABLED = (1 << 9),
MIO_DEV_CAPA_IN_CLOSED = (1 << 10),
MIO_DEV_CAPA_OUT_CLOSED = (1 << 11),
MIO_DEV_CAPA_IN_WATCHED = (1 << 12),
MIO_DEV_CAPA_OUT_WATCHED = (1 << 13),
MIO_DEV_CAPA_PRI_WATCHED = (1 << 14), /**< can be set only if MIO_DEV_CAPA_IN_WATCHED is set */
MIO_DEV_CAPA_ACTIVE = (1 << 15),
MIO_DEV_CAPA_HALTED = (1 << 16),
MIO_DEV_CAPA_ZOMBIE = (1 << 17)
};
typedef enum mio_dev_capa_t mio_dev_capa_t;
enum mio_dev_watch_cmd_t
{
MIO_DEV_WATCH_START,
MIO_DEV_WATCH_UPDATE,
MIO_DEV_WATCH_RENEW, /* automatic update */
MIO_DEV_WATCH_STOP
};
typedef enum mio_dev_watch_cmd_t mio_dev_watch_cmd_t;
enum mio_dev_event_t
{
MIO_DEV_EVENT_IN = (1 << 0),
MIO_DEV_EVENT_OUT = (1 << 1),
MIO_DEV_EVENT_PRI = (1 << 2),
MIO_DEV_EVENT_HUP = (1 << 3),
MIO_DEV_EVENT_ERR = (1 << 4)
};
typedef enum mio_dev_event_t mio_dev_event_t;
/* ========================================================================= */
#ifdef __cplusplus
extern "C" {
#endif
MIO_EXPORT mio_t* mio_open (
mio_mmgr_t* mmgr,
mio_size_t xtnsize,
mio_size_t tmrcapa, /**< initial timer capacity */
mio_errnum_t* errnum
);
MIO_EXPORT void mio_close (
mio_t* mio
);
MIO_EXPORT int mio_init (
mio_t* mio,
mio_mmgr_t* mmgr,
mio_size_t tmrcapa
);
MIO_EXPORT void mio_fini (
mio_t* mio
);
MIO_EXPORT int mio_exec (
mio_t* mio
);
MIO_EXPORT int mio_loop (
mio_t* mio
);
MIO_EXPORT void mio_stop (
mio_t* mio,
mio_stopreq_t stopreq
);
MIO_EXPORT mio_dev_t* mio_makedev (
mio_t* mio,
mio_size_t dev_size,
mio_dev_mth_t* dev_mth,
mio_dev_evcb_t* dev_evcb,
void* make_ctx
);
MIO_EXPORT void mio_killdev (
mio_t* mio,
mio_dev_t* dev
);
MIO_EXPORT int mio_dev_ioctl (
mio_dev_t* dev,
int cmd,
void* arg
);
MIO_EXPORT int mio_dev_watch (
mio_dev_t* dev,
mio_dev_watch_cmd_t cmd,
/** 0 or bitwise-ORed of #MIO_DEV_EVENT_IN and #MIO_DEV_EVENT_OUT */
int events
);
MIO_EXPORT int mio_dev_read (
mio_dev_t* dev,
int enabled
);
/**
* The mio_dev_write() function posts a writing request.
* It attempts to write data immediately if there is no pending requests.
* If writing fails, it returns -1. If writing succeeds, it calls the
* on_write callback. If the callback fails, it returns -1. If the callback
* succeeds, it returns 1. If no immediate writing is possible, the request
* is enqueued to a pending request list. If enqueing gets successful,
* it returns 0. otherwise it returns -1.
*/
MIO_EXPORT int mio_dev_write (
mio_dev_t* dev,
const void* data,
mio_iolen_t len,
void* wrctx,
const mio_devaddr_t* dstaddr
);
MIO_EXPORT int mio_dev_timedwrite (
mio_dev_t* dev,
const void* data,
mio_iolen_t len,
const mio_ntime_t* tmout,
void* wrctx,
const mio_devaddr_t* dstaddr
);
MIO_EXPORT void mio_dev_halt (
mio_dev_t* dev
);
/* ========================================================================= */
#define mio_inittime(x,s,ns) (((x)->sec = (s)), ((x)->nsec = (ns)))
#define mio_cleartime(x) mio_inittime(x,0,0)
#define mio_cmptime(x,y) \
(((x)->sec == (y)->sec)? ((x)->nsec - (y)->nsec): \
((x)->sec - (y)->sec))
/* if time has been normalized properly, nsec must be equal to or
* greater than 0. */
#define mio_isnegtime(x) ((x)->sec < 0)
#define mio_ispostime(x) ((x)->sec > 0 || ((x)->sec == 0 && (x)->nsec > 0))
#define mio_iszerotime(x) ((x)->sec == 0 && (x)->nsec == 0)
/**
* The mio_gettime() function gets the current time.
*/
MIO_EXPORT void mio_gettime (
mio_ntime_t* nt
);
/**
* The mio_addtime() function adds x and y and stores the result in z
*/
MIO_EXPORT void mio_addtime (
const mio_ntime_t* x,
const mio_ntime_t* y,
mio_ntime_t* z
);
/**
* The mio_subtime() function subtract y from x and stores the result in z.
*/
MIO_EXPORT void mio_subtime (
const mio_ntime_t* x,
const mio_ntime_t* y,
mio_ntime_t* z
);
/**
* The mio_instmrjob() function schedules a new event.
*
* \return #MIO_TMRIDX_INVALID on failure, valid index on success.
*/
MIO_EXPORT mio_tmridx_t mio_instmrjob (
mio_t* mio,
const mio_tmrjob_t* job
);
MIO_EXPORT mio_tmridx_t mio_updtmrjob (
mio_t* mio,
mio_tmridx_t index,
const mio_tmrjob_t* job
);
MIO_EXPORT void mio_deltmrjob (
mio_t* mio,
mio_tmridx_t index
);
/**
* The mio_gettmrjob() function returns the
* pointer to the registered event at the given index.
*/
MIO_EXPORT mio_tmrjob_t* mio_gettmrjob (
mio_t* mio,
mio_tmridx_t index
);
MIO_EXPORT int mio_gettmrjobdeadline (
mio_t* mio,
mio_tmridx_t index,
mio_ntime_t* deadline
);
/* ========================================================================= */
#if defined(MIO_HAVE_UINT16_T)
MIO_EXPORT mio_uint16_t mio_ntoh16 (
mio_uint16_t x
);
MIO_EXPORT mio_uint16_t mio_hton16 (
mio_uint16_t x
);
#endif
#if defined(MIO_HAVE_UINT32_T)
MIO_EXPORT mio_uint32_t mio_ntoh32 (
mio_uint32_t x
);
MIO_EXPORT mio_uint32_t mio_hton32 (
mio_uint32_t x
);
#endif
#if defined(MIO_HAVE_UINT64_T)
MIO_EXPORT mio_uint64_t mio_ntoh64 (
mio_uint64_t x
);
MIO_EXPORT mio_uint64_t mio_hton64 (
mio_uint64_t x
);
#endif
#if defined(MIO_HAVE_UINT128_T)
MIO_EXPORT mio_uint128_t mio_ntoh128 (
mio_uint128_t x
);
MIO_EXPORT mio_uint128_t mio_hton128 (
mio_uint128_t x
);
#endif
/* ========================================================================= */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,4 +1,4 @@
/* lib/stio-cfg.h.in. Generated from configure.ac by autoheader. */
/* lib/mio-cfg.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
@ -830,118 +830,118 @@
#undef STDC_HEADERS
/* Big Endian */
#undef STIO_ENDIAN_BIG
#undef MIO_ENDIAN_BIG
/* Little Endian */
#undef STIO_ENDIAN_LITTLE
#undef MIO_ENDIAN_LITTLE
/* Unknown Endian */
#undef STIO_ENDIAN_UNKNOWN
#undef MIO_ENDIAN_UNKNOWN
/* MB_LEN_MAX */
#undef STIO_MBLEN_MAX
#undef MIO_MBLEN_MAX
/* Author */
#undef STIO_PACKAGE_AUTHOR
#undef MIO_PACKAGE_AUTHOR
/* package name */
#undef STIO_PACKAGE_NAME
#undef MIO_PACKAGE_NAME
/* Project URL */
#undef STIO_PACKAGE_URL
#undef MIO_PACKAGE_URL
/* Package version */
#undef STIO_PACKAGE_VERSION
#undef MIO_PACKAGE_VERSION
/* Major version number */
#undef STIO_PACKAGE_VERSION_MAJOR
#undef MIO_PACKAGE_VERSION_MAJOR
/* Minor version number */
#undef STIO_PACKAGE_VERSION_MINOR
#undef MIO_PACKAGE_VERSION_MINOR
/* Patch level */
#undef STIO_PACKAGE_VERSION_PATCH
#undef MIO_PACKAGE_VERSION_PATCH
/* sizeof(char) */
#undef STIO_SIZEOF_CHAR
#undef MIO_SIZEOF_CHAR
/* sizeof(double) */
#undef STIO_SIZEOF_DOUBLE
#undef MIO_SIZEOF_DOUBLE
/* sizeof(float) */
#undef STIO_SIZEOF_FLOAT
#undef MIO_SIZEOF_FLOAT
/* sizeof(int) */
#undef STIO_SIZEOF_INT
#undef MIO_SIZEOF_INT
/* sizeof(long) */
#undef STIO_SIZEOF_LONG
#undef MIO_SIZEOF_LONG
/* sizeof(long double) */
#undef STIO_SIZEOF_LONG_DOUBLE
#undef MIO_SIZEOF_LONG_DOUBLE
/* sizeof(long long) */
#undef STIO_SIZEOF_LONG_LONG
#undef MIO_SIZEOF_LONG_LONG
/* sizeof(mbstate_t) */
#undef STIO_SIZEOF_MBSTATE_T
#undef MIO_SIZEOF_MBSTATE_T
/* sizeof(off64_t) */
#undef STIO_SIZEOF_OFF64_T
#undef MIO_SIZEOF_OFF64_T
/* sizeof(off_t) */
#undef STIO_SIZEOF_OFF_T
#undef MIO_SIZEOF_OFF_T
/* sizeof(short) */
#undef STIO_SIZEOF_SHORT
#undef MIO_SIZEOF_SHORT
/* sizeof(socklen_t) */
#undef STIO_SIZEOF_SOCKLEN_T
#undef MIO_SIZEOF_SOCKLEN_T
/* sizeof(struct sockaddr_dl) */
#undef STIO_SIZEOF_STRUCT_SOCKADDR_DL
#undef MIO_SIZEOF_STRUCT_SOCKADDR_DL
/* sizeof(struct sockaddr_in) */
#undef STIO_SIZEOF_STRUCT_SOCKADDR_IN
#undef MIO_SIZEOF_STRUCT_SOCKADDR_IN
/* sizeof(struct sockaddr_in6) */
#undef STIO_SIZEOF_STRUCT_SOCKADDR_IN6
#undef MIO_SIZEOF_STRUCT_SOCKADDR_IN6
/* sizeof(struct sockaddr_ll) */
#undef STIO_SIZEOF_STRUCT_SOCKADDR_LL
#undef MIO_SIZEOF_STRUCT_SOCKADDR_LL
/* sizeof(struct sockaddr_un) */
#undef STIO_SIZEOF_STRUCT_SOCKADDR_UN
#undef MIO_SIZEOF_STRUCT_SOCKADDR_UN
/* sizeof(void*) */
#undef STIO_SIZEOF_VOID_P
#undef MIO_SIZEOF_VOID_P
/* sizeof(wchar_t) */
#undef STIO_SIZEOF_WCHAR_T
#undef MIO_SIZEOF_WCHAR_T
/* sizeof(__float128) */
#undef STIO_SIZEOF___FLOAT128
#undef MIO_SIZEOF___FLOAT128
/* sizeof(__int128) */
#undef STIO_SIZEOF___INT128
#undef MIO_SIZEOF___INT128
/* sizeof(__int128_t) */
#undef STIO_SIZEOF___INT128_T
#undef MIO_SIZEOF___INT128_T
/* sizeof(__int16) */
#undef STIO_SIZEOF___INT16
#undef MIO_SIZEOF___INT16
/* sizeof(__int32) */
#undef STIO_SIZEOF___INT32
#undef MIO_SIZEOF___INT32
/* sizeof(__int64) */
#undef STIO_SIZEOF___INT64
#undef MIO_SIZEOF___INT64
/* sizeof(__int8) */
#undef STIO_SIZEOF___INT8
#undef MIO_SIZEOF___INT8
/* Define if socklen_t is signed */
#undef STIO_SOCKLEN_T_IS_SIGNED
#undef MIO_SOCKLEN_T_IS_SIGNED
/* Version number of package */
#undef VERSION

View File

@ -1,569 +0,0 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STIO_CMN_H_
#define _STIO_CMN_H_
/* WARNING: NEVER CHANGE/DELETE THE FOLLOWING STIO_HAVE_CFG_H DEFINITION.
* IT IS USED FOR DEPLOYMENT BY MAKEFILE.AM */
/*#define STIO_HAVE_CFG_H*/
#if defined(STIO_HAVE_CFG_H)
# include "stio-cfg.h"
#elif defined(_WIN32)
# include "stio-msw.h"
#elif defined(__OS2__)
# include "stio-os2.h"
#elif defined(__MSDOS__)
# include "stio-dos.h"
#elif defined(macintosh)
# include "stio-mac.h" /* class mac os */
#else
# error UNSUPPORTED SYSTEM
#endif
#if defined(EMSCRIPTEN)
# if defined(STIO_SIZEOF___INT128)
# undef STIO_SIZEOF___INT128
# define STIO_SIZEOF___INT128 0
# endif
# if defined(STIO_SIZEOF_LONG) && defined(STIO_SIZEOF_INT) && (STIO_SIZEOF_LONG > STIO_SIZEOF_INT)
/* autoconf doesn't seem to match actual emscripten */
# undef STIO_SIZEOF_LONG
# define STIO_SIZEOF_LONG STIO_SIZEOF_INT
# endif
#endif
/* =========================================================================
* PRIMITIVE TYPE DEFINTIONS
* ========================================================================= */
/* stio_int8_t */
#if defined(STIO_SIZEOF_CHAR) && (STIO_SIZEOF_CHAR == 1)
# define STIO_HAVE_UINT8_T
# define STIO_HAVE_INT8_T
typedef unsigned char stio_uint8_t;
typedef signed char stio_int8_t;
#elif defined(STIO_SIZEOF___INT8) && (STIO_SIZEOF___INT8 == 1)
# define STIO_HAVE_UINT8_T
# define STIO_HAVE_INT8_T
typedef unsigned __int8 stio_uint8_t;
typedef signed __int8 stio_int8_t;
#elif defined(STIO_SIZEOF___INT8_T) && (STIO_SIZEOF___INT8_T == 1)
# define STIO_HAVE_UINT8_T
# define STIO_HAVE_INT8_T
typedef unsigned __int8_t stio_uint8_t;
typedef signed __int8_t stio_int8_t;
#else
# define STIO_HAVE_UINT8_T
# define STIO_HAVE_INT8_T
typedef unsigned char stio_uint8_t;
typedef signed char stio_int8_t;
#endif
/* stio_int16_t */
#if defined(STIO_SIZEOF_SHORT) && (STIO_SIZEOF_SHORT == 2)
# define STIO_HAVE_UINT16_T
# define STIO_HAVE_INT16_T
typedef unsigned short int stio_uint16_t;
typedef signed short int stio_int16_t;
#elif defined(STIO_SIZEOF___INT16) && (STIO_SIZEOF___INT16 == 2)
# define STIO_HAVE_UINT16_T
# define STIO_HAVE_INT16_T
typedef unsigned __int16 stio_uint16_t;
typedef signed __int16 stio_int16_t;
#elif defined(STIO_SIZEOF___INT16_T) && (STIO_SIZEOF___INT16_T == 2)
# define STIO_HAVE_UINT16_T
# define STIO_HAVE_INT16_T
typedef unsigned __int16_t stio_uint16_t;
typedef signed __int16_t stio_int16_t;
#else
# define STIO_HAVE_UINT16_T
# define STIO_HAVE_INT16_T
typedef unsigned short int stio_uint16_t;
typedef signed short int stio_int16_t;
#endif
/* stio_int32_t */
#if defined(STIO_SIZEOF_INT) && (STIO_SIZEOF_INT == 4)
# define STIO_HAVE_UINT32_T
# define STIO_HAVE_INT32_T
typedef unsigned int stio_uint32_t;
typedef signed int stio_int32_t;
#elif defined(STIO_SIZEOF_LONG) && (STIO_SIZEOF_LONG == 4)
# define STIO_HAVE_UINT32_T
# define STIO_HAVE_INT32_T
typedef unsigned long stio_uint32_t;
typedef signed long stio_int32_t;
#elif defined(STIO_SIZEOF___INT32) && (STIO_SIZEOF___INT32 == 4)
# define STIO_HAVE_UINT32_T
# define STIO_HAVE_INT32_T
typedef unsigned __int32 stio_uint32_t;
typedef signed __int32 stio_int32_t;
#elif defined(STIO_SIZEOF___INT32_T) && (STIO_SIZEOF___INT32_T == 4)
# define STIO_HAVE_UINT32_T
# define STIO_HAVE_INT32_T
typedef unsigned __int32_t stio_uint32_t;
typedef signed __int32_t stio_int32_t;
#elif defined(__MSDOS__)
# define STIO_HAVE_UINT32_T
# define STIO_HAVE_INT32_T
typedef unsigned long int stio_uint32_t;
typedef signed long int stio_int32_t;
#else
# define STIO_HAVE_UINT32_T
# define STIO_HAVE_INT32_T
typedef unsigned int stio_uint32_t;
typedef signed int stio_int32_t;
#endif
/* stio_int64_t */
#if defined(STIO_SIZEOF_INT) && (STIO_SIZEOF_INT == 8)
# define STIO_HAVE_UINT64_T
# define STIO_HAVE_INT64_T
typedef unsigned int stio_uint64_t;
typedef signed int stio_int64_t;
#elif defined(STIO_SIZEOF_LONG) && (STIO_SIZEOF_LONG == 8)
# define STIO_HAVE_UINT64_T
# define STIO_HAVE_INT64_T
typedef unsigned long stio_uint64_t;
typedef signed long stio_int64_t;
#elif defined(STIO_SIZEOF_LONG_LONG) && (STIO_SIZEOF_LONG_LONG == 8)
# define STIO_HAVE_UINT64_T
# define STIO_HAVE_INT64_T
typedef unsigned long long stio_uint64_t;
typedef signed long long stio_int64_t;
#elif defined(STIO_SIZEOF___INT64) && (STIO_SIZEOF___INT64 == 8)
# define STIO_HAVE_UINT64_T
# define STIO_HAVE_INT64_T
typedef unsigned __int64 stio_uint64_t;
typedef signed __int64 stio_int64_t;
#elif defined(STIO_SIZEOF___INT64_T) && (STIO_SIZEOF___INT64_T == 8)
# define STIO_HAVE_UINT64_T
# define STIO_HAVE_INT64_T
typedef unsigned __int64_t stio_uint64_t;
typedef signed __int64_t stio_int64_t;
#elif defined(_WIN64) || defined(_WIN32)
# define STIO_HAVE_UINT64_T
# define STIO_HAVE_INT64_T
typedef unsigned __int64 stio_uint64_t;
typedef signed __int64 stio_int64_t;
#else
/* no 64-bit integer */
#endif
/* stio_int128_t */
#if defined(STIO_SIZEOF_INT) && (STIO_SIZEOF_INT == 16)
# define STIO_HAVE_UINT128_T
# define STIO_HAVE_INT128_T
typedef unsigned int stio_uint128_t;
typedef signed int stio_int128_t;
#elif defined(STIO_SIZEOF_LONG) && (STIO_SIZEOF_LONG == 16)
# define STIO_HAVE_UINT128_T
# define STIO_HAVE_INT128_T
typedef unsigned long stio_uint128_t;
typedef signed long stio_int128_t;
#elif defined(STIO_SIZEOF_LONG_LONG) && (STIO_SIZEOF_LONG_LONG == 16)
# define STIO_HAVE_UINT128_T
# define STIO_HAVE_INT128_T
typedef unsigned long long stio_uint128_t;
typedef signed long long stio_int128_t;
#elif defined(STIO_SIZEOF___INT128) && (STIO_SIZEOF___INT128 == 16)
# define STIO_HAVE_UINT128_T
# define STIO_HAVE_INT128_T
typedef unsigned __int128 stio_uint128_t;
typedef signed __int128 stio_int128_t;
#elif defined(STIO_SIZEOF___INT128_T) && (STIO_SIZEOF___INT128_T == 16)
# define STIO_HAVE_UINT128_T
# define STIO_HAVE_INT128_T
#if defined(__clang__)
typedef __uint128_t stio_uint128_t;
typedef __int128_t stio_int128_t;
#else
typedef unsigned __int128_t stio_uint128_t;
typedef signed __int128_t stio_int128_t;
#endif
#else
/* no 128-bit integer */
#endif
#if defined(STIO_HAVE_UINT8_T) && (STIO_SIZEOF_VOID_P == 1)
# error UNSUPPORTED POINTER SIZE
#elif defined(STIO_HAVE_UINT16_T) && (STIO_SIZEOF_VOID_P == 2)
typedef stio_uint16_t stio_uintptr_t;
typedef stio_int16_t stio_intptr_t;
typedef stio_uint8_t stio_ushortptr_t;
typedef stio_int8_t stio_shortptr_t;
#elif defined(STIO_HAVE_UINT32_T) && (STIO_SIZEOF_VOID_P == 4)
typedef stio_uint32_t stio_uintptr_t;
typedef stio_int32_t stio_intptr_t;
typedef stio_uint16_t stio_ushortptr_t;
typedef stio_int16_t stio_shortptr_t;
#elif defined(STIO_HAVE_UINT64_T) && (STIO_SIZEOF_VOID_P == 8)
typedef stio_uint64_t stio_uintptr_t;
typedef stio_int64_t stio_intptr_t;
typedef stio_uint32_t stio_ushortptr_t;
typedef stio_int32_t stio_shortptr_t;
#elif defined(STIO_HAVE_UINT128_T) && (STIO_SIZEOF_VOID_P == 16)
typedef stio_uint128_t stio_uintptr_t;
typedef stio_int128_t stio_intptr_t;
typedef stio_uint64_t stio_ushortptr_t;
typedef stio_int64_t stio_shortptr_t;
#else
# error UNKNOWN POINTER SIZE
#endif
#define STIO_SIZEOF_INTPTR_T STIO_SIZEOF_VOID_P
#define STIO_SIZEOF_UINTPTR_T STIO_SIZEOF_VOID_P
#define STIO_SIZEOF_SHORTPTR_T (STIO_SIZEOF_VOID_P / 2)
#define STIO_SIZEOF_USHORTPTR_T (STIO_SIZEOF_VOID_P / 2)
#if defined(STIO_HAVE_INT128_T)
# define STIO_SIZEOF_INTMAX_T 16
# define STIO_SIZEOF_UINTMAX_T 16
typedef stio_int128_t stio_intmax_t;
typedef stio_uint128_t stio_uintmax_t;
#elif defined(STIO_HAVE_INT64_T)
# define STIO_SIZEOF_INTMAX_T 8
# define STIO_SIZEOF_UINTMAX_T 8
typedef stio_int64_t stio_intmax_t;
typedef stio_uint64_t stio_uintmax_t;
#elif defined(STIO_HAVE_INT32_T)
# define STIO_SIZEOF_INTMAX_T 4
# define STIO_SIZEOF_UINTMAX_T 4
typedef stio_int32_t stio_intmax_t;
typedef stio_uint32_t stio_uintmax_t;
#elif defined(STIO_HAVE_INT16_T)
# define STIO_SIZEOF_INTMAX_T 2
# define STIO_SIZEOF_UINTMAX_T 2
typedef stio_int16_t stio_intmax_t;
typedef stio_uint16_t stio_uintmax_t;
#elif defined(STIO_HAVE_INT8_T)
# define STIO_SIZEOF_INTMAX_T 1
# define STIO_SIZEOF_UINTMAX_T 1
typedef stio_int8_t stio_intmax_t;
typedef stio_uint8_t stio_uintmax_t;
#else
# error UNKNOWN INTMAX SIZE
#endif
/* =========================================================================
* BASIC STIO TYPES
* =========================================================================*/
typedef stio_uint8_t stio_byte_t;
typedef stio_uintptr_t stio_size_t;
typedef char stio_mchar_t;
typedef int stio_mcint_t;
#define STIO_MT(x) (x)
/* =========================================================================
* PRIMITIVE MACROS
* ========================================================================= */
#define STIO_SIZEOF(x) (sizeof(x))
#define STIO_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
/**
* The STIO_OFFSETOF() macro returns the offset of a field from the beginning
* of a structure.
*/
#define STIO_OFFSETOF(type,member) ((stio_uintptr_t)&((type*)0)->member)
/**
* The STIO_ALIGNOF() macro returns the alignment size of a structure.
* Note that this macro may not work reliably depending on the type given.
*/
#define STIO_ALIGNOF(type) STIO_OFFSETOF(struct { stio_uint8_t d1; type d2; }, d2)
/*(sizeof(struct { stio_uint8_t d1; type d2; }) - sizeof(type))*/
/**
* Round up a positive integer to the nearest multiple of 'align'
*/
#define STIO_ALIGNTO(num,align) ((((num) + (align) - 1) / (align)) * (align))
#if 0
/**
* Round up a number, both positive and negative, to the nearest multiple of 'align'
*/
#define STIO_ALIGNTO(num,align) ((((num) + (num >= 0? 1: -1) * (align) - 1) / (align)) * (align))
#endif
/**
* Round up a positive integer to to the nearest multiple of 'align' which
* should be a multiple of a power of 2
*/
#define STIO_ALIGNTO_POW2(num,align) ((((num) + (align) - 1)) & ~((align) - 1))
#if defined(__cplusplus)
# if (__cplusplus >= 201103L) /* C++11 */
# define STIO_NULL nullptr
# else
# define STIO_NULL (0)
# endif
#else
# define STIO_NULL ((void*)0)
#endif
/* make a bit mask that can mask off low n bits */
#define STIO_LBMASK(type,n) (~(~((type)0) << (n)))
#define STIO_LBMASK_SAFE(type,n) (((n) < STIO_SIZEOF(type) * 8)? STIO_LBMASK(type,n): ~(type)0)
/* make a bit mask that can mask off hig n bits */
#define STIO_HBMASK(type,n) (~(~((type)0) >> (n)))
#define STIO_HBMASK_SAFE(type,n) (((n) < STIO_SIZEOF(type) * 8)? STIO_HBMASK(type,n): ~(type)0)
/* get 'length' bits starting from the bit at the 'offset' */
#define STIO_GETBITS(type,value,offset,length) \
((((type)(value)) >> (offset)) & STIO_LBMASK(type,length))
#define STIO_SETBITS(type,value,offset,length,bits) \
(value = (((type)(value)) | (((bits) & STIO_LBMASK(type,length)) << (offset))))
/**
* The STIO_BITS_MAX() macros calculates the maximum value that the 'nbits'
* bits of an unsigned integer of the given 'type' can hold.
* \code
* printf ("%u", STIO_BITS_MAX(unsigned int, 5));
* \endcode
*/
/*#define STIO_BITS_MAX(type,nbits) ((((type)1) << (nbits)) - 1)*/
#define STIO_BITS_MAX(type,nbits) ((~(type)0) >> (STIO_SIZEOF(type) * 8 - (nbits)))
/* =========================================================================
* MMGR
* ========================================================================= */
typedef struct stio_mmgr_t stio_mmgr_t;
/**
* allocate a memory chunk of the size \a n.
* \return pointer to a memory chunk on success, #STIO_NULL on failure.
*/
typedef void* (*stio_mmgr_alloc_t) (stio_mmgr_t* mmgr, stio_size_t n);
/**
* resize a memory chunk pointed to by \a ptr to the size \a n.
* \return pointer to a memory chunk on success, #STIO_NULL on failure.
*/
typedef void* (*stio_mmgr_realloc_t) (stio_mmgr_t* mmgr, void* ptr, stio_size_t n);
/**
* free a memory chunk pointed to by \a ptr.
*/
typedef void (*stio_mmgr_free_t) (stio_mmgr_t* mmgr, void* ptr);
/**
* The stio_mmgr_t type defines the memory management interface.
* As the type is merely a structure, it is just used as a single container
* for memory management functions with a pointer to user-defined data.
* The user-defined data pointer \a ctx is passed to each memory management
* function whenever it is called. You can allocate, reallocate, and free
* a memory chunk.
*
* For example, a stio_xxx_open() function accepts a pointer of the stio_mmgr_t
* type and the xxx object uses it to manage dynamic data within the object.
*/
struct stio_mmgr_t
{
stio_mmgr_alloc_t alloc; /**< allocation function */
stio_mmgr_realloc_t realloc; /**< resizing function */
stio_mmgr_free_t free; /**< disposal function */
void* ctx; /**< user-defined data pointer */
};
/**
* The STIO_MMGR_ALLOC() macro allocates a memory block of the \a size bytes
* using the \a mmgr memory manager.
*/
#define STIO_MMGR_ALLOC(mmgr,size) ((mmgr)->alloc(mmgr,size))
/**
* The STIO_MMGR_REALLOC() macro resizes a memory block pointed to by \a ptr
* to the \a size bytes using the \a mmgr memory manager.
*/
#define STIO_MMGR_REALLOC(mmgr,ptr,size) ((mmgr)->realloc(mmgr,ptr,size))
/**
* The STIO_MMGR_FREE() macro deallocates the memory block pointed to by \a ptr.
*/
#define STIO_MMGR_FREE(mmgr,ptr) ((mmgr)->free(mmgr,ptr))
/* =========================================================================
* MACROS THAT CHANGES THE BEHAVIORS OF THE C COMPILER/LINKER
* =========================================================================*/
#if defined(_WIN32) || (defined(__WATCOMC__) && !defined(__WINDOWS_386__))
# define STIO_IMPORT __declspec(dllimport)
# define STIO_EXPORT __declspec(dllexport)
# define STIO_PRIVATE
#elif defined(__GNUC__) && (__GNUC__>=4)
# define STIO_IMPORT __attribute__((visibility("default")))
# define STIO_EXPORT __attribute__((visibility("default")))
# define STIO_PRIVATE __attribute__((visibility("hidden")))
/*# define STIO_PRIVATE __attribute__((visibility("internal")))*/
#else
# define STIO_IMPORT
# define STIO_EXPORT
# define STIO_PRIVATE
#endif
#if defined(__STDC_VERSION__) && (__STDC_VERSION__>=199901L)
# define STIO_INLINE inline
# define STIO_HAVE_INLINE
#elif defined(__GNUC__) && defined(__GNUC_GNU_INLINE__)
/* gcc disables inline when -std=c89 or -ansi is used.
* so use __inline__ supported by gcc regardless of the options */
# define STIO_INLINE /*extern*/ __inline__
# define STIO_HAVE_INLINE
#else
# define STIO_INLINE
# undef STIO_HAVE_INLINE
#endif
/**
* The STIO_TYPE_IS_SIGNED() macro determines if a type is signed.
* \code
* printf ("%d\n", (int)STIO_TYPE_IS_SIGNED(int));
* printf ("%d\n", (int)STIO_TYPE_IS_SIGNED(unsigned int));
* \endcode
*/
#define STIO_TYPE_IS_SIGNED(type) (((type)0) > ((type)-1))
/**
* The STIO_TYPE_IS_SIGNED() macro determines if a type is unsigned.
* \code
* printf ("%d\n", STIO_TYPE_IS_UNSIGNED(int));
* printf ("%d\n", STIO_TYPE_IS_UNSIGNED(unsigned int));
* \endcode
*/
#define STIO_TYPE_IS_UNSIGNED(type) (((type)0) < ((type)-1))
#define STIO_TYPE_SIGNED_MAX(type) \
((type)~((type)1 << ((type)STIO_SIZEOF(type) * 8 - 1)))
#define STIO_TYPE_UNSIGNED_MAX(type) ((type)(~(type)0))
#define STIO_TYPE_SIGNED_MIN(type) \
((type)((type)1 << ((type)STIO_SIZEOF(type) * 8 - 1)))
#define STIO_TYPE_UNSIGNED_MIN(type) ((type)0)
#define STIO_TYPE_MAX(type) \
((STIO_TYPE_IS_SIGNED(type)? STIO_TYPE_SIGNED_MAX(type): STIO_TYPE_UNSIGNED_MAX(type)))
#define STIO_TYPE_MIN(type) \
((STIO_TYPE_IS_SIGNED(type)? STIO_TYPE_SIGNED_MIN(type): STIO_TYPE_UNSIGNED_MIN(type)))
/* =========================================================================
* COMPILER FEATURE TEST MACROS
* =========================================================================*/
#if defined(__has_builtin)
#if __has_builtin(__builtin_ctz)
#define STIO_HAVE_BUILTIN_CTZ
#endif
#if __has_builtin(__builtin_uadd_overflow)
#define STIO_HAVE_BUILTIN_UADD_OVERFLOW
#endif
#if __has_builtin(__builtin_uaddl_overflow)
#define STIO_HAVE_BUILTIN_UADDL_OVERFLOW
#endif
#if __has_builtin(__builtin_uaddll_overflow)
#define STIO_HAVE_BUILTIN_UADDLL_OVERFLOW
#endif
#if __has_builtin(__builtin_umul_overflow)
#define STIO_HAVE_BUILTIN_UMUL_OVERFLOW
#endif
#if __has_builtin(__builtin_umull_overflow)
#define STIO_HAVE_BUILTIN_UMULL_OVERFLOW
#endif
#if __has_builtin(__builtin_umulll_overflow)
#define STIO_HAVE_BUILTIN_UMULLL_OVERFLOW
#endif
#if __has_builtin(__builtin_sadd_overflow)
#define STIO_HAVE_BUILTIN_SADD_OVERFLOW
#endif
#if __has_builtin(__builtin_saddl_overflow)
#define STIO_HAVE_BUILTIN_SADDL_OVERFLOW
#endif
#if __has_builtin(__builtin_saddll_overflow)
#define STIO_HAVE_BUILTIN_SADDLL_OVERFLOW
#endif
#if __has_builtin(__builtin_smul_overflow)
#define STIO_HAVE_BUILTIN_SMUL_OVERFLOW
#endif
#if __has_builtin(__builtin_smull_overflow)
#define STIO_HAVE_BUILTIN_SMULL_OVERFLOW
#endif
#if __has_builtin(__builtin_smulll_overflow)
#define STIO_HAVE_BUILTIN_SMULLL_OVERFLOW
#endif
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#define STIO_HAVE_BUILTIN_CTZ
#endif
#if (__GNUC__ >= 5)
#define STIO_HAVE_BUILTIN_UADD_OVERFLOW
#define STIO_HAVE_BUILTIN_UADDL_OVERFLOW
#define STIO_HAVE_BUILTIN_UADDLL_OVERFLOW
#define STIO_HAVE_BUILTIN_UMUL_OVERFLOW
#define STIO_HAVE_BUILTIN_UMULL_OVERFLOW
#define STIO_HAVE_BUILTIN_UMULLL_OVERFLOW
#define STIO_HAVE_BUILTIN_SADD_OVERFLOW
#define STIO_HAVE_BUILTIN_SADDL_OVERFLOW
#define STIO_HAVE_BUILTIN_SADDLL_OVERFLOW
#define STIO_HAVE_BUILTIN_SMUL_OVERFLOW
#define STIO_HAVE_BUILTIN_SMULL_OVERFLOW
#define STIO_HAVE_BUILTIN_SMULLL_OVERFLOW
#endif
#endif
/*
#if !defined(__has_builtin)
#define __has_builtin(x) 0
#endif
#if !defined(__is_identifier)
#define __is_identifier(x) 0
#endif
#if !defined(__has_attribute)
#define __has_attribute(x) 0
#endif
*/
#endif

View File

@ -1,846 +0,0 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "stio-pro.h"
#include "stio-prv.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>
/* ========================================================================= */
struct slave_info_t
{
stio_dev_pro_make_t* mi;
stio_syshnd_t pfd;
int dev_capa;
stio_dev_pro_sid_t id;
};
typedef struct slave_info_t slave_info_t;
static stio_dev_pro_slave_t* make_slave (stio_t* stio, slave_info_t* si);
/* ========================================================================= */
struct param_t
{
stio_mchar_t* mcmd;
stio_mchar_t* fixed_argv[4];
stio_mchar_t** argv;
};
typedef struct param_t param_t;
static void free_param (stio_t* stio, param_t* param)
{
if (param->argv && param->argv != param->fixed_argv)
STIO_MMGR_FREE (stio->mmgr, param->argv);
if (param->mcmd) STIO_MMGR_FREE (stio->mmgr, param->mcmd);
STIO_MEMSET (param, 0, STIO_SIZEOF(*param));
}
static int make_param (stio_t* stio, const stio_mchar_t* cmd, int flags, param_t* param)
{
int fcnt = 0;
stio_mchar_t* mcmd = STIO_NULL;
STIO_MEMSET (param, 0, STIO_SIZEOF(*param));
if (flags & STIO_DEV_PRO_SHELL)
{
mcmd = (stio_mchar_t*)cmd;
param->argv = param->fixed_argv;
param->argv[0] = STIO_MT("/bin/sh");
param->argv[1] = STIO_MT("-c");
param->argv[2] = mcmd;
param->argv[3] = STIO_NULL;
}
else
{
int i;
stio_mchar_t** argv;
stio_mchar_t* mcmdptr;
mcmd = stio_mbsdup (stio, cmd);
if (!mcmd) goto oops;
fcnt = stio_mbsspl (mcmd, STIO_MT(""), STIO_MT('\"'), STIO_MT('\"'), STIO_MT('\\'));
if (fcnt <= 0)
{
/* no field or an error */
stio->errnum = STIO_EINVAL;
goto oops;
}
if (fcnt < STIO_COUNTOF(param->fixed_argv))
{
param->argv = param->fixed_argv;
}
else
{
param->argv = STIO_MMGR_ALLOC (stio->mmgr, (fcnt + 1) * STIO_SIZEOF(argv[0]));
if (param->argv == STIO_NULL)
{
stio->errnum = STIO_ENOMEM;
goto oops;
}
}
mcmdptr = mcmd;
for (i = 0; i < fcnt; i++)
{
param->argv[i] = mcmdptr;
while (*mcmdptr != STIO_MT('\0')) mcmdptr++;
mcmdptr++;
}
param->argv[i] = STIO_NULL;
}
if (mcmd && mcmd != (stio_mchar_t*)cmd) param->mcmd = mcmd;
return 0;
oops:
if (mcmd && mcmd != cmd) STIO_MMGR_FREE (stio->mmgr, mcmd);
return -1;
}
static pid_t standard_fork_and_exec (stio_t* stio, int pfds[], int flags, param_t* param)
{
pid_t pid;
pid = fork ();
if (pid == -1)
{
stio->errnum = stio_syserrtoerrnum(errno);
return -1;
}
if (pid == 0)
{
/* slave process */
stio_syshnd_t devnull = STIO_SYSHND_INVALID;
/* TODO: close all uneeded fds */
if (flags & STIO_DEV_PRO_WRITEIN)
{
/* slave should read */
close (pfds[1]);
pfds[1] = STIO_SYSHND_INVALID;
/* let the pipe be standard input */
if (dup2 (pfds[0], 0) <= -1) goto slave_oops;
close (pfds[0]);
pfds[0] = STIO_SYSHND_INVALID;
}
if (flags & STIO_DEV_PRO_READOUT)
{
/* slave should write */
close (pfds[2]);
pfds[2] = STIO_SYSHND_INVALID;
if (dup2(pfds[3], 1) == -1) goto slave_oops;
if (flags & STIO_DEV_PRO_ERRTOOUT)
{
if (dup2(pfds[3], 2) == -1) goto slave_oops;
}
close (pfds[3]);
pfds[3] = STIO_SYSHND_INVALID;
}
if (flags & STIO_DEV_PRO_READERR)
{
close (pfds[4]);
pfds[4] = STIO_SYSHND_INVALID;
if (dup2(pfds[5], 2) == -1) goto slave_oops;
if (flags & STIO_DEV_PRO_OUTTOERR)
{
if (dup2(pfds[5], 1) == -1) goto slave_oops;
}
close (pfds[5]);
pfds[5] = STIO_SYSHND_INVALID;
}
if ((flags & STIO_DEV_PRO_INTONUL) ||
(flags & STIO_DEV_PRO_OUTTONUL) ||
(flags & STIO_DEV_PRO_ERRTONUL))
{
#if defined(O_LARGEFILE)
devnull = open (STIO_MT("/dev/null"), O_RDWR | O_LARGEFILE, 0);
#else
devnull = open (STIO_MT("/dev/null"), O_RDWR, 0);
#endif
if (devnull == STIO_SYSHND_INVALID) goto slave_oops;
}
execv (param->argv[0], param->argv);
/* if exec fails, free 'param' parameter which is an inherited pointer */
free_param (stio, param);
slave_oops:
if (devnull != STIO_SYSHND_INVALID) close(devnull);
_exit (128);
}
/* parent process */
return pid;
}
static int dev_pro_make_master (stio_dev_t* dev, void* ctx)
{
stio_dev_pro_t* rdev = (stio_dev_pro_t*)dev;
stio_dev_pro_make_t* info = (stio_dev_pro_make_t*)ctx;
stio_syshnd_t pfds[6];
int i, minidx = -1, maxidx = -1;
param_t param;
pid_t pid;
if (info->flags & STIO_DEV_PRO_WRITEIN)
{
if (pipe(&pfds[0]) == -1)
{
dev->stio->errnum = stio_syserrtoerrnum(errno);
goto oops;
}
minidx = 0; maxidx = 1;
}
if (info->flags & STIO_DEV_PRO_READOUT)
{
if (pipe(&pfds[2]) == -1)
{
dev->stio->errnum = stio_syserrtoerrnum(errno);
goto oops;
}
if (minidx == -1) minidx = 2;
maxidx = 3;
}
if (info->flags & STIO_DEV_PRO_READERR)
{
if (pipe(&pfds[4]) == -1)
{
dev->stio->errnum = stio_syserrtoerrnum(errno);
goto oops;
}
if (minidx == -1) minidx = 4;
maxidx = 5;
}
if (maxidx == -1)
{
dev->stio->errnum = STIO_EINVAL;
goto oops;
}
if (make_param (rdev->stio, info->cmd, info->flags, &param) <= -1) goto oops;
/* TODO: more advanced fork and exec .. */
pid = standard_fork_and_exec (rdev->stio, pfds, info->flags, &param);
if (pid <= -1)
{
free_param (rdev->stio, &param);
goto oops;
}
free_param (rdev->stio, &param);
rdev->child_pid = pid;
/* this is the parent process */
if (info->flags & STIO_DEV_PRO_WRITEIN)
{
/*
* 012345
* rw----
* X
* WRITE => 1
*/
close (pfds[0]);
pfds[0] = STIO_SYSHND_INVALID;
if (stio_makesyshndasync (dev->stio, pfds[1]) <= -1) goto oops;
}
if (info->flags & STIO_DEV_PRO_READOUT)
{
/*
* 012345
* --rw--
* X
* READ => 2
*/
close (pfds[3]);
pfds[3] = STIO_SYSHND_INVALID;
if (stio_makesyshndasync (dev->stio, pfds[2]) <= -1) goto oops;
}
if (info->flags & STIO_DEV_PRO_READERR)
{
/*
* 012345
* ----rw
* X
* READ => 4
*/
close (pfds[5]);
pfds[5] = STIO_SYSHND_INVALID;
if (stio_makesyshndasync (dev->stio, pfds[4]) <= -1) goto oops;
}
if (pfds[1] != STIO_SYSHND_INVALID)
{
/* hand over pfds[2] to the first slave device */
slave_info_t si;
si.mi = info;
si.pfd = pfds[1];
si.dev_capa = STIO_DEV_CAPA_OUT | STIO_DEV_CAPA_OUT_QUEUED | STIO_DEV_CAPA_STREAM;
si.id = STIO_DEV_PRO_IN;
rdev->slave[STIO_DEV_PRO_IN] = make_slave (dev->stio, &si);
if (!rdev->slave[STIO_DEV_PRO_IN]) goto oops;
pfds[1] = STIO_SYSHND_INVALID;
rdev->slave_count++;
}
if (pfds[2] != STIO_SYSHND_INVALID)
{
/* hand over pfds[2] to the first slave device */
slave_info_t si;
si.mi = info;
si.pfd = pfds[2];
si.dev_capa = STIO_DEV_CAPA_IN | STIO_DEV_CAPA_STREAM;
si.id = STIO_DEV_PRO_OUT;
rdev->slave[STIO_DEV_PRO_OUT] = make_slave (dev->stio, &si);
if (!rdev->slave[STIO_DEV_PRO_OUT]) goto oops;
pfds[2] = STIO_SYSHND_INVALID;
rdev->slave_count++;
}
if (pfds[4] != STIO_SYSHND_INVALID)
{
/* hand over pfds[4] to the second slave device */
slave_info_t si;
si.mi = info;
si.pfd = pfds[4];
si.dev_capa = STIO_DEV_CAPA_IN | STIO_DEV_CAPA_STREAM;
si.id = STIO_DEV_PRO_ERR;
rdev->slave[STIO_DEV_PRO_ERR] = make_slave (dev->stio, &si);
if (!rdev->slave[STIO_DEV_PRO_ERR]) goto oops;
pfds[4] = STIO_SYSHND_INVALID;
rdev->slave_count++;
}
for (i = 0; i < STIO_COUNTOF(rdev->slave); i++)
{
if (rdev->slave[i]) rdev->slave[i]->master = rdev;
}
rdev->dev_capa = STIO_DEV_CAPA_VIRTUAL; /* the master device doesn't perform I/O */
rdev->flags = info->flags;
rdev->on_read = info->on_read;
rdev->on_write = info->on_write;
rdev->on_close = info->on_close;
return 0;
oops:
for (i = minidx; i < maxidx; i++)
{
if (pfds[i] != STIO_SYSHND_INVALID) close (pfds[i]);
}
if (rdev->mcmd)
{
STIO_MMGR_FREE (rdev->stio->mmgr, rdev->mcmd);
free_param (rdev->stio, &param);
}
for (i = STIO_COUNTOF(rdev->slave); i > 0; )
{
i--;
if (rdev->slave[i])
{
stio_killdev (rdev->stio, (stio_dev_t*)rdev->slave[i]);
rdev->slave[i] = STIO_NULL;
}
}
rdev->slave_count = 0;
return -1;
}
static int dev_pro_make_slave (stio_dev_t* dev, void* ctx)
{
stio_dev_pro_slave_t* rdev = (stio_dev_pro_slave_t*)dev;
slave_info_t* si = (slave_info_t*)ctx;
rdev->dev_capa = si->dev_capa;
rdev->id = si->id;
rdev->pfd = si->pfd;
/* keep rdev->master to STIO_NULL. it's set to the right master
* device in dev_pro_make() */
return 0;
}
static int dev_pro_kill_master (stio_dev_t* dev, int force)
{
stio_dev_pro_t* rdev = (stio_dev_pro_t*)dev;
int i, status;
pid_t wpid;
if (rdev->slave_count > 0)
{
for (i = 0; i < STIO_COUNTOF(rdev->slave); i++)
{
if (rdev->slave[i])
{
stio_dev_pro_slave_t* sdev = rdev->slave[i];
/* nullify the pointer to the slave device
* before calling stio_killdev() on the slave device.
* the slave device can check this pointer to tell from
* self-initiated termination or master-driven termination */
rdev->slave[i] = STIO_NULL;
stio_killdev (rdev->stio, (stio_dev_t*)sdev);
}
}
}
if (rdev->child_pid >= 0)
{
if (!(rdev->flags & STIO_DEV_PRO_FORGET_CHILD))
{
int killed = 0;
await_child:
wpid = waitpid (rdev->child_pid, &status, WNOHANG);
if (wpid == 0)
{
if (force && !killed)
{
if (!(rdev->flags & STIO_DEV_PRO_FORGET_DIEHARD_CHILD))
{
kill (rdev->child_pid, SIGKILL);
killed = 1;
goto await_child;
}
}
else
{
/* child process is still alive */
rdev->stio->errnum = STIO_EAGAIN;
return -1; /* call me again */
}
}
/* wpid == rdev->child_pid => full success
* wpid == -1 && errno == ECHILD => no such process. it's waitpid()'ed by some other part of the program?
* other cases ==> can't really handle properly. forget it by returning success
* no need not worry about EINTR because errno can't have the value when WNOHANG is set.
*/
}
printf (">>>>>>>>>>>>>>>>>>> REAPED CHILD %d\n", (int)rdev->child_pid);
rdev->child_pid = -1;
}
if (rdev->on_close) rdev->on_close (rdev, STIO_DEV_PRO_MASTER);
return 0;
}
static int dev_pro_kill_slave (stio_dev_t* dev, int force)
{
stio_dev_pro_slave_t* rdev = (stio_dev_pro_slave_t*)dev;
if (rdev->master)
{
stio_dev_pro_t* master;
master = rdev->master;
rdev->master = STIO_NULL;
/* indicate EOF */
if (master->on_close) master->on_close (master, rdev->id);
STIO_ASSERT (master->slave_count > 0);
master->slave_count--;
if (master->slave[rdev->id])
{
/* this call is started by the slave device itself.
* if this is the last slave, kill the master also */
if (master->slave_count <= 0)
{
stio_killdev (rdev->stio, (stio_dev_t*)master);
/* the master pointer is not valid from this point onwards
* as the actual master device object is freed in stio_killdev() */
}
}
else
{
/* this call is initiated by this slave device itself.
* if it were by the master device, it would be STIO_NULL as
* nullified by the dev_pro_kill() */
master->slave[rdev->id] = STIO_NULL;
}
}
if (rdev->pfd != STIO_SYSHND_INVALID)
{
close (rdev->pfd);
rdev->pfd = STIO_SYSHND_INVALID;
}
return 0;
}
static int dev_pro_read_slave (stio_dev_t* dev, void* buf, stio_iolen_t* len, stio_devaddr_t* srcaddr)
{
stio_dev_pro_slave_t* pro = (stio_dev_pro_slave_t*)dev;
ssize_t x;
x = read (pro->pfd, buf, *len);
if (x <= -1)
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data available */
if (errno == EINTR) return 0;
pro->stio->errnum = stio_syserrtoerrnum(errno);
return -1;
}
*len = x;
return 1;
}
static int dev_pro_write_slave (stio_dev_t* dev, const void* data, stio_iolen_t* len, const stio_devaddr_t* dstaddr)
{
stio_dev_pro_slave_t* pro = (stio_dev_pro_slave_t*)dev;
ssize_t x;
x = write (pro->pfd, data, *len);
if (x <= -1)
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */
if (errno == EINTR) return 0;
pro->stio->errnum = stio_syserrtoerrnum(errno);
return -1;
}
*len = x;
return 1;
}
static stio_syshnd_t dev_pro_getsyshnd (stio_dev_t* dev)
{
return STIO_SYSHND_INVALID;
}
static stio_syshnd_t dev_pro_getsyshnd_slave (stio_dev_t* dev)
{
stio_dev_pro_slave_t* pro = (stio_dev_pro_slave_t*)dev;
return (stio_syshnd_t)pro->pfd;
}
static int dev_pro_ioctl (stio_dev_t* dev, int cmd, void* arg)
{
stio_dev_pro_t* rdev = (stio_dev_pro_t*)dev;
switch (cmd)
{
case STIO_DEV_PRO_CLOSE:
{
stio_dev_pro_sid_t sid = *(stio_dev_pro_sid_t*)arg;
if (sid < STIO_DEV_PRO_IN || sid > STIO_DEV_PRO_ERR)
{
rdev->stio->errnum = STIO_EINVAL;
return -1;
}
if (rdev->slave[sid])
{
/* unlike dev_pro_kill_master(), i don't nullify rdev->slave[sid].
* so i treat the closing ioctl as if it's a kill request
* initiated by the slave device itself. */
stio_killdev (rdev->stio, (stio_dev_t*)rdev->slave[sid]);
}
return 0;
}
case STIO_DEV_PRO_KILL_CHILD:
if (rdev->child_pid >= 0)
{
if (kill (rdev->child_pid, SIGKILL) == -1)
{
rdev->stio->errnum = stio_syserrtoerrnum(errno);
return -1;
}
}
return 0;
default:
dev->stio->errnum = STIO_EINVAL;
return -1;
}
}
static stio_dev_mth_t dev_pro_methods =
{
dev_pro_make_master,
dev_pro_kill_master,
dev_pro_getsyshnd,
STIO_NULL,
STIO_NULL,
dev_pro_ioctl
};
static stio_dev_mth_t dev_pro_methods_slave =
{
dev_pro_make_slave,
dev_pro_kill_slave,
dev_pro_getsyshnd_slave,
dev_pro_read_slave,
dev_pro_write_slave,
dev_pro_ioctl
};
/* ========================================================================= */
static int pro_ready (stio_dev_t* dev, int events)
{
/* virtual device. no I/O */
dev->stio->errnum = STIO_EINTERN;
return -1;
}
static int pro_on_read (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_devaddr_t* srcaddr)
{
/* virtual device. no I/O */
dev->stio->errnum = STIO_EINTERN;
return -1;
}
static int pro_on_write (stio_dev_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_devaddr_t* dstaddr)
{
/* virtual device. no I/O */
dev->stio->errnum = STIO_EINTERN;
return -1;
}
static stio_dev_evcb_t dev_pro_event_callbacks =
{
pro_ready,
pro_on_read,
pro_on_write
};
/* ========================================================================= */
static int pro_ready_slave (stio_dev_t* dev, int events)
{
stio_dev_pro_t* pro = (stio_dev_pro_t*)dev;
if (events & STIO_DEV_EVENT_ERR)
{
pro->stio->errnum = STIO_EDEVERR;
return -1;
}
if (events & STIO_DEV_EVENT_HUP)
{
if (events & (STIO_DEV_EVENT_PRI | STIO_DEV_EVENT_IN | STIO_DEV_EVENT_OUT))
{
/* probably half-open? */
return 1;
}
pro->stio->errnum = STIO_EDEVHUP;
return -1;
}
return 1; /* the device is ok. carry on reading or writing */
}
static int pro_on_read_slave_out (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_devaddr_t* srcaddr)
{
stio_dev_pro_slave_t* pro = (stio_dev_pro_slave_t*)dev;
return pro->master->on_read (pro->master, data, len, STIO_DEV_PRO_OUT);
}
static int pro_on_read_slave_err (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_devaddr_t* srcaddr)
{
stio_dev_pro_slave_t* pro = (stio_dev_pro_slave_t*)dev;
return pro->master->on_read (pro->master, data, len, STIO_DEV_PRO_ERR);
}
static int pro_on_write_slave (stio_dev_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_devaddr_t* dstaddr)
{
stio_dev_pro_slave_t* pro = (stio_dev_pro_slave_t*)dev;
return pro->master->on_write (pro->master, wrlen, wrctx);
}
static stio_dev_evcb_t dev_pro_event_callbacks_slave_in =
{
pro_ready_slave,
STIO_NULL,
pro_on_write_slave
};
static stio_dev_evcb_t dev_pro_event_callbacks_slave_out =
{
pro_ready_slave,
pro_on_read_slave_out,
STIO_NULL
};
static stio_dev_evcb_t dev_pro_event_callbacks_slave_err =
{
pro_ready_slave,
pro_on_read_slave_err,
STIO_NULL
};
/* ========================================================================= */
static stio_dev_pro_slave_t* make_slave (stio_t* stio, slave_info_t* si)
{
switch (si->id)
{
case STIO_DEV_PRO_IN:
return (stio_dev_pro_slave_t*)stio_makedev (
stio, STIO_SIZEOF(stio_dev_pro_t),
&dev_pro_methods_slave, &dev_pro_event_callbacks_slave_in, si);
case STIO_DEV_PRO_OUT:
return (stio_dev_pro_slave_t*)stio_makedev (
stio, STIO_SIZEOF(stio_dev_pro_t),
&dev_pro_methods_slave, &dev_pro_event_callbacks_slave_out, si);
case STIO_DEV_PRO_ERR:
return (stio_dev_pro_slave_t*)stio_makedev (
stio, STIO_SIZEOF(stio_dev_pro_t),
&dev_pro_methods_slave, &dev_pro_event_callbacks_slave_err, si);
default:
stio->errnum = STIO_EINVAL;
return STIO_NULL;
}
}
stio_dev_pro_t* stio_dev_pro_make (stio_t* stio, stio_size_t xtnsize, const stio_dev_pro_make_t* info)
{
return (stio_dev_pro_t*)stio_makedev (
stio, STIO_SIZEOF(stio_dev_pro_t) + xtnsize,
&dev_pro_methods, &dev_pro_event_callbacks, (void*)info);
}
void stio_dev_pro_kill (stio_dev_pro_t* dev)
{
stio_killdev (dev->stio, (stio_dev_t*)dev);
}
int stio_dev_pro_write (stio_dev_pro_t* dev, const void* data, stio_iolen_t dlen, void* wrctx)
{
if (dev->slave[0])
{
return stio_dev_write ((stio_dev_t*)dev->slave[0], data, dlen, wrctx, STIO_NULL);
}
else
{
dev->stio->errnum = STIO_ENOCAPA; /* TODO: is it the right error number? */
return -1;
}
}
int stio_dev_pro_timedwrite (stio_dev_pro_t* dev, const void* data, stio_iolen_t dlen, const stio_ntime_t* tmout, void* wrctx)
{
if (dev->slave[0])
{
return stio_dev_timedwrite ((stio_dev_t*)dev->slave[0], data, dlen, tmout, wrctx, STIO_NULL);
}
else
{
dev->stio->errnum = STIO_ENOCAPA; /* TODO: is it the right error number? */
return -1;
}
}
int stio_dev_pro_close (stio_dev_pro_t* dev, stio_dev_pro_sid_t sid)
{
return stio_dev_ioctl ((stio_dev_t*)dev, STIO_DEV_PRO_CLOSE, &sid);
}
int stio_dev_pro_killchild (stio_dev_pro_t* dev)
{
return stio_dev_ioctl ((stio_dev_t*)dev, STIO_DEV_PRO_KILL_CHILD, STIO_NULL);
}
#if 0
stio_dev_pro_t* stio_dev_pro_getdev (stio_dev_pro_t* pro, stio_dev_pro_sid_t sid)
{
switch (type)
{
case STIO_DEV_PRO_IN:
return XXX;
case STIO_DEV_PRO_OUT:
return XXX;
case STIO_DEV_PRO_ERR:
return XXX;
}
pro->dev->stio = STIO_EINVAL;
return STIO_NULL;
}
#endif

View File

@ -1,164 +0,0 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STIO_PRO_H_
#define _STIO_PRO_H_
#include <stio.h>
enum stio_dev_pro_sid_t
{
STIO_DEV_PRO_MASTER = -1,
STIO_DEV_PRO_IN = 0,
STIO_DEV_PRO_OUT = 1,
STIO_DEV_PRO_ERR = 2
};
typedef enum stio_dev_pro_sid_t stio_dev_pro_sid_t;
typedef struct stio_dev_pro_t stio_dev_pro_t;
typedef struct stio_dev_pro_slave_t stio_dev_pro_slave_t;
typedef int (*stio_dev_pro_on_read_t) (stio_dev_pro_t* dev, const void* data, stio_iolen_t len, stio_dev_pro_sid_t sid);
typedef int (*stio_dev_pro_on_write_t) (stio_dev_pro_t* dev, stio_iolen_t wrlen, void* wrctx);
typedef void (*stio_dev_pro_on_close_t) (stio_dev_pro_t* dev, stio_dev_pro_sid_t sid);
struct stio_dev_pro_t
{
STIO_DEV_HEADERS;
int flags;
stio_intptr_t child_pid;
stio_dev_pro_slave_t* slave[3];
int slave_count;
stio_dev_pro_on_read_t on_read;
stio_dev_pro_on_write_t on_write;
stio_dev_pro_on_close_t on_close;
stio_mchar_t* mcmd;
};
struct stio_dev_pro_slave_t
{
STIO_DEV_HEADERS;
stio_dev_pro_sid_t id;
stio_syshnd_t pfd;
stio_dev_pro_t* master; /* parent device */
};
enum stio_dev_pro_make_flag_t
{
STIO_DEV_PRO_WRITEIN = (1 << 0),
STIO_DEV_PRO_READOUT = (1 << 1),
STIO_DEV_PRO_READERR = (1 << 2),
STIO_DEV_PRO_ERRTOOUT = (1 << 3),
STIO_DEV_PRO_OUTTOERR = (1 << 4),
STIO_DEV_PRO_INTONUL = (1 << 5),
STIO_DEV_PRO_OUTTONUL = (1 << 6),
STIO_DEV_PRO_ERRTONUL = (1 << 7),
STUO_DEV_PRO_DROPIN = (1 << 8),
STUO_DEV_PRO_DROPOUT = (1 << 9),
STUO_DEV_PRO_DROPERR = (1 << 10),
STIO_DEV_PRO_SHELL = (1 << 13),
/* perform no waitpid() on a child process upon device destruction.
* you should set this flag if your application has automatic child
* process reaping enabled. for instance, SIGCHLD is set to SIG_IGN
* on POSIX.1-2001 compliant systems */
STIO_DEV_PRO_FORGET_CHILD = (1 << 14),
STIO_DEV_PRO_FORGET_DIEHARD_CHILD = (1 << 15)
};
typedef enum stio_dev_pro_make_flag_t stio_dev_pro_make_flag_t;
typedef struct stio_dev_pro_make_t stio_dev_pro_make_t;
struct stio_dev_pro_make_t
{
int flags; /**< bitwise-ORed of stio_dev_pro_make_flag_t enumerators */
const void* cmd;
stio_dev_pro_on_write_t on_write; /* mandatory */
stio_dev_pro_on_read_t on_read; /* mandatory */
stio_dev_pro_on_close_t on_close; /* optional */
};
enum stio_dev_pro_ioctl_cmd_t
{
STIO_DEV_PRO_CLOSE,
STIO_DEV_PRO_KILL_CHILD
};
typedef enum stio_dev_pro_ioctl_cmd_t stio_dev_pro_ioctl_cmd_t;
#ifdef __cplusplus
extern "C" {
#endif
STIO_EXPORT stio_dev_pro_t* stio_dev_pro_make (
stio_t* stio,
stio_size_t xtnsize,
const stio_dev_pro_make_t* data
);
STIO_EXPORT void stio_dev_pro_kill (
stio_dev_pro_t* pro
);
STIO_EXPORT int stio_dev_pro_write (
stio_dev_pro_t* pro,
const void* data,
stio_iolen_t len,
void* wrctx
);
STIO_EXPORT int stio_dev_pro_timedwrite (
stio_dev_pro_t* pro,
const void* data,
stio_iolen_t len,
const stio_ntime_t* tmout,
void* wrctx
);
STIO_EXPORT int stio_dev_pro_close (
stio_dev_pro_t* pro,
stio_dev_pro_sid_t sid
);
STIO_EXPORT int stio_dev_pro_killchild (
stio_dev_pro_t* pro
);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,204 +0,0 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STIO_PRV_H_
#define _STIO_PRV_H_
#include "stio.h"
/*TODO: redefine and remove these */
#include <assert.h>
#include <string.h>
#include <stdio.h>
/*TODO: redefine these */
#define STIO_MEMSET(dst,byte,count) memset(dst,byte,count)
#define STIO_MEMCPY(dst,src,count) memcpy(dst,src,count)
#define STIO_MEMMOVE(dst,src,count) memmove(dst,src,count)
#define STIO_MEMCMP(dst,src,count) memcmp(dst,src,count)
#define STIO_ASSERT assert
typedef struct stio_mux_t stio_mux_t;
struct stio_t
{
stio_mmgr_t* mmgr;
stio_errnum_t errnum;
stio_stopreq_t stopreq; /* stop request to abort stio_loop() */
struct
{
stio_dev_t* head;
stio_dev_t* tail;
} actdev; /* active devices */
struct
{
stio_dev_t* head;
stio_dev_t* tail;
} hltdev; /* halted devices */
struct
{
stio_dev_t* head;
stio_dev_t* tail;
} zmbdev; /* zombie devices */
stio_uint8_t bigbuf[65535]; /* TODO: make this dynamic depending on devices added. device may indicate a buffer size required??? */
unsigned int renew_watch: 1;
unsigned int in_exec: 1;
struct
{
stio_size_t capa;
stio_size_t size;
stio_tmrjob_t* jobs;
} tmr;
/* platform specific fields below */
#if defined(_WIN32)
HANDLE iocp;
#else
stio_mux_t* mux;
#endif
};
#define STIO_EPOCH_YEAR (1970)
#define STIO_EPOCH_MON (1)
#define STIO_EPOCH_DAY (1)
#define STIO_EPOCH_WDAY (4)
/* windows specific epoch time */
#define STIO_EPOCH_YEAR_WIN (1601)
#define STIO_EPOCH_MON_WIN (1)
#define STIO_EPOCH_DAY_WIN (1)
#define STIO_DAYS_PER_WEEK (7)
#define STIO_MONS_PER_YEAR (12)
#define STIO_HOURS_PER_DAY (24)
#define STIO_MINS_PER_HOUR (60)
#define STIO_MINS_PER_DAY (STIO_MINS_PER_HOUR*STIO_HOURS_PER_DAY)
#define STIO_SECS_PER_MIN (60)
#define STIO_SECS_PER_HOUR (STIO_SECS_PER_MIN*STIO_MINS_PER_HOUR)
#define STIO_SECS_PER_DAY (STIO_SECS_PER_MIN*STIO_MINS_PER_DAY)
#define STIO_MSECS_PER_SEC (1000)
#define STIO_MSECS_PER_MIN (STIO_MSECS_PER_SEC*STIO_SECS_PER_MIN)
#define STIO_MSECS_PER_HOUR (STIO_MSECS_PER_SEC*STIO_SECS_PER_HOUR)
#define STIO_MSECS_PER_DAY (STIO_MSECS_PER_SEC*STIO_SECS_PER_DAY)
#define STIO_USECS_PER_MSEC (1000)
#define STIO_NSECS_PER_USEC (1000)
#define STIO_NSECS_PER_MSEC (STIO_NSECS_PER_USEC*STIO_USECS_PER_MSEC)
#define STIO_USECS_PER_SEC (STIO_USECS_PER_MSEC*STIO_MSECS_PER_SEC)
#define STIO_NSECS_PER_SEC (STIO_NSECS_PER_USEC*STIO_USECS_PER_MSEC*STIO_MSECS_PER_SEC)
#define STIO_SECNSEC_TO_MSEC(sec,nsec) \
(((stio_intptr_t)(sec) * STIO_MSECS_PER_SEC) + ((stio_intptr_t)(nsec) / STIO_NSECS_PER_MSEC))
#define STIO_SECNSEC_TO_USEC(sec,nsec) \
(((stio_intptr_t)(sec) * STIO_USECS_PER_SEC) + ((stio_intptr_t)(nsec) / STIO_NSECS_PER_USEC))
#define STIO_SEC_TO_MSEC(sec) ((sec) * STIO_MSECS_PER_SEC)
#define STIO_MSEC_TO_SEC(sec) ((sec) / STIO_MSECS_PER_SEC)
#define STIO_USEC_TO_NSEC(usec) ((usec) * STIO_NSECS_PER_USEC)
#define STIO_NSEC_TO_USEC(nsec) ((nsec) / STIO_NSECS_PER_USEC)
#define STIO_MSEC_TO_NSEC(msec) ((msec) * STIO_NSECS_PER_MSEC)
#define STIO_NSEC_TO_MSEC(nsec) ((nsec) / STIO_NSECS_PER_MSEC)
#define STIO_SEC_TO_NSEC(sec) ((sec) * STIO_NSECS_PER_SEC)
#define STIO_NSEC_TO_SEC(nsec) ((nsec) / STIO_NSECS_PER_SEC)
#define STIO_SEC_TO_USEC(sec) ((sec) * STIO_USECS_PER_SEC)
#define STIO_USEC_TO_SEC(usec) ((usec) / STIO_USECS_PER_SEC)
#ifdef __cplusplus
extern "C" {
#endif
int stio_makesyshndasync (
stio_t* stio,
stio_syshnd_t hnd
);
stio_errnum_t stio_syserrtoerrnum (
int no
);
stio_mchar_t* stio_mbsdup (
stio_t* stio,
const stio_mchar_t* src
);
stio_size_t stio_mbscpy (
stio_mchar_t* buf,
const stio_mchar_t* str
);
int stio_mbsspltrn (
stio_mchar_t* s,
const stio_mchar_t* delim,
stio_mchar_t lquote,
stio_mchar_t rquote,
stio_mchar_t escape,
const stio_mchar_t* trset
);
int stio_mbsspl (
stio_mchar_t* s,
const stio_mchar_t* delim,
stio_mchar_t lquote,
stio_mchar_t rquote,
stio_mchar_t escape
);
void stio_cleartmrjobs (
stio_t* stio
);
void stio_firetmrjobs (
stio_t* stio,
const stio_ntime_t* tmbase,
stio_size_t* firecnt
);
int stio_gettmrtmout (
stio_t* stio,
const stio_ntime_t* tmbase,
stio_ntime_t* tmout
);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,600 +0,0 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STIO_SCK_H_
#define _STIO_SCK_H_
#include <stio.h>
/* ========================================================================= */
/* TOOD: move these to a separte file */
#define STIO_ETHHDR_PROTO_IP4 0x0800
#define STIO_ETHHDR_PROTO_ARP 0x0806
#define STIO_ETHHDR_PROTO_8021Q 0x8100 /* 802.1Q VLAN */
#define STIO_ETHHDR_PROTO_IP6 0x86DD
#define STIO_ARPHDR_OPCODE_REQUEST 1
#define STIO_ARPHDR_OPCODE_REPLY 2
#define STIO_ARPHDR_HTYPE_ETH 0x0001
#define STIO_ARPHDR_PTYPE_IP4 0x0800
#define STIO_ETHADDR_LEN 6
#define STIO_IP4ADDR_LEN 4
#define STIO_IP6ADDR_LEN 16
#if defined(__GNUC__)
# define STIO_PACKED __attribute__((__packed__))
#else
# define STIO_PACKED
# STIO_PACK_PUSH pack(push)
# STIO_PACK_PUSH pack(push)
# STIO_PACK(x) pack(x)
#endif
#if defined(__GNUC__)
/* nothing */
#else
#pragma pack(push)
#pragma pack(1)
#endif
struct STIO_PACKED stio_ethaddr_t
{
stio_uint8_t v[STIO_ETHADDR_LEN];
};
typedef struct stio_ethaddr_t stio_ethaddr_t;
struct STIO_PACKED stio_ip4addr_t
{
stio_uint8_t v[STIO_IP4ADDR_LEN];
};
typedef struct stio_ip4addr_t stio_ip4addr_t;
struct STIO_PACKED stio_ip6addr_t
{
stio_uint8_t v[STIO_IP6ADDR_LEN];
};
typedef struct stio_ip6addr_t stio_ip6addr_t;
struct STIO_PACKED stio_ethhdr_t
{
stio_uint8_t dest[STIO_ETHADDR_LEN];
stio_uint8_t source[STIO_ETHADDR_LEN];
stio_uint16_t proto;
};
typedef struct stio_ethhdr_t stio_ethhdr_t;
struct STIO_PACKED stio_arphdr_t
{
stio_uint16_t htype; /* hardware type (ethernet: 0x0001) */
stio_uint16_t ptype; /* protocol type (ipv4: 0x0800) */
stio_uint8_t hlen; /* hardware address length (ethernet: 6) */
stio_uint8_t plen; /* protocol address length (ipv4 :4) */
stio_uint16_t opcode; /* operation code */
};
typedef struct stio_arphdr_t stio_arphdr_t;
/* arp payload for ipv4 over ethernet */
struct STIO_PACKED stio_etharp_t
{
stio_uint8_t sha[STIO_ETHADDR_LEN]; /* source hardware address */
stio_uint8_t spa[STIO_IP4ADDR_LEN]; /* source protocol address */
stio_uint8_t tha[STIO_ETHADDR_LEN]; /* target hardware address */
stio_uint8_t tpa[STIO_IP4ADDR_LEN]; /* target protocol address */
};
typedef struct stio_etharp_t stio_etharp_t;
struct STIO_PACKED stio_etharp_pkt_t
{
stio_ethhdr_t ethhdr;
stio_arphdr_t arphdr;
stio_etharp_t arppld;
};
typedef struct stio_etharp_pkt_t stio_etharp_pkt_t;
struct stio_iphdr_t
{
#if defined(STIO_ENDIAN_LITTLE)
stio_uint8_t ihl:4;
stio_uint8_t version:4;
#elif defined(STIO_ENDIAN_BIG)
stio_uint8_t version:4;
stio_uint8_t ihl:4;
#else
# UNSUPPORTED ENDIAN
#endif
stio_int8_t tos;
stio_int16_t tot_len;
stio_int16_t id;
stio_int16_t frag_off;
stio_int8_t ttl;
stio_int8_t protocol;
stio_int16_t check;
stio_int32_t saddr;
stio_int32_t daddr;
/*The options start here. */
};
typedef struct stio_iphdr_t stio_iphdr_t;
struct STIO_PACKED stio_icmphdr_t
{
stio_uint8_t type; /* message type */
stio_uint8_t code; /* subcode */
stio_uint16_t checksum;
union
{
struct
{
stio_uint16_t id;
stio_uint16_t seq;
} echo;
stio_uint32_t gateway;
struct
{
stio_uint16_t frag_unused;
stio_uint16_t mtu;
} frag; /* path mut discovery */
} u;
};
typedef struct stio_icmphdr_t stio_icmphdr_t;
#if defined(__GNUC__)
/* nothing */
#else
#pragma pack(pop)
#endif
/* ICMP types */
#define STIO_ICMP_ECHO_REPLY 0
#define STIO_ICMP_UNREACH 3 /* destination unreachable */
#define STIO_ICMP_SOURCE_QUENCE 4
#define STIO_ICMP_REDIRECT 5
#define STIO_ICMP_ECHO_REQUEST 8
#define STIO_ICMP_TIME_EXCEEDED 11
#define STIO_ICMP_PARAM_PROBLEM 12
#define STIO_ICMP_TIMESTAMP_REQUEST 13
#define STIO_ICMP_TIMESTAMP_REPLY 14
#define STIO_ICMP_INFO_REQUEST 15
#define STIO_ICMP_INFO_REPLY 16
#define STIO_ICMP_ADDR_MASK_REQUEST 17
#define STIO_ICMP_ADDR_MASK_REPLY 18
/* Subcode for STIO_ICMP_UNREACH */
#define STIO_ICMP_UNREACH_NET 0
#define STIO_ICMP_UNREACH_HOST 1
#define STIO_ICMP_UNREACH_PROTOCOL 2
#define STIO_ICMP_UNREACH_PORT 3
#define STIO_ICMP_UNREACH_FRAG_NEEDED 4
/* Subcode for STIO_ICMP_REDIRECT */
#define STIO_ICMP_REDIRECT_NET 0
#define STIO_ICMP_REDIRECT_HOST 1
#define STIO_ICMP_REDIRECT_NETTOS 2
#define STIO_ICMP_REDIRECT_HOSTTOS 3
/* Subcode for STIO_ICMP_TIME_EXCEEDED */
#define STIO_ICMP_TIME_EXCEEDED_TTL 0
#define STIO_ICMP_TIME_EXCEEDED_FRAGTIME 1
/* ========================================================================= */
typedef int stio_sckfam_t;
struct stio_sckaddr_t
{
stio_sckfam_t family;
stio_uint8_t data[128]; /* TODO: use the actual sockaddr size */
};
typedef struct stio_sckaddr_t stio_sckaddr_t;
#if (STIO_SIZEOF_SOCKLEN_T == STIO_SIZEOF_INT)
#if defined(STIO_SOCKLEN_T_IS_SIGNED)
typedef int stio_scklen_t;
#else
typedef unsigned int stio_scklen_t;
#endif
#elif (STIO_SIZEOF_SOCKLEN_T == STIO_SIZEOF_LONG)
#if defined(STIO_SOCKLEN_T_IS_SIGNED)
typedef long stio_scklen_t;
#else
typedef unsigned long stio_scklen_t;
#endif
#else
typedef int stio_scklen_t;
#endif
#if defined(_WIN32)
# define STIO_IOCP_KEY 1
/*
typedef HANDLE stio_syshnd_t;
typedef SOCKET stio_sckhnd_t;
# define STIO_SCKHND_INVALID (INVALID_SOCKET)
*/
typedef stio_uintptr_t qse_sckhnd_t;
# define STIO_SCKHND_INVALID (~(qse_sck_hnd_t)0)
#else
typedef int stio_sckhnd_t;
# define STIO_SCKHND_INVALID (-1)
#endif
/* ========================================================================= */
enum stio_dev_sck_ioctl_cmd_t
{
STIO_DEV_SCK_BIND,
STIO_DEV_SCK_CONNECT,
STIO_DEV_SCK_LISTEN
};
typedef enum stio_dev_sck_ioctl_cmd_t stio_dev_sck_ioctl_cmd_t;
#define STIO_DEV_SCK_SET_PROGRESS(dev,bit) do { \
(dev)->state &= ~STIO_DEV_SCK_ALL_PROGRESS_BITS; \
(dev)->state |= (bit); \
} while(0)
#define STIO_DEV_SCK_GET_PROGRESS(dev) ((dev)->state & STIO_DEV_SCK_ALL_PROGRESS_BITS)
enum stio_dev_sck_state_t
{
/* the following items(progress bits) are mutually exclusive */
STIO_DEV_SCK_CONNECTING = (1 << 0),
STIO_DEV_SCK_CONNECTING_SSL = (1 << 1),
STIO_DEV_SCK_CONNECTED = (1 << 2),
STIO_DEV_SCK_LISTENING = (1 << 3),
STIO_DEV_SCK_ACCEPTING_SSL = (1 << 4),
STIO_DEV_SCK_ACCEPTED = (1 << 5),
/* the following items can be bitwise-ORed with an exclusive item above */
STIO_DEV_SCK_INTERCEPTED = (1 << 15),
/* convenience bit masks */
STIO_DEV_SCK_ALL_PROGRESS_BITS = (STIO_DEV_SCK_CONNECTING |
STIO_DEV_SCK_CONNECTING_SSL |
STIO_DEV_SCK_CONNECTED |
STIO_DEV_SCK_LISTENING |
STIO_DEV_SCK_ACCEPTING_SSL |
STIO_DEV_SCK_ACCEPTED)
};
typedef enum stio_dev_sck_state_t stio_dev_sck_state_t;
typedef struct stio_dev_sck_t stio_dev_sck_t;
typedef int (*stio_dev_sck_on_read_t) (
stio_dev_sck_t* dev,
const void* data,
stio_iolen_t dlen,
const stio_sckaddr_t* srcaddr
);
typedef int (*stio_dev_sck_on_write_t) (
stio_dev_sck_t* dev,
stio_iolen_t wrlen,
void* wrctx,
const stio_sckaddr_t* dstaddr
);
typedef void (*stio_dev_sck_on_disconnect_t) (
stio_dev_sck_t* dev
);
typedef int (*stio_dev_sck_on_connect_t) (
stio_dev_sck_t* dev
);
enum stio_dev_sck_type_t
{
STIO_DEV_SCK_TCP4,
STIO_DEV_SCK_TCP6,
STIO_DEV_SCK_UPD4,
STIO_DEV_SCK_UDP6,
/* ARP at the ethernet layer */
STIO_DEV_SCK_ARP,
STIO_DEV_SCK_ARP_DGRAM,
/* ICMP at the IPv4 layer */
STIO_DEV_SCK_ICMP4,
/* ICMP at the IPv6 layer */
STIO_DEV_SCK_ICMP6
#if 0
STIO_DEV_SCK_RAW, /* raw L2-level packet */
#endif
};
typedef enum stio_dev_sck_type_t stio_dev_sck_type_t;
typedef struct stio_dev_sck_make_t stio_dev_sck_make_t;
struct stio_dev_sck_make_t
{
stio_dev_sck_type_t type;
stio_dev_sck_on_write_t on_write;
stio_dev_sck_on_read_t on_read;
stio_dev_sck_on_disconnect_t on_disconnect;
};
enum stio_dev_sck_bind_option_t
{
STIO_DEV_SCK_BIND_BROADCAST = (1 << 0),
STIO_DEV_SCK_BIND_REUSEADDR = (1 << 1),
STIO_DEV_SCK_BIND_REUSEPORT = (1 << 2),
STIO_DEV_SCK_BIND_TRANSPARENT = (1 << 3),
/* TODO: more options --- SO_RCVBUF, SO_SNDBUF, SO_RCVTIMEO, SO_SNDTIMEO, SO_KEEPALIVE */
/* BINDTODEVICE??? */
STIO_DEV_SCK_BIND_SSL = (1 << 15)
};
typedef enum stio_dev_sck_bind_option_t stio_dev_sck_bind_option_t;
typedef struct stio_dev_sck_bind_t stio_dev_sck_bind_t;
struct stio_dev_sck_bind_t
{
int options;
stio_sckaddr_t localaddr;
/* TODO: add device name for BIND_TO_DEVICE */
const stio_mchar_t* ssl_certfile;
const stio_mchar_t* ssl_keyfile;
stio_ntime_t accept_tmout;
};
enum stio_def_sck_connect_option_t
{
STIO_DEV_SCK_CONNECT_SSL = (1 << 15)
};
typedef enum stio_dev_sck_connect_option_t stio_dev_sck_connect_option_t;
typedef struct stio_dev_sck_connect_t stio_dev_sck_connect_t;
struct stio_dev_sck_connect_t
{
int options;
stio_sckaddr_t remoteaddr;
stio_ntime_t connect_tmout;
stio_dev_sck_on_connect_t on_connect;
};
typedef struct stio_dev_sck_listen_t stio_dev_sck_listen_t;
struct stio_dev_sck_listen_t
{
int backlogs;
stio_dev_sck_on_connect_t on_connect; /* optional, but new connections are dropped immediately without this */
};
typedef struct stio_dev_sck_accept_t stio_dev_sck_accept_t;
struct stio_dev_sck_accept_t
{
stio_syshnd_t sck;
/* TODO: add timeout */
stio_sckaddr_t remoteaddr;
};
struct stio_dev_sck_t
{
STIO_DEV_HEADERS;
stio_dev_sck_type_t type;
stio_sckhnd_t sck;
int state;
/* remote peer address for a stateful stream socket. valid if one of the
* followings is set in state:
* STIO_DEV_TCP_ACCEPTING_SSL
* STIO_DEV_TCP_ACCEPTED
* STIO_DEV_TCP_CONNECTED
* STIO_DEV_TCP_CONNECTING
* STIO_DEV_TCP_CONNECTING_SSL
*
* also used as a placeholder to store source address for
* a stateless socket */
stio_sckaddr_t remoteaddr;
/* local socket address */
stio_sckaddr_t localaddr;
/* original destination address */
stio_sckaddr_t orgdstaddr;
stio_dev_sck_on_write_t on_write;
stio_dev_sck_on_read_t on_read;
/* return 0 on succes, -1 on failure.
* called on a new tcp device for an accepted client or
* on a tcp device conntected to a remote server */
stio_dev_sck_on_connect_t on_connect;
stio_dev_sck_on_disconnect_t on_disconnect;
/* timer job index for handling
* - connect() timeout for a connecting socket.
* - SSL_accept() timeout for a socket accepting SSL */
stio_tmridx_t tmrjob_index;
/* connect timeout, ssl-connect timeout, ssl-accept timeout.
* it denotes timeout duration under some circumstances
* or an absolute expiry time under some other circumstances. */
stio_ntime_t tmout;
void* ssl_ctx;
void* ssl;
};
#ifdef __cplusplus
extern "C" {
#endif
STIO_EXPORT stio_sckhnd_t stio_openasyncsck (
stio_t* stio,
int domain,
int type,
int proto
);
STIO_EXPORT void stio_closeasyncsck (
stio_t* stio,
stio_sckhnd_t sck
);
STIO_EXPORT int stio_makesckasync (
stio_t* stio,
stio_sckhnd_t sck
);
STIO_EXPORT int stio_getsckaddrinfo (
stio_t* stio,
const stio_sckaddr_t* addr,
stio_scklen_t* len,
stio_sckfam_t* family
);
/*
* The stio_getsckaddrport() function returns the port number of a socket
* address in the host byte order. If the address doesn't support the port
* number, it returns 0.
*/
STIO_EXPORT stio_uint16_t stio_getsckaddrport (
const stio_sckaddr_t* addr
);
/*
* The stio_getsckaddrifindex() function returns an interface number.
* If the address doesn't support the interface number, it returns 0. */
STIO_EXPORT int stio_getsckaddrifindex (
const stio_sckaddr_t* addr
);
STIO_EXPORT void stio_sckaddr_initforip4 (
stio_sckaddr_t* sckaddr,
stio_uint16_t port,
stio_ip4addr_t* ip4addr
);
STIO_EXPORT void stio_sckaddr_initforip6 (
stio_sckaddr_t* sckaddr,
stio_uint16_t port,
stio_ip6addr_t* ip6addr
);
STIO_EXPORT void stio_sckaddr_initforeth (
stio_sckaddr_t* sckaddr,
int ifindex,
stio_ethaddr_t* ethaddr
);
/* ========================================================================= */
STIO_EXPORT stio_dev_sck_t* stio_dev_sck_make (
stio_t* stio,
stio_size_t xtnsize,
const stio_dev_sck_make_t* info
);
STIO_EXPORT int stio_dev_sck_bind (
stio_dev_sck_t* dev,
stio_dev_sck_bind_t* info
);
STIO_EXPORT int stio_dev_sck_connect (
stio_dev_sck_t* dev,
stio_dev_sck_connect_t* info
);
STIO_EXPORT int stio_dev_sck_listen (
stio_dev_sck_t* dev,
stio_dev_sck_listen_t* info
);
STIO_EXPORT int stio_dev_sck_write (
stio_dev_sck_t* dev,
const void* data,
stio_iolen_t len,
void* wrctx,
const stio_sckaddr_t* dstaddr
);
STIO_EXPORT int stio_dev_sck_timedwrite (
stio_dev_sck_t* dev,
const void* data,
stio_iolen_t len,
const stio_ntime_t* tmout,
void* wrctx,
const stio_sckaddr_t* dstaddr
);
#if defined(STIO_HAVE_INLINE)
static STIO_INLINE void stio_dev_sck_halt (stio_dev_sck_t* sck)
{
stio_dev_halt ((stio_dev_t*)sck);
}
static STIO_INLINE int stio_dev_sck_read (stio_dev_sck_t* sck, int enabled)
{
return stio_dev_read ((stio_dev_t*)sck, enabled);
}
#else
#define stio_dev_sck_halt(sck) stio_dev_halt((stio_dev_t*)sck)
#define stio_dev_sck_read(sck,enabled) stio_dev_read((stio_dev_t*)sck, enabled)
#endif
STIO_EXPORT stio_uint16_t stio_checksumip (
const void* hdr,
stio_size_t len
);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,234 +0,0 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "stio-prv.h"
#define HEAP_PARENT(x) (((x) - 1) / 2)
#define HEAP_LEFT(x) ((x) * 2 + 1)
#define HEAP_RIGHT(x) ((x) * 2 + 2)
#define YOUNGER_THAN(x,y) (stio_cmptime(&(x)->when, &(y)->when) < 0)
void stio_cleartmrjobs (stio_t* stio)
{
while (stio->tmr.size > 0) stio_deltmrjob (stio, 0);
}
static stio_tmridx_t sift_up (stio_t* stio, stio_tmridx_t index, int notify)
{
stio_tmridx_t parent;
parent = HEAP_PARENT(index);
if (index > 0 && YOUNGER_THAN(&stio->tmr.jobs[index], &stio->tmr.jobs[parent]))
{
stio_tmrjob_t item;
item = stio->tmr.jobs[index];
do
{
/* move down the parent to my current position */
stio->tmr.jobs[index] = stio->tmr.jobs[parent];
if (stio->tmr.jobs[index].idxptr) *stio->tmr.jobs[index].idxptr = index;
/* traverse up */
index = parent;
parent = HEAP_PARENT(parent);
}
while (index > 0 && YOUNGER_THAN(&item, &stio->tmr.jobs[parent]));
stio->tmr.jobs[index] = item;
if (stio->tmr.jobs[index].idxptr) *stio->tmr.jobs[index].idxptr = index;
}
return index;
}
static stio_tmridx_t sift_down (stio_t* stio, stio_tmridx_t index, int notify)
{
stio_size_t base = stio->tmr.size / 2;
if (index < base) /* at least 1 child is under the 'index' position */
{
stio_tmrjob_t item;
item = stio->tmr.jobs[index];
do
{
stio_tmridx_t left, right, younger;
left = HEAP_LEFT(index);
right = HEAP_RIGHT(index);
if (right < stio->tmr.size && YOUNGER_THAN(&stio->tmr.jobs[right], &stio->tmr.jobs[left]))
{
younger = right;
}
else
{
younger = left;
}
if (YOUNGER_THAN(&item, &stio->tmr.jobs[younger])) break;
stio->tmr.jobs[index] = stio->tmr.jobs[younger];
if (stio->tmr.jobs[index].idxptr) *stio->tmr.jobs[index].idxptr = index;
index = younger;
}
while (index < base);
stio->tmr.jobs[index] = item;
if (stio->tmr.jobs[index].idxptr) *stio->tmr.jobs[index].idxptr = index;
}
return index;
}
void stio_deltmrjob (stio_t* stio, stio_tmridx_t index)
{
stio_tmrjob_t item;
STIO_ASSERT (index < stio->tmr.size);
item = stio->tmr.jobs[index];
if (stio->tmr.jobs[index].idxptr) *stio->tmr.jobs[index].idxptr = STIO_TMRIDX_INVALID;
stio->tmr.size = stio->tmr.size - 1;
if (stio->tmr.size > 0 && index != stio->tmr.size)
{
stio->tmr.jobs[index] = stio->tmr.jobs[stio->tmr.size];
if (stio->tmr.jobs[index].idxptr) *stio->tmr.jobs[index].idxptr = index;
YOUNGER_THAN(&stio->tmr.jobs[index], &item)? sift_up(stio, index, 1): sift_down(stio, index, 1);
}
}
stio_tmridx_t stio_instmrjob (stio_t* stio, const stio_tmrjob_t* job)
{
stio_tmridx_t index = stio->tmr.size;
if (index >= stio->tmr.capa)
{
stio_tmrjob_t* tmp;
stio_size_t new_capa;
STIO_ASSERT (stio->tmr.capa >= 1);
new_capa = stio->tmr.capa * 2;
tmp = (stio_tmrjob_t*)STIO_MMGR_REALLOC (stio->mmgr, stio->tmr.jobs, new_capa * STIO_SIZEOF(*tmp));
if (tmp == STIO_NULL)
{
stio->errnum = STIO_ENOMEM;
return STIO_TMRIDX_INVALID;
}
stio->tmr.jobs = tmp;
stio->tmr.capa = new_capa;
}
stio->tmr.size = stio->tmr.size + 1;
stio->tmr.jobs[index] = *job;
if (stio->tmr.jobs[index].idxptr) *stio->tmr.jobs[index].idxptr = index;
return sift_up (stio, index, 0);
}
stio_tmridx_t stio_updtmrjob (stio_t* stio, stio_tmridx_t index, const stio_tmrjob_t* job)
{
stio_tmrjob_t item;
item = stio->tmr.jobs[index];
stio->tmr.jobs[index] = *job;
if (stio->tmr.jobs[index].idxptr) *stio->tmr.jobs[index].idxptr = index;
return YOUNGER_THAN(job, &item)? sift_up (stio, index, 0): sift_down (stio, index, 0);
}
void stio_firetmrjobs (stio_t* stio, const stio_ntime_t* tm, stio_size_t* firecnt)
{
stio_ntime_t now;
stio_tmrjob_t tmrjob;
stio_size_t count = 0;
/* if the current time is not specified, get it from the system */
if (tm) now = *tm;
else stio_gettime (&now);
while (stio->tmr.size > 0)
{
if (stio_cmptime(&stio->tmr.jobs[0].when, &now) > 0) break;
tmrjob = stio->tmr.jobs[0]; /* copy the scheduled job */
stio_deltmrjob (stio, 0); /* deschedule the job */
count++;
tmrjob.handler (stio, &now, &tmrjob); /* then fire the job */
}
if (firecnt) *firecnt = count;
}
int stio_gettmrtmout (stio_t* stio, const stio_ntime_t* tm, stio_ntime_t* tmout)
{
stio_ntime_t now;
/* time-out can't be calculated when there's no job scheduled */
if (stio->tmr.size <= 0)
{
stio->errnum = STIO_ENOENT;
return -1;
}
/* if the current time is not specified, get it from the system */
if (tm) now = *tm;
else stio_gettime (&now);
stio_subtime (&stio->tmr.jobs[0].when, &now, tmout);
if (tmout->sec < 0) stio_cleartime (tmout);
return 0;
}
stio_tmrjob_t* stio_gettmrjob (stio_t* stio, stio_tmridx_t index)
{
if (index < 0 || index >= stio->tmr.size)
{
stio->errnum = STIO_ENOENT;
return STIO_NULL;
}
return &stio->tmr.jobs[index];
}
int stio_gettmrjobdeadline (stio_t* stio, stio_tmridx_t index, stio_ntime_t* deadline)
{
if (index < 0 || index >= stio->tmr.size)
{
stio->errnum = STIO_ENOENT;
return -1;
}
*deadline = stio->tmr.jobs[index].when;
return 0;
}

View File

@ -1,524 +0,0 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "stio-prv.h"
/* ========================================================================= */
#if defined(STIO_HAVE_UINT16_T)
stio_uint16_t stio_ntoh16 (stio_uint16_t x)
{
#if defined(STIO_ENDIAN_BIG)
return x;
#elif defined(STIO_ENDIAN_LITTLE)
stio_uint8_t* c = (stio_uint8_t*)&x;
return (stio_uint16_t)(
((stio_uint16_t)c[0] << 8) |
((stio_uint16_t)c[1] << 0));
#else
# error Unknown endian
#endif
}
stio_uint16_t stio_hton16 (stio_uint16_t x)
{
#if defined(STIO_ENDIAN_BIG)
return x;
#elif defined(STIO_ENDIAN_LITTLE)
stio_uint8_t* c = (stio_uint8_t*)&x;
return (stio_uint16_t)(
((stio_uint16_t)c[0] << 8) |
((stio_uint16_t)c[1] << 0));
#else
# error Unknown endian
#endif
}
#endif
/* ========================================================================= */
#if defined(STIO_HAVE_UINT32_T)
stio_uint32_t stio_ntoh32 (stio_uint32_t x)
{
#if defined(STIO_ENDIAN_BIG)
return x;
#elif defined(STIO_ENDIAN_LITTLE)
stio_uint8_t* c = (stio_uint8_t*)&x;
return (stio_uint32_t)(
((stio_uint32_t)c[0] << 24) |
((stio_uint32_t)c[1] << 16) |
((stio_uint32_t)c[2] << 8) |
((stio_uint32_t)c[3] << 0));
#else
# error Unknown endian
#endif
}
stio_uint32_t stio_hton32 (stio_uint32_t x)
{
#if defined(STIO_ENDIAN_BIG)
return x;
#elif defined(STIO_ENDIAN_LITTLE)
stio_uint8_t* c = (stio_uint8_t*)&x;
return (stio_uint32_t)(
((stio_uint32_t)c[0] << 24) |
((stio_uint32_t)c[1] << 16) |
((stio_uint32_t)c[2] << 8) |
((stio_uint32_t)c[3] << 0));
#else
# error Unknown endian
#endif
}
#endif
/* ========================================================================= */
#if defined(STIO_HAVE_UINT64_T)
stio_uint64_t stio_ntoh64 (stio_uint64_t x)
{
#if defined(STIO_ENDIAN_BIG)
return x;
#elif defined(STIO_ENDIAN_LITTLE)
stio_uint8_t* c = (stio_uint8_t*)&x;
return (stio_uint64_t)(
((stio_uint64_t)c[0] << 56) |
((stio_uint64_t)c[1] << 48) |
((stio_uint64_t)c[2] << 40) |
((stio_uint64_t)c[3] << 32) |
((stio_uint64_t)c[4] << 24) |
((stio_uint64_t)c[5] << 16) |
((stio_uint64_t)c[6] << 8) |
((stio_uint64_t)c[7] << 0));
#else
# error Unknown endian
#endif
}
stio_uint64_t stio_hton64 (stio_uint64_t x)
{
#if defined(STIO_ENDIAN_BIG)
return x;
#elif defined(STIO_ENDIAN_LITTLE)
stio_uint8_t* c = (stio_uint8_t*)&x;
return (stio_uint64_t)(
((stio_uint64_t)c[0] << 56) |
((stio_uint64_t)c[1] << 48) |
((stio_uint64_t)c[2] << 40) |
((stio_uint64_t)c[3] << 32) |
((stio_uint64_t)c[4] << 24) |
((stio_uint64_t)c[5] << 16) |
((stio_uint64_t)c[6] << 8) |
((stio_uint64_t)c[7] << 0));
#else
# error Unknown endian
#endif
}
#endif
/* ========================================================================= */
#if defined(STIO_HAVE_UINT128_T)
stio_uint128_t stio_ntoh128 (stio_uint128_t x)
{
#if defined(STIO_ENDIAN_BIG)
return x;
#elif defined(STIO_ENDIAN_LITTLE)
stio_uint8_t* c = (stio_uint8_t*)&x;
return (stio_uint128_t)(
((stio_uint128_t)c[0] << 120) |
((stio_uint128_t)c[1] << 112) |
((stio_uint128_t)c[2] << 104) |
((stio_uint128_t)c[3] << 96) |
((stio_uint128_t)c[4] << 88) |
((stio_uint128_t)c[5] << 80) |
((stio_uint128_t)c[6] << 72) |
((stio_uint128_t)c[7] << 64) |
((stio_uint128_t)c[8] << 56) |
((stio_uint128_t)c[9] << 48) |
((stio_uint128_t)c[10] << 40) |
((stio_uint128_t)c[11] << 32) |
((stio_uint128_t)c[12] << 24) |
((stio_uint128_t)c[13] << 16) |
((stio_uint128_t)c[14] << 8) |
((stio_uint128_t)c[15] << 0));
#else
# error Unknown endian
#endif
}
stio_uint128_t stio_hton128 (stio_uint128_t x)
{
#if defined(STIO_ENDIAN_BIG)
return x;
#elif defined(STIO_ENDIAN_LITTLE)
stio_uint8_t* c = (stio_uint8_t*)&x;
return (stio_uint128_t)(
((stio_uint128_t)c[0] << 120) |
((stio_uint128_t)c[1] << 112) |
((stio_uint128_t)c[2] << 104) |
((stio_uint128_t)c[3] << 96) |
((stio_uint128_t)c[4] << 88) |
((stio_uint128_t)c[5] << 80) |
((stio_uint128_t)c[6] << 72) |
((stio_uint128_t)c[7] << 64) |
((stio_uint128_t)c[8] << 56) |
((stio_uint128_t)c[9] << 48) |
((stio_uint128_t)c[10] << 40) |
((stio_uint128_t)c[11] << 32) |
((stio_uint128_t)c[12] << 24) |
((stio_uint128_t)c[13] << 16) |
((stio_uint128_t)c[14] << 8) |
((stio_uint128_t)c[15] << 0));
#else
# error Unknown endian
#endif
}
#endif
/* ========================================================================= */
#define IS_MSPACE(x) ((x) == STIO_MT(' ') || (x) == STIO_MT('\t') || (x) == STIO_MT('\n') || (x) == STIO_MT('\r'))
stio_mchar_t* stio_mbsdup (stio_t* stio, const stio_mchar_t* src)
{
stio_mchar_t* dst;
stio_size_t len;
dst = (stio_mchar_t*)src;
while (*dst != STIO_MT('\0')) dst++;
len = dst - src;
dst = STIO_MMGR_ALLOC (stio->mmgr, (len + 1) * STIO_SIZEOF(*src));
if (!dst)
{
stio->errnum = STIO_ENOMEM;
return STIO_NULL;
}
STIO_MEMCPY (dst, src, (len + 1) * STIO_SIZEOF(*src));
return dst;
}
stio_size_t stio_mbscpy (stio_mchar_t* buf, const stio_mchar_t* str)
{
stio_mchar_t* org = buf;
while ((*buf++ = *str++) != STIO_MT('\0'));
return buf - org - 1;
}
int stio_mbsspltrn (
stio_mchar_t* s, const stio_mchar_t* delim,
stio_mchar_t lquote, stio_mchar_t rquote,
stio_mchar_t escape, const stio_mchar_t* trset)
{
stio_mchar_t* p = s, *d;
stio_mchar_t* sp = STIO_NULL, * ep = STIO_NULL;
int delim_mode;
int cnt = 0;
if (delim == STIO_NULL) delim_mode = 0;
else
{
delim_mode = 1;
for (d = (stio_mchar_t*)delim; *d != STIO_MT('\0'); d++)
if (!IS_MSPACE(*d)) delim_mode = 2;
}
if (delim_mode == 0)
{
/* skip preceding space characters */
while (IS_MSPACE(*p)) p++;
/* when 0 is given as "delim", it has an effect of cutting
preceding and trailing space characters off "s". */
if (lquote != STIO_MT('\0') && *p == lquote)
{
stio_mbscpy (p, p + 1);
for (;;)
{
if (*p == STIO_MT('\0')) return -1;
if (escape != STIO_MT('\0') && *p == escape)
{
if (trset != STIO_NULL && p[1] != STIO_MT('\0'))
{
const stio_mchar_t* ep = trset;
while (*ep != STIO_MT('\0'))
{
if (p[1] == *ep++)
{
p[1] = *ep;
break;
}
}
}
stio_mbscpy (p, p + 1);
}
else
{
if (*p == rquote)
{
p++;
break;
}
}
if (sp == 0) sp = p;
ep = p;
p++;
}
while (IS_MSPACE(*p)) p++;
if (*p != STIO_MT('\0')) return -1;
if (sp == 0 && ep == 0) s[0] = STIO_MT('\0');
else
{
ep[1] = STIO_MT('\0');
if (s != (stio_mchar_t*)sp) stio_mbscpy (s, sp);
cnt++;
}
}
else
{
while (*p)
{
if (!IS_MSPACE(*p))
{
if (sp == 0) sp = p;
ep = p;
}
p++;
}
if (sp == 0 && ep == 0) s[0] = STIO_MT('\0');
else
{
ep[1] = STIO_MT('\0');
if (s != (stio_mchar_t*)sp) stio_mbscpy (s, sp);
cnt++;
}
}
}
else if (delim_mode == 1)
{
stio_mchar_t* o;
while (*p)
{
o = p;
while (IS_MSPACE(*p)) p++;
if (o != p) { stio_mbscpy (o, p); p = o; }
if (lquote != STIO_MT('\0') && *p == lquote)
{
stio_mbscpy (p, p + 1);
for (;;)
{
if (*p == STIO_MT('\0')) return -1;
if (escape != STIO_MT('\0') && *p == escape)
{
if (trset != STIO_NULL && p[1] != STIO_MT('\0'))
{
const stio_mchar_t* ep = trset;
while (*ep != STIO_MT('\0'))
{
if (p[1] == *ep++)
{
p[1] = *ep;
break;
}
}
}
stio_mbscpy (p, p + 1);
}
else
{
if (*p == rquote)
{
*p++ = STIO_MT('\0');
cnt++;
break;
}
}
p++;
}
}
else
{
o = p;
for (;;)
{
if (*p == STIO_MT('\0'))
{
if (o != p) cnt++;
break;
}
if (IS_MSPACE (*p))
{
*p++ = STIO_MT('\0');
cnt++;
break;
}
p++;
}
}
}
}
else /* if (delim_mode == 2) */
{
stio_mchar_t* o;
int ok;
while (*p != STIO_MT('\0'))
{
o = p;
while (IS_MSPACE(*p)) p++;
if (o != p) { stio_mbscpy (o, p); p = o; }
if (lquote != STIO_MT('\0') && *p == lquote)
{
stio_mbscpy (p, p + 1);
for (;;)
{
if (*p == STIO_MT('\0')) return -1;
if (escape != STIO_MT('\0') && *p == escape)
{
if (trset != STIO_NULL && p[1] != STIO_MT('\0'))
{
const stio_mchar_t* ep = trset;
while (*ep != STIO_MT('\0'))
{
if (p[1] == *ep++)
{
p[1] = *ep;
break;
}
}
}
stio_mbscpy (p, p + 1);
}
else
{
if (*p == rquote)
{
*p++ = STIO_MT('\0');
cnt++;
break;
}
}
p++;
}
ok = 0;
while (IS_MSPACE(*p)) p++;
if (*p == STIO_MT('\0')) ok = 1;
for (d = (stio_mchar_t*)delim; *d != STIO_MT('\0'); d++)
{
if (*p == *d)
{
ok = 1;
stio_mbscpy (p, p + 1);
break;
}
}
if (ok == 0) return -1;
}
else
{
o = p; sp = ep = 0;
for (;;)
{
if (*p == STIO_MT('\0'))
{
if (ep)
{
ep[1] = STIO_MT('\0');
p = &ep[1];
}
cnt++;
break;
}
for (d = (stio_mchar_t*)delim; *d != STIO_MT('\0'); d++)
{
if (*p == *d)
{
if (sp == STIO_NULL)
{
stio_mbscpy (o, p); p = o;
*p++ = STIO_MT('\0');
}
else
{
stio_mbscpy (&ep[1], p);
stio_mbscpy (o, sp);
o[ep - sp + 1] = STIO_MT('\0');
p = &o[ep - sp + 2];
}
cnt++;
/* last empty field after delim */
if (*p == STIO_MT('\0')) cnt++;
goto exit_point;
}
}
if (!IS_MSPACE (*p))
{
if (sp == STIO_NULL) sp = p;
ep = p;
}
p++;
}
exit_point:
;
}
}
}
return cnt;
}
int stio_mbsspl (
stio_mchar_t* s, const stio_mchar_t* delim,
stio_mchar_t lquote, stio_mchar_t rquote, stio_mchar_t escape)
{
return stio_mbsspltrn (s, delim, lquote, rquote, escape, STIO_NULL);
}

View File

@ -1,554 +0,0 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STIO_H_
#define _STIO_H_
#include <stio-cmn.h>
/**
* The stio_ntime_t type defines a numeric time type expressed in the
* number of milliseconds since the Epoch (00:00:00 UTC, Jan 1, 1970).
*/
typedef struct stio_ntime_t stio_ntime_t;
struct stio_ntime_t
{
stio_intptr_t sec;
stio_int32_t nsec; /* nanoseconds */
};
#if defined(_WIN32)
typedef stio_uintptr_t qse_syshnd_t;
#define STIO_SYSHND_INVALID (~(stio_uintptr_t)0)
#else
typedef int stio_syshnd_t;
#define STIO_SYSHND_INVALID (-1)
#endif
typedef struct stio_devaddr_t stio_devaddr_t;
struct stio_devaddr_t
{
int len;
void* ptr;
};
#define STIO_CONST_SWAP16(x) \
((stio_uint16_t)((((stio_uint16_t)(x) & (stio_uint16_t)0x00ffU) << 8) | \
(((stio_uint16_t)(x) & (stio_uint16_t)0xff00U) >> 8) ))
#define STIO_CONST_SWAP32(x) \
((stio_uint32_t)((((stio_uint32_t)(x) & (stio_uint32_t)0x000000ffUL) << 24) | \
(((stio_uint32_t)(x) & (stio_uint32_t)0x0000ff00UL) << 8) | \
(((stio_uint32_t)(x) & (stio_uint32_t)0x00ff0000UL) >> 8) | \
(((stio_uint32_t)(x) & (stio_uint32_t)0xff000000UL) >> 24) ))
#if defined(STIO_ENDIAN_LITTLE)
# define STIO_CONST_NTOH16(x) STIO_CONST_SWAP16(x)
# define STIO_CONST_HTON16(x) STIO_CONST_SWAP16(x)
# define STIO_CONST_NTOH32(x) STIO_CONST_SWAP32(x)
# define STIO_CONST_HTON32(x) STIO_CONST_SWAP32(x)
#elif defined(STIO_ENDIAN_BIG)
# define STIO_CONST_NTOH16(x) (x)
# define STIO_CONST_HTON16(x) (x)
# define STIO_CONST_NTOH32(x) (x)
# define STIO_CONST_HTON32(x) (x)
#else
# error UNKNOWN ENDIAN
#endif
/* ========================================================================= */
typedef struct stio_t stio_t;
typedef struct stio_dev_t stio_dev_t;
typedef struct stio_dev_mth_t stio_dev_mth_t;
typedef struct stio_dev_evcb_t stio_dev_evcb_t;
typedef struct stio_wq_t stio_wq_t;
typedef stio_intptr_t stio_iolen_t; /* NOTE: this is a signed type */
enum stio_errnum_t
{
STIO_ENOERR,
STIO_ENOIMPL,
STIO_ESYSERR,
STIO_EINTERN,
STIO_ENOMEM,
STIO_EINVAL,
STIO_EEXIST,
STIO_ENOENT,
STIO_ENOSUP, /* not supported */
STIO_EMFILE, /* too many open files */
STIO_ENFILE,
STIO_EAGAIN,
STIO_ECONRF, /* connection refused */
STIO_ECONRS, /* connection reset */
STIO_ENOCAPA, /* no capability */
STIO_ETMOUT, /* timed out */
STIO_EPERM, /* operation not permitted */
STIO_EDEVMAKE,
STIO_EDEVERR,
STIO_EDEVHUP
};
typedef enum stio_errnum_t stio_errnum_t;
enum stio_stopreq_t
{
STIO_STOPREQ_NONE = 0,
STIO_STOPREQ_TERMINATION,
STIO_STOPREQ_WATCHER_ERROR
};
typedef enum stio_stopreq_t stio_stopreq_t;
/* ========================================================================= */
#define STIO_TMRIDX_INVALID ((stio_tmridx_t)-1)
typedef stio_size_t stio_tmridx_t;
typedef struct stio_tmrjob_t stio_tmrjob_t;
typedef void (*stio_tmrjob_handler_t) (
stio_t* stio,
const stio_ntime_t* now,
stio_tmrjob_t* tmrjob
);
struct stio_tmrjob_t
{
void* ctx;
stio_ntime_t when;
stio_tmrjob_handler_t handler;
stio_tmridx_t* idxptr; /* pointer to the index holder */
};
/* ========================================================================= */
struct stio_dev_mth_t
{
/* ------------------------------------------------------------------ */
/* mandatory. called in stio_makedev() */
int (*make) (stio_dev_t* dev, void* ctx);
/* ------------------------------------------------------------------ */
/* mandatory. called in stio_killdev(). also called in stio_makedev() upon
* failure after make() success.
*
* when 'force' is 0, the return value of -1 causes the device to be a
* zombie. the kill method is called periodically on a zombie device
* until the method returns 0.
*
* when 'force' is 1, the called should not return -1. If it does, the
* method is called once more only with the 'force' value of 2.
*
* when 'force' is 2, the device is destroyed regardless of the return value.
*/
int (*kill) (stio_dev_t* dev, int force);
/* ------------------------------------------------------------------ */
stio_syshnd_t (*getsyshnd) (stio_dev_t* dev); /* mandatory. called in stio_makedev() after successful make() */
/* ------------------------------------------------------------------ */
/* return -1 on failure, 0 if no data is availble, 1 otherwise.
* when returning 1, *len must be sent to the length of data read.
* if *len is set to 0, it's treated as EOF. */
int (*read) (stio_dev_t* dev, void* data, stio_iolen_t* len, stio_devaddr_t* srcaddr);
/* ------------------------------------------------------------------ */
int (*write) (stio_dev_t* dev, const void* data, stio_iolen_t* len, const stio_devaddr_t* dstaddr);
/* ------------------------------------------------------------------ */
int (*ioctl) (stio_dev_t* dev, int cmd, void* arg);
};
struct stio_dev_evcb_t
{
/* return -1 on failure. 0 or 1 on success.
* when 0 is returned, it doesn't attempt to perform actual I/O.
* when 1 is returned, it attempts to perform actual I/O. */
int (*ready) (stio_dev_t* dev, int events);
/* return -1 on failure, 0 or 1 on success.
* when 0 is returned, the main loop stops the attempt to read more data.
* when 1 is returned, the main loop attempts to read more data without*/
int (*on_read) (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_devaddr_t* srcaddr);
/* return -1 on failure, 0 on success.
* wrlen is the length of data written. it is the length of the originally
* posted writing request for a stream device. For a non stream device, it
* may be shorter than the originally posted length. */
int (*on_write) (stio_dev_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_devaddr_t* dstaddr);
};
struct stio_wq_t
{
stio_wq_t* next;
stio_wq_t* prev;
stio_iolen_t olen; /* original data length */
stio_uint8_t* ptr; /* pointer to data */
stio_iolen_t len; /* remaining data length */
void* ctx;
stio_dev_t* dev; /* back-pointer to the device */
stio_tmridx_t tmridx;
stio_devaddr_t dstaddr;
};
#define STIO_WQ_INIT(wq) ((wq)->next = (wq)->prev = (wq))
#define STIO_WQ_TAIL(wq) ((wq)->prev)
#define STIO_WQ_HEAD(wq) ((wq)->next)
#define STIO_WQ_ISEMPTY(wq) (STIO_WQ_HEAD(wq) == (wq))
#define STIO_WQ_ISNODE(wq,x) ((wq) != (x))
#define STIO_WQ_ISHEAD(wq,x) (STIO_WQ_HEAD(wq) == (x))
#define STIO_WQ_ISTAIL(wq,x) (STIO_WQ_TAIL(wq) == (x))
#define STIO_WQ_NEXT(x) ((x)->next)
#define STIO_WQ_PREV(x) ((x)->prev)
#define STIO_WQ_LINK(p,x,n) do { \
stio_wq_t* pp = (p), * nn = (n); \
(x)->prev = (p); \
(x)->next = (n); \
nn->prev = (x); \
pp->next = (x); \
} while (0)
#define STIO_WQ_UNLINK(x) do { \
stio_wq_t* pp = (x)->prev, * nn = (x)->next; \
nn->prev = pp; pp->next = nn; \
} while (0)
#define STIO_WQ_REPL(o,n) do { \
stio_wq_t* oo = (o), * nn = (n); \
nn->next = oo->next; \
nn->next->prev = nn; \
nn->prev = oo->prev; \
nn->prev->next = nn; \
} while (0)
/* insert an item at the back of the queue */
/*#define STIO_WQ_ENQ(wq,x) STIO_WQ_LINK(STIO_WQ_TAIL(wq), x, STIO_WQ_TAIL(wq)->next)*/
#define STIO_WQ_ENQ(wq,x) STIO_WQ_LINK(STIO_WQ_TAIL(wq), x, wq)
/* remove an item in the front from the queue */
#define STIO_WQ_DEQ(wq) STIO_WQ_UNLINK(STIO_WQ_HEAD(wq))
#define STIO_DEV_HEADERS \
stio_t* stio; \
stio_size_t dev_size; \
int dev_capa; \
stio_dev_mth_t* dev_mth; \
stio_dev_evcb_t* dev_evcb; \
stio_wq_t wq; \
stio_dev_t* dev_prev; \
stio_dev_t* dev_next
struct stio_dev_t
{
STIO_DEV_HEADERS;
};
enum stio_dev_capa_t
{
STIO_DEV_CAPA_VIRTUAL = (1 << 0),
STIO_DEV_CAPA_IN = (1 << 1),
STIO_DEV_CAPA_OUT = (1 << 2),
/* #STIO_DEV_CAPA_PRI is meaningful only if #STIO_DEV_CAPA_IN is set */
STIO_DEV_CAPA_PRI = (1 << 3),
STIO_DEV_CAPA_STREAM = (1 << 4),
STIO_DEV_CAPA_OUT_QUEUED = (1 << 5),
/* internal use only. never set this bit to the dev_capa field */
STIO_DEV_CAPA_IN_DISABLED = (1 << 9),
STIO_DEV_CAPA_IN_CLOSED = (1 << 10),
STIO_DEV_CAPA_OUT_CLOSED = (1 << 11),
STIO_DEV_CAPA_IN_WATCHED = (1 << 12),
STIO_DEV_CAPA_OUT_WATCHED = (1 << 13),
STIO_DEV_CAPA_PRI_WATCHED = (1 << 14), /**< can be set only if STIO_DEV_CAPA_IN_WATCHED is set */
STIO_DEV_CAPA_ACTIVE = (1 << 15),
STIO_DEV_CAPA_HALTED = (1 << 16),
STIO_DEV_CAPA_ZOMBIE = (1 << 17)
};
typedef enum stio_dev_capa_t stio_dev_capa_t;
enum stio_dev_watch_cmd_t
{
STIO_DEV_WATCH_START,
STIO_DEV_WATCH_UPDATE,
STIO_DEV_WATCH_RENEW, /* automatic update */
STIO_DEV_WATCH_STOP
};
typedef enum stio_dev_watch_cmd_t stio_dev_watch_cmd_t;
enum stio_dev_event_t
{
STIO_DEV_EVENT_IN = (1 << 0),
STIO_DEV_EVENT_OUT = (1 << 1),
STIO_DEV_EVENT_PRI = (1 << 2),
STIO_DEV_EVENT_HUP = (1 << 3),
STIO_DEV_EVENT_ERR = (1 << 4)
};
typedef enum stio_dev_event_t stio_dev_event_t;
/* ========================================================================= */
#ifdef __cplusplus
extern "C" {
#endif
STIO_EXPORT stio_t* stio_open (
stio_mmgr_t* mmgr,
stio_size_t xtnsize,
stio_size_t tmrcapa, /**< initial timer capacity */
stio_errnum_t* errnum
);
STIO_EXPORT void stio_close (
stio_t* stio
);
STIO_EXPORT int stio_init (
stio_t* stio,
stio_mmgr_t* mmgr,
stio_size_t tmrcapa
);
STIO_EXPORT void stio_fini (
stio_t* stio
);
STIO_EXPORT int stio_exec (
stio_t* stio
);
STIO_EXPORT int stio_loop (
stio_t* stio
);
STIO_EXPORT void stio_stop (
stio_t* stio,
stio_stopreq_t stopreq
);
STIO_EXPORT stio_dev_t* stio_makedev (
stio_t* stio,
stio_size_t dev_size,
stio_dev_mth_t* dev_mth,
stio_dev_evcb_t* dev_evcb,
void* make_ctx
);
STIO_EXPORT void stio_killdev (
stio_t* stio,
stio_dev_t* dev
);
STIO_EXPORT int stio_dev_ioctl (
stio_dev_t* dev,
int cmd,
void* arg
);
STIO_EXPORT int stio_dev_watch (
stio_dev_t* dev,
stio_dev_watch_cmd_t cmd,
/** 0 or bitwise-ORed of #STIO_DEV_EVENT_IN and #STIO_DEV_EVENT_OUT */
int events
);
STIO_EXPORT int stio_dev_read (
stio_dev_t* dev,
int enabled
);
/**
* The stio_dev_write() function posts a writing request.
* It attempts to write data immediately if there is no pending requests.
* If writing fails, it returns -1. If writing succeeds, it calls the
* on_write callback. If the callback fails, it returns -1. If the callback
* succeeds, it returns 1. If no immediate writing is possible, the request
* is enqueued to a pending request list. If enqueing gets successful,
* it returns 0. otherwise it returns -1.
*/
STIO_EXPORT int stio_dev_write (
stio_dev_t* dev,
const void* data,
stio_iolen_t len,
void* wrctx,
const stio_devaddr_t* dstaddr
);
STIO_EXPORT int stio_dev_timedwrite (
stio_dev_t* dev,
const void* data,
stio_iolen_t len,
const stio_ntime_t* tmout,
void* wrctx,
const stio_devaddr_t* dstaddr
);
STIO_EXPORT void stio_dev_halt (
stio_dev_t* dev
);
/* ========================================================================= */
#define stio_inittime(x,s,ns) (((x)->sec = (s)), ((x)->nsec = (ns)))
#define stio_cleartime(x) stio_inittime(x,0,0)
#define stio_cmptime(x,y) \
(((x)->sec == (y)->sec)? ((x)->nsec - (y)->nsec): \
((x)->sec - (y)->sec))
/* if time has been normalized properly, nsec must be equal to or
* greater than 0. */
#define stio_isnegtime(x) ((x)->sec < 0)
#define stio_ispostime(x) ((x)->sec > 0 || ((x)->sec == 0 && (x)->nsec > 0))
#define stio_iszerotime(x) ((x)->sec == 0 && (x)->nsec == 0)
/**
* The stio_gettime() function gets the current time.
*/
STIO_EXPORT void stio_gettime (
stio_ntime_t* nt
);
/**
* The stio_addtime() function adds x and y and stores the result in z
*/
STIO_EXPORT void stio_addtime (
const stio_ntime_t* x,
const stio_ntime_t* y,
stio_ntime_t* z
);
/**
* The stio_subtime() function subtract y from x and stores the result in z.
*/
STIO_EXPORT void stio_subtime (
const stio_ntime_t* x,
const stio_ntime_t* y,
stio_ntime_t* z
);
/**
* The stio_instmrjob() function schedules a new event.
*
* \return #STIO_TMRIDX_INVALID on failure, valid index on success.
*/
STIO_EXPORT stio_tmridx_t stio_instmrjob (
stio_t* stio,
const stio_tmrjob_t* job
);
STIO_EXPORT stio_tmridx_t stio_updtmrjob (
stio_t* stio,
stio_tmridx_t index,
const stio_tmrjob_t* job
);
STIO_EXPORT void stio_deltmrjob (
stio_t* stio,
stio_tmridx_t index
);
/**
* The stio_gettmrjob() function returns the
* pointer to the registered event at the given index.
*/
STIO_EXPORT stio_tmrjob_t* stio_gettmrjob (
stio_t* stio,
stio_tmridx_t index
);
STIO_EXPORT int stio_gettmrjobdeadline (
stio_t* stio,
stio_tmridx_t index,
stio_ntime_t* deadline
);
/* ========================================================================= */
#if defined(STIO_HAVE_UINT16_T)
STIO_EXPORT stio_uint16_t stio_ntoh16 (
stio_uint16_t x
);
STIO_EXPORT stio_uint16_t stio_hton16 (
stio_uint16_t x
);
#endif
#if defined(STIO_HAVE_UINT32_T)
STIO_EXPORT stio_uint32_t stio_ntoh32 (
stio_uint32_t x
);
STIO_EXPORT stio_uint32_t stio_hton32 (
stio_uint32_t x
);
#endif
#if defined(STIO_HAVE_UINT64_T)
STIO_EXPORT stio_uint64_t stio_ntoh64 (
stio_uint64_t x
);
STIO_EXPORT stio_uint64_t stio_hton64 (
stio_uint64_t x
);
#endif
#if defined(STIO_HAVE_UINT128_T)
STIO_EXPORT stio_uint128_t stio_ntoh128 (
stio_uint128_t x
);
STIO_EXPORT stio_uint128_t stio_hton128 (
stio_uint128_t x
);
#endif
/* ========================================================================= */
#ifdef __cplusplus
}
#endif
#endif