diff --git a/stio/lib/Makefile.am b/stio/lib/Makefile.am index 6151634..2b9713b 100644 --- a/stio/lib/Makefile.am +++ b/stio/lib/Makefile.am @@ -22,6 +22,8 @@ pkgbindir = $(bindir) pkginclude_HEADERS = \ stio-cfg.h \ stio-cmn.h \ + stio-pro.h \ + stio-sck.h \ stio-tcp.h \ stio-udp.h \ stio.h @@ -30,6 +32,7 @@ pkglib_LTLIBRARIES = libstio.la libstio_la_SOURCES = \ stio-prv.h \ stio.c \ + stio-pro.c \ stio-sck.c \ stio-tcp.c \ stio-tim.c \ diff --git a/stio/lib/Makefile.in b/stio/lib/Makefile.in index 6f9f369..afcac3e 100644 --- a/stio/lib/Makefile.in +++ b/stio/lib/Makefile.in @@ -129,9 +129,10 @@ LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) libstio_la_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_libstio_la_OBJECTS = libstio_la-stio.lo libstio_la-stio-sck.lo \ - libstio_la-stio-tcp.lo libstio_la-stio-tim.lo \ - libstio_la-stio-tmr.lo libstio_la-stio-udp.lo +am_libstio_la_OBJECTS = libstio_la-stio.lo libstio_la-stio-pro.lo \ + libstio_la-stio-sck.lo libstio_la-stio-tcp.lo \ + libstio_la-stio-tim.lo libstio_la-stio-tmr.lo \ + libstio_la-stio-udp.lo libstio_la_OBJECTS = $(am_libstio_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -379,6 +380,8 @@ pkgbindir = $(bindir) pkginclude_HEADERS = \ stio-cfg.h \ stio-cmn.h \ + stio-pro.h \ + stio-sck.h \ stio-tcp.h \ stio-udp.h \ stio.h @@ -387,6 +390,7 @@ pkglib_LTLIBRARIES = libstio.la libstio_la_SOURCES = \ stio-prv.h \ stio.c \ + stio-pro.c \ stio-sck.c \ stio-tcp.c \ stio-tim.c \ @@ -548,6 +552,7 @@ 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-tcp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-tim.Plo@am__quote@ @@ -584,6 +589,13 @@ libstio_la-stio.lo: stio.c @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 +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@ +@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 + 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 diff --git a/stio/lib/main.c b/stio/lib/main.c index ed80beb..0a1205f 100644 --- a/stio/lib/main.c +++ b/stio/lib/main.c @@ -60,7 +60,7 @@ static stio_mmgr_t mmgr = STIO_NULL }; -static void tcp_on_disconnected (stio_dev_tcp_t* tcp) +static void tcp_on_disconnect (stio_dev_tcp_t* tcp) { if (tcp->state & STIO_DEV_TCP_CONNECTING) { @@ -83,7 +83,7 @@ static void tcp_on_disconnected (stio_dev_tcp_t* tcp) printf ("TCP DISCONNECTED - THIS MUST NOT HAPPEN (%d)\n", tcp->sck); } } -static int tcp_on_connected (stio_dev_tcp_t* tcp) +static int tcp_on_connect (stio_dev_tcp_t* tcp) { if (tcp->state & STIO_DEV_TCP_CONNECTED) @@ -95,24 +95,24 @@ printf ("device connected to a remote server... .asdfjkasdfkljasdlfkjasdj...\n") printf ("device accepted client device... .asdfjkasdfkljasdlfkjasdj...\n"); } - return stio_dev_tcp_send (tcp, "hello", 5, STIO_NULL); + return stio_dev_tcp_write (tcp, "hello", 5, STIO_NULL); } -static int tcp_on_sent (stio_dev_tcp_t* tcp, void* sendctx) +static int tcp_on_write (stio_dev_tcp_t* tcp, void* wrctx) { printf (">>> TCP SENT MESSAGE\n"); return 0; } -static int tcp_on_recv (stio_dev_tcp_t* tcp, const void* buf, stio_len_t len) +static int tcp_on_read (stio_dev_tcp_t* tcp, const void* buf, stio_len_t len) { int n; static char a ='A'; char* xxx = malloc (1000000); memset (xxx, a++ ,1000000); - //return stio_dev_tcp_send (tcp, "HELLO", 5, STIO_NULL); - n = stio_dev_tcp_send (tcp, xxx, 1000000, STIO_NULL); + //return stio_dev_tcp_write (tcp, "HELLO", 5, STIO_NULL); + n = stio_dev_tcp_write (tcp, xxx, 1000000, STIO_NULL); free (xxx); return n; } @@ -170,8 +170,8 @@ int main () sin.sin_family = AF_INET; memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make)); memcpy (&tcp_make.addr, &sin, STIO_SIZEOF(sin)); - tcp_make.on_sent = tcp_on_sent; - tcp_make.on_recv = tcp_on_recv; + tcp_make.on_write = tcp_on_write; + tcp_make.on_read = tcp_on_read; tcp[0] = stio_dev_tcp_make (stio, 0, &tcp_make); if (!tcp[0]) { @@ -189,8 +189,8 @@ int main () memset (&tcp_conn, 0, STIO_SIZEOF(tcp_conn)); memcpy (&tcp_conn.addr, &sin, STIO_SIZEOF(sin)); tcp_conn.timeout.sec = 5; - tcp_conn.on_connected = tcp_on_connected; - tcp_conn.on_disconnected = tcp_on_disconnected; + tcp_conn.on_connect = tcp_on_connect; + tcp_conn.on_disconnect = tcp_on_disconnect; if (stio_dev_tcp_connect (tcp[0], &tcp_conn) <= -1) { printf ("stio_dev_tcp_connect() failed....\n"); @@ -202,8 +202,8 @@ int main () sin.sin_port = htons(1234); memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make)); memcpy (&tcp_make.addr, &sin, STIO_SIZEOF(sin)); - tcp_make.on_sent = tcp_on_sent; - tcp_make.on_recv = tcp_on_recv; + tcp_make.on_write = tcp_on_write; + tcp_make.on_read = tcp_on_read; tcp[1] = stio_dev_tcp_make (stio, 0, &tcp_make); if (!tcp[1]) @@ -213,8 +213,8 @@ int main () } tcp_lstn.backlogs = 100; - tcp_lstn.on_connected = tcp_on_connected; - tcp_lstn.on_disconnected = tcp_on_disconnected; + tcp_lstn.on_connect = tcp_on_connect; + tcp_lstn.on_disconnect = tcp_on_disconnect; if (stio_dev_tcp_listen (tcp[1], &tcp_lstn) <= -1) { printf ("stio_dev_tcp_listen() failed....\n"); diff --git a/stio/lib/stio-pro.c b/stio/lib/stio-pro.c new file mode 100644 index 0000000..8fadd5c --- /dev/null +++ b/stio/lib/stio-pro.c @@ -0,0 +1,259 @@ +/* + * $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 +#include +#include + +static int pro_make (stio_dev_t* dev, void* ctx) +{ + stio_dev_pro_t* pro = (stio_dev_pro_t*)dev; + stio_dev_pro_make_t* arg = (stio_dev_pro_make_t*)ctx; + stio_syshnd_t hnd[6]; + int i, minidx = -1, maxidx = -1; + + if (arg->flags & STIO_DEV_PRO_WRITEIN) + { + if (pipe(&hnd[0]) == -1) + { + dev->stio->errnum = stio_syserrtoerrnum(errno); + goto oops; + } + minidx = 0; maxidx = 1; + } + + if (arg->flags & STIO_DEV_PRO_READOUT) + { + if (pipe(&hnd[2]) == -1) + { + dev->stio->errnum = stio_syserrtoerrnum(errno); + goto oops; + } + if (minidx == -1) minidx = 2; + maxidx = 3; + } + + if (arg->flags & STIO_DEV_PRO_READERR) + { + if (pipe(&hnd[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; + } + + /* TODO: fork and exec... */ + + if (arg->flags & STIO_DEV_PRO_WRITEIN) + { + /* + * 012345 + * rw---- + * X + * WRITE => 1 + */ + close (hnd[0]); + hnd[0] = STIO_SYSHND_INVALID; + } + + if (arg->flags & STIO_DEV_PRO_READOUT) + { + /* + * 012345 + * --rw-- + * X + * READ => 2 + */ + close (hnd[3]); + hnd[3] = STIO_SYSHND_INVALID; + } + + if (arg->flags & STIO_DEV_PRO_READERR) + { + /* + * 012345 + * ----rw + * X + * READ => 4 + */ + close (hnd[5]); + hnd[5] = STIO_SYSHND_INVALID; + } + + if (stio_makesyshndasync (pro->stio, hnd[1]) <= -1 || + stio_makesyshndasync (pro->stio, hnd[2]) <= -1 || + stio_makesyshndasync (pro->stio, hnd[4]) <= -1) goto oops; + + return 0; + +oops: + for (i = minidx; i < maxidx; i++) + { + if (hnd[i] != STIO_SYSHND_INVALID) close (hnd[i]); + } + + return -1; +} + + +static void pro_kill (stio_dev_t* dev) +{ +} + +static int pro_read (stio_dev_t* dev, void* buf, stio_len_t* len) +{ + stio_dev_pro_t* pro = (stio_dev_pro_t*)dev; + ssize_t x; + + x = write (pro->pfd, buf, *len); + if (x <= -1) + { + if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0; /* no data available */ + if (errno == EINTR) return 0; + pro->stio->errnum = stio_syserrtoerrnum(errno); + return -1; + } + + *len = x; + return 1; +} + +static int pro_write (stio_dev_t* dev, const void* data, stio_len_t* len) +{ +} + +static stio_syshnd_t pro_getsyshnd (stio_dev_t* dev) +{ + stio_dev_pro_t* pro = (stio_dev_pro_t*)dev; + return (stio_syshnd_t)pro->pfd; +} + + +static int pro_ioctl (stio_dev_t* dev, int cmd, void* arg) +{ + return 0; +} + +static stio_dev_mth_t pro_mth = +{ + pro_make, + pro_kill, + pro_getsyshnd, + pro_read, + pro_write, + pro_ioctl +}; + +static int pro_ready (stio_dev_t* dev, int events) +{ + stio_dev_pro_t* pro = (stio_dev_pro_t*)dev; +printf ("PRO READY...%p\n", 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 (stio_dev_t* dev, const void* data, stio_len_t len) +{ + stio_dev_pro_t* pro = (stio_dev_pro_t*)dev; + return pro->on_read (pro, data, len); +} + +static int pro_on_write (stio_dev_t* dev, void* wrctx) +{ + stio_dev_pro_t* pro = (stio_dev_pro_t*)dev; + return pro->on_write (pro, wrctx); +} + +static stio_dev_evcb_t pro_evcb = +{ + pro_ready, + pro_on_read, + pro_on_write +}; + +stio_dev_pro_t* stio_dev_pro_make (stio_t* stio, stio_size_t xtnsize, const stio_dev_pro_make_t* data) +{ + return (stio_dev_pro_t*)stio_makedev (stio, STIO_SIZEOF(stio_dev_pro_t) + xtnsize, &pro_mth, &pro_evcb, (void*)data); +} + +void stio_dev_pro_kill (stio_dev_pro_t* pro) +{ + stio_killdev (pro->stio, (stio_dev_t*)pro); +} + +int stio_dev_pro_write (stio_dev_pro_t* pro, const void* data, stio_len_t len, void* wrctx) +{ + return stio_dev_write ((stio_dev_t*)pro, data, len, wrctx); +} + +#if 0 +stio_dev_pro_t* stio_dev_pro_getdev (stio_dev_pro_t* pro, stio_dev_pro_type_t type) +{ + 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 diff --git a/stio/lib/stio-pro.h b/stio/lib/stio-pro.h new file mode 100644 index 0000000..f52837c --- /dev/null +++ b/stio/lib/stio-pro.h @@ -0,0 +1,111 @@ +/* + * $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 + +enum stio_dev_pro_type_t +{ + STIO_DEV_PRO_IN, + STIO_DEV_PRO_OUT, + STIO_DEV_PRO_ERR, +}; +typedef enum stio_dev_pro_type_t stio_dev_pro_type_t; + + +typedef struct stio_dev_pro_t stio_dev_pro_t; + +typedef int (*stio_dev_pro_on_read_t) (stio_dev_pro_t* dev, const void* data, stio_len_t len); +typedef int (*stio_dev_pro_on_write_t) (stio_dev_pro_t* dev, void* wrctx); + +struct stio_dev_pro_t +{ + STIO_DEV_HEADERS; + + stio_syshnd_t pfd; + + /* bitwised-ORed of #stio_dev_pro_state_t enumerators */ + stio_dev_pro_type_t type; + + stio_dev_pro_t* sibling[2]; + + stio_dev_pro_on_read_t on_read; + stio_dev_pro_on_write_t on_write; + + stio_tmridx_t tmridx_connect; +}; + +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_INTONUL = (1 << 3), + STIO_DEV_PRO_OUTTONUL = (1 << 4), + STIO_DEV_PRO_ERRTONUL = (1 << 5), + STUO_DEV_PRO_DROPIN = (1 << 6), + STUO_DEV_PRO_DROPOUT = (1 << 7), + STUO_DEV_PRO_DROPERR = (1 << 8) +}; +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; + stio_dev_pro_on_read_t on_read; +}; + +#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_len_t len, + void* wrctx +); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stio/lib/stio-prv.h b/stio/lib/stio-prv.h index c3e09fe..72ca2ff 100644 --- a/stio/lib/stio-prv.h +++ b/stio/lib/stio-prv.h @@ -157,14 +157,14 @@ struct stio_t extern "C" { #endif -stio_errnum_t stio_syserrtoerrnum (int no); - -stio_sckhnd_t stio_openasyncsck (int domain, int type); -void stio_closeasyncsck (stio_sckhnd_t sck); -int stio_makesckasync (stio_sckhnd_t sck); - -int stio_getsckadrinfo (stio_t* stio, const stio_sckadr_t* addr, stio_scklen_t* len, stio_sckfam_t* family); +int stio_makesyshndasync ( + stio_t* stio, + stio_syshnd_t hnd +); +stio_errnum_t stio_syserrtoerrnum ( + int no +); /** diff --git a/stio/lib/stio-sck.c b/stio/lib/stio-sck.c index c36551f..14a4a2f 100644 --- a/stio/lib/stio-sck.c +++ b/stio/lib/stio-sck.c @@ -25,7 +25,9 @@ */ +#include "stio-sck.h" #include "stio-prv.h" + #include #include #include @@ -34,7 +36,7 @@ #include /* ------------------------------------------------------------------------ */ -void stio_closeasyncsck (stio_sckhnd_t sck) +void stio_closeasyncsck (stio_t* stio, stio_sckhnd_t sck) { #if defined(_WIN32) closesocket (sck); @@ -43,21 +45,12 @@ void stio_closeasyncsck (stio_sckhnd_t sck) #endif } -int stio_makesckasync (stio_sckhnd_t sck) +int stio_makesckasync (stio_t* stio, stio_sckhnd_t sck) { - int flags; - - if ((flags = fcntl (sck, F_GETFL)) <= -1 || - (flags = fcntl (sck, F_SETFL, flags | O_NONBLOCK)) <= -1) - { - /* stio_seterrnum (dev->stio, STIO_ESYSERR); or translate errno to stio errnum */ - return -1; - } - - return 0; + return stio_makesyshndasync (stio, (stio_syshnd_t)sck); } -stio_sckhnd_t stio_openasyncsck (int domain, int type) +stio_sckhnd_t stio_openasyncsck (stio_t* stio, int domain, int type) { stio_sckhnd_t sck; @@ -76,7 +69,7 @@ stio_sckhnd_t stio_openasyncsck (int domain, int type) return STIO_SCKHND_INVALID; } - if (stio_makesckasync (sck) <= -1) + if (stio_makesckasync (stio, sck) <= -1) { close (sck); return STIO_SCKHND_INVALID; diff --git a/stio/lib/stio-sck.h b/stio/lib/stio-sck.h new file mode 100644 index 0000000..58318a6 --- /dev/null +++ b/stio/lib/stio-sck.h @@ -0,0 +1,109 @@ +/* + * $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 + +struct stio_sckadr_t +{ + int family; + stio_uint8_t data[128]; /* TODO: use the actual sockaddr size */ +}; + +typedef struct stio_sckadr_t stio_sckadr_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 + +typedef int stio_sckfam_t; + +#ifdef __cplusplus +extern "C" { +#endif + + +STIO_EXPORT stio_sckhnd_t stio_openasyncsck ( + stio_t* stio, + int domain, + int type +); + +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_getsckadrinfo ( + stio_t* stio, + const stio_sckadr_t* addr, + stio_scklen_t* len, + stio_sckfam_t* family +); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/stio/lib/stio-tcp.c b/stio/lib/stio-tcp.c index 2fda05f..bacb099 100644 --- a/stio/lib/stio-tcp.c +++ b/stio/lib/stio-tcp.c @@ -25,8 +25,8 @@ */ -#include "stio-prv.h" #include "stio-tcp.h" +#include "stio-prv.h" #include #include @@ -36,8 +36,6 @@ static int tcp_make (stio_dev_t* dev, void* ctx) { -/* NOTE: this can be extended to use ctx to tell between INET and INET6 or other types of sockets without creating a new dev method set. */ - stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev; stio_dev_tcp_make_t* arg = (stio_dev_tcp_make_t*)ctx; stio_scklen_t len; @@ -46,7 +44,7 @@ static int tcp_make (stio_dev_t* dev, void* ctx) if (stio_getsckadrinfo(dev->stio, &arg->addr, &len, &family) <= -1) return -1; - tcp->sck = stio_openasyncsck (family, SOCK_STREAM); + tcp->sck = stio_openasyncsck (dev->stio, family, SOCK_STREAM); if (tcp->sck == STIO_SCKHND_INVALID) goto oops; //setsockopt (udp->sck, SOL_SOCKET, SO_REUSEADDR, ...); @@ -59,15 +57,15 @@ static int tcp_make (stio_dev_t* dev, void* ctx) goto oops; } - tcp->on_sent = arg->on_sent; - tcp->on_recv = arg->on_recv; + tcp->on_write = arg->on_write; + tcp->on_read = arg->on_read; tcp->tmridx_connect = STIO_TMRIDX_INVALID; return 0; oops: if (tcp->sck != STIO_SCKHND_INVALID) { - stio_closeasyncsck (tcp->sck); + stio_closeasyncsck (tcp->stio, tcp->sck); tcp->sck = STIO_SCKHND_INVALID; } return -1; @@ -79,7 +77,7 @@ static int tcp_make_accepted (stio_dev_t* dev, void* ctx) stio_syshnd_t* sck = (stio_syshnd_t*)ctx; tcp->sck = *sck; - if (stio_makesckasync (tcp->sck) <= -1) return -1; + if (stio_makesckasync (dev->stio, tcp->sck) <= -1) return -1; return 0; } @@ -90,7 +88,7 @@ static void tcp_kill (stio_dev_t* dev) if (tcp->state & (STIO_DEV_TCP_ACCEPTED | STIO_DEV_TCP_CONNECTED | STIO_DEV_TCP_CONNECTING | STIO_DEV_TCP_LISTENING)) { - if (tcp->on_disconnected) tcp->on_disconnected (tcp); + if (tcp->on_disconnect) tcp->on_disconnect (tcp); } if (tcp->tmridx_connect != STIO_TMRIDX_INVALID) @@ -101,7 +99,7 @@ static void tcp_kill (stio_dev_t* dev) if (tcp->sck != STIO_SCKHND_INVALID) { - stio_closeasyncsck (tcp->sck); + stio_closeasyncsck (tcp->stio, tcp->sck); tcp->sck = STIO_SCKHND_INVALID; } } @@ -113,7 +111,7 @@ static stio_syshnd_t tcp_getsyshnd (stio_dev_t* dev) } -static int tcp_recv (stio_dev_t* dev, void* buf, stio_len_t* len) +static int tcp_read (stio_dev_t* dev, void* buf, stio_len_t* len) { stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev; ssize_t x; @@ -131,7 +129,7 @@ static int tcp_recv (stio_dev_t* dev, void* buf, stio_len_t* len) return 1; } -static int tcp_send (stio_dev_t* dev, const void* data, stio_len_t* len) +static int tcp_write (stio_dev_t* dev, const void* data, stio_len_t* len) { stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev; ssize_t x; @@ -266,8 +264,8 @@ static int tcp_ioctl (stio_dev_t* dev, int cmd, void* arg) tcp->state |= STIO_DEV_TCP_CONNECTING; tcp->peer = conn->addr; - tcp->on_connected = conn->on_connected; - tcp->on_disconnected = conn->on_disconnected; + tcp->on_connect = conn->on_connect; + tcp->on_disconnect = conn->on_disconnect; return 0; } } @@ -279,8 +277,8 @@ static int tcp_ioctl (stio_dev_t* dev, int cmd, void* arg) /* connected immediately */ tcp->state |= STIO_DEV_TCP_CONNECTED; tcp->peer = conn->addr; - tcp->on_connected = conn->on_connected; - tcp->on_disconnected = conn->on_disconnected; + tcp->on_connect = conn->on_connect; + tcp->on_disconnect = conn->on_disconnect; return 0; #endif } @@ -301,8 +299,8 @@ static int tcp_ioctl (stio_dev_t* dev, int cmd, void* arg) } tcp->state |= STIO_DEV_TCP_LISTENING; - tcp->on_connected = lstn->on_connected; - tcp->on_disconnected = lstn->on_disconnected; + tcp->on_connect = lstn->on_connect; + tcp->on_disconnect = lstn->on_disconnect; return 0; #endif } @@ -317,9 +315,9 @@ static stio_dev_mth_t tcp_mth = tcp_make, tcp_kill, tcp_getsyshnd, + tcp_read, + tcp_write, tcp_ioctl, - tcp_recv, - tcp_send }; /* accepted tcp socket */ @@ -328,9 +326,9 @@ static stio_dev_mth_t tcp_acc_mth = tcp_make_accepted, tcp_kill, tcp_getsyshnd, - tcp_ioctl, - tcp_recv, - tcp_send + tcp_read, + tcp_write, + tcp_ioctl }; /* ------------------------------------------------------------------------ */ @@ -405,7 +403,7 @@ printf ("CAANOT MANIPULTE WATCHER ...\n"); STIO_ASSERT (tcp->tmridx_connect == STIO_TMRIDX_INVALID); } - if (tcp->on_connected (tcp) <= -1) + if (tcp->on_connect (tcp) <= -1) { printf ("ON_CONNECTE HANDLER RETURNEF FAILURE...\n"); return -1; @@ -422,7 +420,7 @@ printf ("CAANOT MANIPULTE WATCHER ...\n"); } } - return 0; /* success but don't invoke on_recv() */ + return 0; /* success but don't invoke on_read() */ } else if (tcp->state & STIO_DEV_TCP_LISTENING) { @@ -448,7 +446,7 @@ printf ("CAANOT MANIPULTE WATCHER ...\n"); addrlen = STIO_SIZEOF(peer); clisck = accept (tcp->sck, (struct sockaddr*)&peer, &addrlen); - if (clisck == -1) + if (clisck == STIO_SCKHND_INVALID) { if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0; if (errno == EINTR) return 0; /* if interrupted by a signal, treat it as if it's EINPROGRESS */ @@ -472,15 +470,15 @@ printf ("CAANOT MANIPULTE WATCHER ...\n"); /* inherit some event handlers from the parent. - * you can still change them inside the on_connected handler */ - clitcp->on_connected = tcp->on_connected; - clitcp->on_disconnected = tcp->on_disconnected; - clitcp->on_sent = tcp->on_sent; - clitcp->on_recv = tcp->on_recv; + * you can still change them inside the on_connect handler */ + clitcp->on_connect = tcp->on_connect; + clitcp->on_disconnect = tcp->on_disconnect; + clitcp->on_write = tcp->on_write; + clitcp->on_read = tcp->on_read; clitcp->tmridx_connect = STIO_TMRIDX_INVALID; - if (clitcp->on_connected (clitcp) <= -1) stio_dev_tcp_kill (clitcp); - return 0; /* success but don't invoke on_recv() */ + if (clitcp->on_connect (clitcp) <= -1) stio_dev_tcp_kill (clitcp); + return 0; /* success but don't invoke on_read() */ } } else if (events & STIO_DEV_EVENT_HUP) @@ -498,23 +496,23 @@ printf ("CAANOT MANIPULTE WATCHER ...\n"); return 1; /* the device is ok. carry on reading or writing */ } -static int tcp_on_recv (stio_dev_t* dev, const void* data, stio_len_t len) +static int tcp_on_read (stio_dev_t* dev, const void* data, stio_len_t len) { stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev; - return tcp->on_recv (tcp, data, len); + return tcp->on_read (tcp, data, len); } -static int tcp_on_sent (stio_dev_t* dev, void* sendctx) +static int tcp_on_write (stio_dev_t* dev, void* wrctx) { stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev; - return tcp->on_sent (tcp, sendctx); + return tcp->on_write (tcp, wrctx); } static stio_dev_evcb_t tcp_evcb = { tcp_ready, - tcp_on_recv, - tcp_on_sent + tcp_on_read, + tcp_on_write }; stio_dev_tcp_t* stio_dev_tcp_make (stio_t* stio, stio_size_t xtnsize, const stio_dev_tcp_make_t* data) @@ -542,7 +540,7 @@ int stio_dev_tcp_listen (stio_dev_tcp_t* tcp, stio_dev_tcp_listen_t* lstn) return stio_dev_ioctl ((stio_dev_t*)tcp, STIO_DEV_TCP_LISTEN, lstn); } -int stio_dev_tcp_send (stio_dev_tcp_t* tcp, const void* data, stio_len_t len, void* sendctx) +int stio_dev_tcp_write (stio_dev_tcp_t* tcp, const void* data, stio_len_t len, void* wrctx) { - return stio_dev_send ((stio_dev_t*)tcp, data, len, sendctx); + return stio_dev_write ((stio_dev_t*)tcp, data, len, wrctx); } diff --git a/stio/lib/stio-tcp.h b/stio/lib/stio-tcp.h index 83fdaef..cc73fa7 100644 --- a/stio/lib/stio-tcp.h +++ b/stio/lib/stio-tcp.h @@ -28,6 +28,7 @@ #define _STIO_TCP_H_ #include +#include enum stio_dev_tcp_ioctl_cmd_t { @@ -48,12 +49,12 @@ typedef enum stio_dev_tcp_state_t stio_dev_tcp_state_t; typedef struct stio_dev_tcp_t stio_dev_tcp_t; -typedef int (*stio_dev_tcp_on_connected_t) (stio_dev_tcp_t* dev); +typedef int (*stio_dev_tcp_on_connect_t) (stio_dev_tcp_t* dev); typedef void (*stio_dev_tcp_on_accepted_t) (stio_dev_tcp_t* dev, stio_dev_tcp_t* clidev); -typedef void (*stio_dev_tcp_on_disconnected_t) (stio_dev_tcp_t* dev); +typedef void (*stio_dev_tcp_on_disconnect_t) (stio_dev_tcp_t* dev); -typedef int (*stio_dev_tcp_on_recv_t) (stio_dev_tcp_t* dev, const void* data, stio_len_t len); -typedef int (*stio_dev_tcp_on_sent_t) (stio_dev_tcp_t* dev, void* sendctx); +typedef int (*stio_dev_tcp_on_read_t) (stio_dev_tcp_t* dev, const void* data, stio_len_t len); +typedef int (*stio_dev_tcp_on_write_t) (stio_dev_tcp_t* dev, void* wrctx); struct stio_dev_tcp_t { @@ -70,17 +71,14 @@ struct stio_dev_tcp_t * STIO_DEV_TCP_CONNECTING */ stio_sckadr_t peer; - /* parent tcp device. valid if STIO_DEV_TCP_ACCEPTED is set */ - /*stio_dev_tcp_t* parent;*/ - /** 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_tcp_on_connected_t on_connected; + stio_dev_tcp_on_connect_t on_connect; - stio_dev_tcp_on_disconnected_t on_disconnected; - stio_dev_tcp_on_recv_t on_recv; - stio_dev_tcp_on_sent_t on_sent; + stio_dev_tcp_on_disconnect_t on_disconnect; + stio_dev_tcp_on_read_t on_read; + stio_dev_tcp_on_write_t on_write; stio_tmridx_t tmridx_connect; }; @@ -90,8 +88,8 @@ struct stio_dev_tcp_make_t { /* TODO: options: REUSEADDR for binding?? */ stio_sckadr_t addr; /* binding address. */ - stio_dev_tcp_on_sent_t on_sent; - stio_dev_tcp_on_recv_t on_recv; + stio_dev_tcp_on_write_t on_write; + stio_dev_tcp_on_read_t on_read; }; typedef struct stio_dev_tcp_bind_t stio_dev_tcp_bind_t; @@ -107,16 +105,16 @@ struct stio_dev_tcp_connect_t { stio_sckadr_t addr; stio_ntime_t timeout; /* connect timeout */ - stio_dev_tcp_on_connected_t on_connected; - stio_dev_tcp_on_disconnected_t on_disconnected; + stio_dev_tcp_on_connect_t on_connect; + stio_dev_tcp_on_disconnect_t on_disconnect; }; typedef struct stio_dev_tcp_listen_t stio_dev_tcp_listen_t; struct stio_dev_tcp_listen_t { int backlogs; - stio_dev_tcp_on_connected_t on_connected; /* optional, but new connections are dropped immediately without this */ - stio_dev_tcp_on_disconnected_t on_disconnected; /* should on_discconneted be part of on_accept_t??? */ + stio_dev_tcp_on_connect_t on_connect; /* optional, but new connections are dropped immediately without this */ + stio_dev_tcp_on_disconnect_t on_disconnect; /* should on_discconneted be part of on_accept_t??? */ }; typedef struct stio_dev_tcp_accept_t stio_dev_tcp_accept_t; @@ -124,7 +122,6 @@ struct stio_dev_tcp_accept_t { stio_syshnd_t sck; /* TODO: add timeout */ - /*stio_dev_tcp_t* parent;*/ stio_sckadr_t peer; }; @@ -156,11 +153,11 @@ STIO_EXPORT int stio_dev_tcp_listen ( stio_dev_tcp_listen_t* lstn ); -STIO_EXPORT int stio_dev_tcp_send ( +STIO_EXPORT int stio_dev_tcp_write ( stio_dev_tcp_t* tcp, const void* data, stio_len_t len, - void* sendctx + void* wrctx ); #ifdef __cplusplus diff --git a/stio/lib/stio-udp.c b/stio/lib/stio-udp.c index 096ebe3..8732514 100644 --- a/stio/lib/stio-udp.c +++ b/stio/lib/stio-udp.c @@ -25,8 +25,8 @@ */ -#include "stio-prv.h" #include "stio-udp.h" +#include "stio-prv.h" #include #include @@ -43,7 +43,7 @@ static int udp_make (stio_dev_t* dev, void* ctx) if (stio_getsckadrinfo(dev->stio, &arg->addr, &len, &family) <= -1) return -1; - udp->sck = stio_openasyncsck (family, SOCK_DGRAM); + udp->sck = stio_openasyncsck (dev->stio, family, SOCK_DGRAM); if (udp->sck == STIO_SCKHND_INVALID) goto oops; /* some socket options? */ @@ -53,14 +53,14 @@ static int udp_make (stio_dev_t* dev, void* ctx) goto oops; } - udp->on_sent = arg->on_sent; - udp->on_recv = arg->on_recv; + udp->on_write = arg->on_write; + udp->on_read = arg->on_read; return 0; oops: if (udp->sck != STIO_SCKHND_INVALID) { - stio_closeasyncsck (udp->sck); + stio_closeasyncsck (udp->stio, udp->sck); udp->sck = STIO_SCKHND_INVALID; } return -1; @@ -71,7 +71,7 @@ static void udp_kill (stio_dev_t* dev) stio_dev_udp_t* udp = (stio_dev_udp_t*)dev; if (udp->sck != STIO_SCKHND_INVALID) { - stio_closeasyncsck (udp->sck); + stio_closeasyncsck (udp->stio, udp->sck); udp->sck = STIO_SCKHND_INVALID; } } @@ -82,13 +82,13 @@ static stio_syshnd_t udp_getsyshnd (stio_dev_t* dev) return (stio_syshnd_t)udp->sck; } -static int udp_recv (stio_dev_t* dev, void* buf, stio_len_t* len) +static int udp_read (stio_dev_t* dev, void* buf, stio_len_t* len) { stio_dev_udp_t* udp = (stio_dev_udp_t*)dev; stio_scklen_t addrlen; int x; -/* TODO: udp_recv need source address ... have to extend the send callback to accept the source address */ +/* TODO: udp_read need source address ... have to extend the send callback to accept the source address */ printf ("UDP RECVFROM...\n"); addrlen = STIO_SIZEOF(udp->peer); x = recvfrom (udp->sck, buf, *len, 0, (struct sockaddr*)&udp->peer, &addrlen); @@ -104,13 +104,13 @@ printf ("UDP RECVFROM...\n"); return 1; } -static int udp_send (stio_dev_t* dev, const void* data, stio_len_t* len) +static int udp_write (stio_dev_t* dev, const void* data, stio_len_t* len) { stio_dev_udp_t* udp = (stio_dev_udp_t*)udp; ssize_t x; #if 0 -/* TODO: udp_send need target address ... have to extend the send callback to accept the target address */ +/* TODO: udp_write need target address ... have to extend the send callback to accept the target address */ x = sendto (udp->sck, data, *len, skad, stio_getskadlen(skad)); if (x <= -1) { @@ -137,17 +137,15 @@ static int udp_ioctl (stio_dev_t* dev, int cmd, void* arg) /* ------------------------------------------------------------------------ */ -// ----------------------------------------------------------------- - static stio_dev_mth_t udp_mth = { udp_make, udp_kill, udp_getsyshnd, + udp_read, + udp_write, udp_ioctl, /* ioctl */ - udp_recv, - udp_send }; static int udp_ready (stio_dev_t* dev, int events) @@ -162,14 +160,14 @@ static int udp_ready (stio_dev_t* dev, int events) return 0; } -static int udp_on_recv (stio_dev_t* dev, const void* data, stio_len_t len) +static int udp_on_read (stio_dev_t* dev, const void* data, stio_len_t len) { printf ("dATA received %d bytes\n", (int)len); return 0; } -static int udp_on_sent (stio_dev_t* dev, void* msgid) +static int udp_on_write (stio_dev_t* dev, void* msgid) { return 0; @@ -178,8 +176,8 @@ static int udp_on_sent (stio_dev_t* dev, void* msgid) static stio_dev_evcb_t udp_evcb = { udp_ready, - udp_on_recv, - udp_on_sent + udp_on_read, + udp_on_write }; diff --git a/stio/lib/stio-udp.h b/stio/lib/stio-udp.h index 29fa00f..83b2a2e 100644 --- a/stio/lib/stio-udp.h +++ b/stio/lib/stio-udp.h @@ -29,19 +29,20 @@ #define _STIO_UDP_H_ #include +#include typedef struct stio_dev_udp_t stio_dev_udp_t; -typedef int (*stio_dev_udp_on_recv_t) (stio_dev_udp_t* dev, const void* data, stio_len_t len); -typedef int (*stio_dev_udp_on_sent_t) (stio_dev_udp_t* dev, void* sendctx); +typedef int (*stio_dev_udp_on_read_t) (stio_dev_udp_t* dev, const void* data, stio_len_t len); +typedef int (*stio_dev_udp_on_write_t) (stio_dev_udp_t* dev, void* wrctx); typedef struct stio_dev_udp_make_t stio_dev_udp_make_t; struct stio_dev_udp_make_t { /* TODO: options: REUSEADDR for binding?? */ stio_sckadr_t addr; /* binding address. */ - stio_dev_udp_on_sent_t on_sent; - stio_dev_udp_on_recv_t on_recv; + stio_dev_udp_on_write_t on_write; + stio_dev_udp_on_read_t on_read; }; struct stio_dev_udp_t @@ -50,8 +51,8 @@ struct stio_dev_udp_t stio_sckhnd_t sck; stio_sckadr_t peer; - stio_dev_udp_on_sent_t on_sent; - stio_dev_udp_on_recv_t on_recv; + stio_dev_udp_on_write_t on_write; + stio_dev_udp_on_read_t on_read; }; #ifdef __cplusplus diff --git a/stio/lib/stio.c b/stio/lib/stio.c index 561a284..999c3e5 100644 --- a/stio/lib/stio.c +++ b/stio/lib/stio.c @@ -348,7 +348,7 @@ int stio_exec (stio_t* stio) while (1) { len = STIO_COUNTOF(stio->bigbuf); - x = dev->dev_mth->recv (dev, stio->bigbuf, &len); + x = dev->dev_mth->read (dev, stio->bigbuf, &len); if (x <= -1) { @@ -390,11 +390,11 @@ int stio_exec (stio_t* stio) } else { - /* TODO: for a stream device, merge received data if bigbuf isn't full and fire the on_recv callback + /* TODO: for a stream device, merge received data if bigbuf isn't full and fire the on_read callback * when x == 0 or <= -1. you can */ /* data available */ - if (dev->dev_evcb->on_recv (dev, stio->bigbuf, len) <= -1) + if (dev->dev_evcb->on_read (dev, stio->bigbuf, len) <= -1) { stio_ruindev (stio, dev); dev = STIO_NULL; @@ -421,7 +421,7 @@ int stio_exec (stio_t* stio) send_leftover: ulen = urem; - x = dev->dev_mth->send (dev, uptr, &ulen); + x = dev->dev_mth->write (dev, uptr, &ulen); if (x <= -1) { /* TODO: error handling? call callback? or what? */ @@ -446,7 +446,7 @@ int stio_exec (stio_t* stio) int y; STIO_WQ_UNLINK (q); /* STIO_WQ_DEQ(&dev->wq); */ - y = dev->dev_evcb->on_sent (dev, q->ctx); + y = dev->dev_evcb->on_write (dev, q->ctx); STIO_MMGR_FREE (dev->stio->mmgr, q); if (y <= -1) @@ -589,7 +589,7 @@ int stio_dev_watch (stio_dev_t* dev, stio_dev_watch_cmd_t cmd, int events) return 0; } -int stio_dev_send (stio_dev_t* dev, const void* data, stio_len_t len, void* sendctx) +int stio_dev_write (stio_dev_t* dev, const void* data, stio_len_t len, void* wrctx) { const stio_uint8_t* uptr; stio_len_t urem, ulen; @@ -611,7 +611,7 @@ int stio_dev_send (stio_dev_t* dev, const void* data, stio_len_t len, void* send while (urem > 0) { ulen = urem; - x = dev->dev_mth->send (dev, data, &ulen); + x = dev->dev_mth->write (dev, data, &ulen); if (x <= -1) return -1; else if (x == 0) goto enqueue_data; /* enqueue remaining data */ else @@ -621,7 +621,7 @@ int stio_dev_send (stio_dev_t* dev, const void* data, stio_len_t len, void* send } } - dev->dev_evcb->on_sent (dev, sendctx); + dev->dev_evcb->on_write (dev, wrctx); return 0; enqueue_data: @@ -633,7 +633,7 @@ enqueue_data: return -1; } - q->ctx = sendctx; + q->ctx = wrctx; q->ptr = (stio_uint8_t*)(q + 1); q->len = urem; STIO_MEMCPY (q->ptr, uptr, urem); @@ -652,6 +652,25 @@ enqueue_data: return 0; } +int stio_makesyshndasync (stio_t* stio, stio_syshnd_t hnd) +{ +#if defined(F_GETFL) && defined(F_SETFL) && defined(O_NONBLOCK) + int flags; + + if ((flags = fcntl (hnd, F_GETFL)) <= -1 || + (flags = fcntl (hnd, F_SETFL, flags | O_NONBLOCK)) <= -1) + { + stio->errnum = stio_syserrtoerrnum (errno); + return -1; + } + + return 0; +#else + stio->errnum = STIO_ENOSUP; + return -1; +#endif +} + stio_errnum_t stio_syserrtoerrnum (int no) { switch (no) diff --git a/stio/lib/stio.h b/stio/lib/stio.h index e947324..4115ded 100644 --- a/stio/lib/stio.h +++ b/stio/lib/stio.h @@ -40,51 +40,14 @@ struct stio_ntime_t stio_int32_t nsec; /* nanoseconds */ }; - -struct stio_sckadr_t -{ - int family; - stio_uint8_t data[128]; /* TODO: use the actual sockaddr size */ -}; - -typedef struct stio_sckadr_t stio_sckadr_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_syshnd_t; - typedef stio_uintptr_t qse_sckhnd_t; -# define STIO_SCKHND_INVALID (~(qse_sck_hnd_t)0) - + #define STIO_SYSHND_INVALID (~(stio_uintptr_t)0) #else typedef int stio_syshnd_t; - typedef int stio_sckhnd_t; -# define STIO_SCKHND_INVALID (-1) - + #define STIO_SYSHND_INVALID (-1) #endif -typedef int stio_sckfam_t; /* ------------------------------------------------------------------------- */ typedef struct stio_t stio_t; @@ -130,18 +93,20 @@ struct stio_dev_mth_t /* ------------------------------------------------------------------ */ stio_syshnd_t (*getsyshnd) (stio_dev_t* dev); /* mandatory. called in stio_makedev() after successful make() */ - /* ------------------------------------------------------------------ */ - int (*ioctl) (stio_dev_t* dev, int cmd, void* arg); /* ------------------------------------------------------------------ */ /* 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. * it must not kill the device */ - int (*recv) (stio_dev_t* dev, void* data, stio_len_t* len); + int (*read) (stio_dev_t* dev, void* data, stio_len_t* len); /* ------------------------------------------------------------------ */ - int (*send) (stio_dev_t* dev, const void* data, stio_len_t* len); + int (*write) (stio_dev_t* dev, const void* data, stio_len_t* len); + + /* ------------------------------------------------------------------ */ + int (*ioctl) (stio_dev_t* dev, int cmd, void* arg); + }; struct stio_dev_evcb_t @@ -154,11 +119,11 @@ struct stio_dev_evcb_t /* return -1 on failure, 0 on success * it must not kill the device */ - int (*on_recv) (stio_dev_t* dev, const void* data, stio_len_t len); + int (*on_read) (stio_dev_t* dev, const void* data, stio_len_t len); /* return -1 on failure, 0 on success. * it must not kill the device */ - int (*on_sent) (stio_dev_t* dev, void* sendctx); + int (*on_write) (stio_dev_t* dev, void* wrctx); }; struct stio_wq_t @@ -340,11 +305,11 @@ STIO_EXPORT int stio_dev_watch ( int events ); -STIO_EXPORT int stio_dev_send ( +STIO_EXPORT int stio_dev_write ( stio_dev_t* dev, const void* data, stio_len_t len, - void* sendctx + void* wrctx ); #ifdef __cplusplus