renamed recv and send to read and write respectively

added some code for process pipes
This commit is contained in:
hyung-hwan 2016-02-02 15:40:09 +00:00
parent 7f47a92573
commit 8768bf4063
14 changed files with 645 additions and 180 deletions

View File

@ -22,6 +22,8 @@ pkgbindir = $(bindir)
pkginclude_HEADERS = \ pkginclude_HEADERS = \
stio-cfg.h \ stio-cfg.h \
stio-cmn.h \ stio-cmn.h \
stio-pro.h \
stio-sck.h \
stio-tcp.h \ stio-tcp.h \
stio-udp.h \ stio-udp.h \
stio.h stio.h
@ -30,6 +32,7 @@ pkglib_LTLIBRARIES = libstio.la
libstio_la_SOURCES = \ libstio_la_SOURCES = \
stio-prv.h \ stio-prv.h \
stio.c \ stio.c \
stio-pro.c \
stio-sck.c \ stio-sck.c \
stio-tcp.c \ stio-tcp.c \
stio-tim.c \ stio-tim.c \

View File

@ -129,9 +129,10 @@ LTLIBRARIES = $(pkglib_LTLIBRARIES)
am__DEPENDENCIES_1 = am__DEPENDENCIES_1 =
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
libstio_la_DEPENDENCIES = $(am__DEPENDENCIES_2) libstio_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_libstio_la_OBJECTS = libstio_la-stio.lo libstio_la-stio-sck.lo \ am_libstio_la_OBJECTS = libstio_la-stio.lo libstio_la-stio-pro.lo \
libstio_la-stio-tcp.lo libstio_la-stio-tim.lo \ libstio_la-stio-sck.lo libstio_la-stio-tcp.lo \
libstio_la-stio-tmr.lo libstio_la-stio-udp.lo libstio_la-stio-tim.lo libstio_la-stio-tmr.lo \
libstio_la-stio-udp.lo
libstio_la_OBJECTS = $(am_libstio_la_OBJECTS) libstio_la_OBJECTS = $(am_libstio_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@) AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@ -379,6 +380,8 @@ pkgbindir = $(bindir)
pkginclude_HEADERS = \ pkginclude_HEADERS = \
stio-cfg.h \ stio-cfg.h \
stio-cmn.h \ stio-cmn.h \
stio-pro.h \
stio-sck.h \
stio-tcp.h \ stio-tcp.h \
stio-udp.h \ stio-udp.h \
stio.h stio.h
@ -387,6 +390,7 @@ pkglib_LTLIBRARIES = libstio.la
libstio_la_SOURCES = \ libstio_la_SOURCES = \
stio-prv.h \ stio-prv.h \
stio.c \ stio.c \
stio-pro.c \
stio-sck.c \ stio-sck.c \
stio-tcp.c \ stio-tcp.c \
stio-tim.c \ stio-tim.c \
@ -548,6 +552,7 @@ mostlyclean-compile:
distclean-compile: distclean-compile:
-rm -f *.tab.c -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-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-tcp.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-tim.Plo@am__quote@
@ -584,6 +589,13 @@ libstio_la-stio.lo: stio.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @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) $(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 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_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 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstio_la-stio-sck.Tpo $(DEPDIR)/libstio_la-stio-sck.Plo

View File

@ -60,7 +60,7 @@ static stio_mmgr_t mmgr =
STIO_NULL 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) 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); 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) 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"); 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"); printf (">>> TCP SENT MESSAGE\n");
return 0; 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; int n;
static char a ='A'; static char a ='A';
char* xxx = malloc (1000000); char* xxx = malloc (1000000);
memset (xxx, a++ ,1000000); memset (xxx, a++ ,1000000);
//return stio_dev_tcp_send (tcp, "HELLO", 5, STIO_NULL); //return stio_dev_tcp_write (tcp, "HELLO", 5, STIO_NULL);
n = stio_dev_tcp_send (tcp, xxx, 1000000, STIO_NULL); n = stio_dev_tcp_write (tcp, xxx, 1000000, STIO_NULL);
free (xxx); free (xxx);
return n; return n;
} }
@ -170,8 +170,8 @@ int main ()
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make)); memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make));
memcpy (&tcp_make.addr, &sin, STIO_SIZEOF(sin)); memcpy (&tcp_make.addr, &sin, STIO_SIZEOF(sin));
tcp_make.on_sent = tcp_on_sent; tcp_make.on_write = tcp_on_write;
tcp_make.on_recv = tcp_on_recv; tcp_make.on_read = tcp_on_read;
tcp[0] = stio_dev_tcp_make (stio, 0, &tcp_make); tcp[0] = stio_dev_tcp_make (stio, 0, &tcp_make);
if (!tcp[0]) if (!tcp[0])
{ {
@ -189,8 +189,8 @@ int main ()
memset (&tcp_conn, 0, STIO_SIZEOF(tcp_conn)); memset (&tcp_conn, 0, STIO_SIZEOF(tcp_conn));
memcpy (&tcp_conn.addr, &sin, STIO_SIZEOF(sin)); memcpy (&tcp_conn.addr, &sin, STIO_SIZEOF(sin));
tcp_conn.timeout.sec = 5; tcp_conn.timeout.sec = 5;
tcp_conn.on_connected = tcp_on_connected; tcp_conn.on_connect = tcp_on_connect;
tcp_conn.on_disconnected = tcp_on_disconnected; tcp_conn.on_disconnect = tcp_on_disconnect;
if (stio_dev_tcp_connect (tcp[0], &tcp_conn) <= -1) if (stio_dev_tcp_connect (tcp[0], &tcp_conn) <= -1)
{ {
printf ("stio_dev_tcp_connect() failed....\n"); printf ("stio_dev_tcp_connect() failed....\n");
@ -202,8 +202,8 @@ int main ()
sin.sin_port = htons(1234); sin.sin_port = htons(1234);
memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make)); memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make));
memcpy (&tcp_make.addr, &sin, STIO_SIZEOF(sin)); memcpy (&tcp_make.addr, &sin, STIO_SIZEOF(sin));
tcp_make.on_sent = tcp_on_sent; tcp_make.on_write = tcp_on_write;
tcp_make.on_recv = tcp_on_recv; tcp_make.on_read = tcp_on_read;
tcp[1] = stio_dev_tcp_make (stio, 0, &tcp_make); tcp[1] = stio_dev_tcp_make (stio, 0, &tcp_make);
if (!tcp[1]) if (!tcp[1])
@ -213,8 +213,8 @@ int main ()
} }
tcp_lstn.backlogs = 100; tcp_lstn.backlogs = 100;
tcp_lstn.on_connected = tcp_on_connected; tcp_lstn.on_connect = tcp_on_connect;
tcp_lstn.on_disconnected = tcp_on_disconnected; tcp_lstn.on_disconnect = tcp_on_disconnect;
if (stio_dev_tcp_listen (tcp[1], &tcp_lstn) <= -1) if (stio_dev_tcp_listen (tcp[1], &tcp_lstn) <= -1)
{ {
printf ("stio_dev_tcp_listen() failed....\n"); printf ("stio_dev_tcp_listen() failed....\n");

259
stio/lib/stio-pro.c Normal file
View File

@ -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 <unistd.h>
#include <fcntl.h>
#include <errno.h>
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

111
stio/lib/stio-pro.h Normal file
View File

@ -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 <stio.h>
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

View File

@ -157,14 +157,14 @@ struct stio_t
extern "C" { extern "C" {
#endif #endif
stio_errnum_t stio_syserrtoerrnum (int no); int stio_makesyshndasync (
stio_t* stio,
stio_sckhnd_t stio_openasyncsck (int domain, int type); stio_syshnd_t hnd
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);
stio_errnum_t stio_syserrtoerrnum (
int no
);
/** /**

View File

@ -25,7 +25,9 @@
*/ */
#include "stio-sck.h"
#include "stio-prv.h" #include "stio-prv.h"
#include <sys/socket.h> #include <sys/socket.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
@ -34,7 +36,7 @@
#include <arpa/inet.h> #include <arpa/inet.h>
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
void stio_closeasyncsck (stio_sckhnd_t sck) void stio_closeasyncsck (stio_t* stio, stio_sckhnd_t sck)
{ {
#if defined(_WIN32) #if defined(_WIN32)
closesocket (sck); closesocket (sck);
@ -43,21 +45,12 @@ void stio_closeasyncsck (stio_sckhnd_t sck)
#endif #endif
} }
int stio_makesckasync (stio_sckhnd_t sck) int stio_makesckasync (stio_t* stio, stio_sckhnd_t sck)
{ {
int flags; return stio_makesyshndasync (stio, (stio_syshnd_t)sck);
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;
} }
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; stio_sckhnd_t sck;
@ -76,7 +69,7 @@ stio_sckhnd_t stio_openasyncsck (int domain, int type)
return STIO_SCKHND_INVALID; return STIO_SCKHND_INVALID;
} }
if (stio_makesckasync (sck) <= -1) if (stio_makesckasync (stio, sck) <= -1)
{ {
close (sck); close (sck);
return STIO_SCKHND_INVALID; return STIO_SCKHND_INVALID;

109
stio/lib/stio-sck.h Normal file
View File

@ -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 <stio.h>
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

View File

@ -25,8 +25,8 @@
*/ */
#include "stio-prv.h"
#include "stio-tcp.h" #include "stio-tcp.h"
#include "stio-prv.h"
#include <unistd.h> #include <unistd.h>
#include <sys/socket.h> #include <sys/socket.h>
@ -36,8 +36,6 @@
static int tcp_make (stio_dev_t* dev, void* ctx) 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_t* tcp = (stio_dev_tcp_t*)dev;
stio_dev_tcp_make_t* arg = (stio_dev_tcp_make_t*)ctx; stio_dev_tcp_make_t* arg = (stio_dev_tcp_make_t*)ctx;
stio_scklen_t len; 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; 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; if (tcp->sck == STIO_SCKHND_INVALID) goto oops;
//setsockopt (udp->sck, SOL_SOCKET, SO_REUSEADDR, ...); //setsockopt (udp->sck, SOL_SOCKET, SO_REUSEADDR, ...);
@ -59,15 +57,15 @@ static int tcp_make (stio_dev_t* dev, void* ctx)
goto oops; goto oops;
} }
tcp->on_sent = arg->on_sent; tcp->on_write = arg->on_write;
tcp->on_recv = arg->on_recv; tcp->on_read = arg->on_read;
tcp->tmridx_connect = STIO_TMRIDX_INVALID; tcp->tmridx_connect = STIO_TMRIDX_INVALID;
return 0; return 0;
oops: oops:
if (tcp->sck != STIO_SCKHND_INVALID) if (tcp->sck != STIO_SCKHND_INVALID)
{ {
stio_closeasyncsck (tcp->sck); stio_closeasyncsck (tcp->stio, tcp->sck);
tcp->sck = STIO_SCKHND_INVALID; tcp->sck = STIO_SCKHND_INVALID;
} }
return -1; 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; stio_syshnd_t* sck = (stio_syshnd_t*)ctx;
tcp->sck = *sck; tcp->sck = *sck;
if (stio_makesckasync (tcp->sck) <= -1) return -1; if (stio_makesckasync (dev->stio, tcp->sck) <= -1) return -1;
return 0; 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->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) 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) if (tcp->sck != STIO_SCKHND_INVALID)
{ {
stio_closeasyncsck (tcp->sck); stio_closeasyncsck (tcp->stio, tcp->sck);
tcp->sck = STIO_SCKHND_INVALID; 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; stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
ssize_t x; ssize_t x;
@ -131,7 +129,7 @@ static int tcp_recv (stio_dev_t* dev, void* buf, stio_len_t* len)
return 1; 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; stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
ssize_t x; 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->state |= STIO_DEV_TCP_CONNECTING;
tcp->peer = conn->addr; tcp->peer = conn->addr;
tcp->on_connected = conn->on_connected; tcp->on_connect = conn->on_connect;
tcp->on_disconnected = conn->on_disconnected; tcp->on_disconnect = conn->on_disconnect;
return 0; return 0;
} }
} }
@ -279,8 +277,8 @@ static int tcp_ioctl (stio_dev_t* dev, int cmd, void* arg)
/* connected immediately */ /* connected immediately */
tcp->state |= STIO_DEV_TCP_CONNECTED; tcp->state |= STIO_DEV_TCP_CONNECTED;
tcp->peer = conn->addr; tcp->peer = conn->addr;
tcp->on_connected = conn->on_connected; tcp->on_connect = conn->on_connect;
tcp->on_disconnected = conn->on_disconnected; tcp->on_disconnect = conn->on_disconnect;
return 0; return 0;
#endif #endif
} }
@ -301,8 +299,8 @@ static int tcp_ioctl (stio_dev_t* dev, int cmd, void* arg)
} }
tcp->state |= STIO_DEV_TCP_LISTENING; tcp->state |= STIO_DEV_TCP_LISTENING;
tcp->on_connected = lstn->on_connected; tcp->on_connect = lstn->on_connect;
tcp->on_disconnected = lstn->on_disconnected; tcp->on_disconnect = lstn->on_disconnect;
return 0; return 0;
#endif #endif
} }
@ -317,9 +315,9 @@ static stio_dev_mth_t tcp_mth =
tcp_make, tcp_make,
tcp_kill, tcp_kill,
tcp_getsyshnd, tcp_getsyshnd,
tcp_read,
tcp_write,
tcp_ioctl, tcp_ioctl,
tcp_recv,
tcp_send
}; };
/* accepted tcp socket */ /* accepted tcp socket */
@ -328,9 +326,9 @@ static stio_dev_mth_t tcp_acc_mth =
tcp_make_accepted, tcp_make_accepted,
tcp_kill, tcp_kill,
tcp_getsyshnd, tcp_getsyshnd,
tcp_ioctl, tcp_read,
tcp_recv, tcp_write,
tcp_send tcp_ioctl
}; };
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
@ -405,7 +403,7 @@ printf ("CAANOT MANIPULTE WATCHER ...\n");
STIO_ASSERT (tcp->tmridx_connect == STIO_TMRIDX_INVALID); 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"); printf ("ON_CONNECTE HANDLER RETURNEF FAILURE...\n");
return -1; 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) else if (tcp->state & STIO_DEV_TCP_LISTENING)
{ {
@ -448,7 +446,7 @@ printf ("CAANOT MANIPULTE WATCHER ...\n");
addrlen = STIO_SIZEOF(peer); addrlen = STIO_SIZEOF(peer);
clisck = accept (tcp->sck, (struct sockaddr*)&peer, &addrlen); 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 == EINPROGRESS || errno == EWOULDBLOCK) return 0;
if (errno == EINTR) return 0; /* if interrupted by a signal, treat it as if it's EINPROGRESS */ 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. /* inherit some event handlers from the parent.
* you can still change them inside the on_connected handler */ * you can still change them inside the on_connect handler */
clitcp->on_connected = tcp->on_connected; clitcp->on_connect = tcp->on_connect;
clitcp->on_disconnected = tcp->on_disconnected; clitcp->on_disconnect = tcp->on_disconnect;
clitcp->on_sent = tcp->on_sent; clitcp->on_write = tcp->on_write;
clitcp->on_recv = tcp->on_recv; clitcp->on_read = tcp->on_read;
clitcp->tmridx_connect = STIO_TMRIDX_INVALID; clitcp->tmridx_connect = STIO_TMRIDX_INVALID;
if (clitcp->on_connected (clitcp) <= -1) stio_dev_tcp_kill (clitcp); if (clitcp->on_connect (clitcp) <= -1) stio_dev_tcp_kill (clitcp);
return 0; /* success but don't invoke on_recv() */ return 0; /* success but don't invoke on_read() */
} }
} }
else if (events & STIO_DEV_EVENT_HUP) 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 */ 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; 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; 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 = static stio_dev_evcb_t tcp_evcb =
{ {
tcp_ready, tcp_ready,
tcp_on_recv, tcp_on_read,
tcp_on_sent 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) 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); 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);
} }

View File

@ -28,6 +28,7 @@
#define _STIO_TCP_H_ #define _STIO_TCP_H_
#include <stio.h> #include <stio.h>
#include <stio-sck.h>
enum stio_dev_tcp_ioctl_cmd_t 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 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_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_read_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_write_t) (stio_dev_tcp_t* dev, void* wrctx);
struct stio_dev_tcp_t struct stio_dev_tcp_t
{ {
@ -70,17 +71,14 @@ struct stio_dev_tcp_t
* STIO_DEV_TCP_CONNECTING */ * STIO_DEV_TCP_CONNECTING */
stio_sckadr_t peer; 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/ /** return 0 on succes, -1 on failure/
* called on a new tcp device for an accepted client or * called on a new tcp device for an accepted client or
* on a tcp device conntected to a remote server */ * 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_disconnect_t on_disconnect;
stio_dev_tcp_on_recv_t on_recv; stio_dev_tcp_on_read_t on_read;
stio_dev_tcp_on_sent_t on_sent; stio_dev_tcp_on_write_t on_write;
stio_tmridx_t tmridx_connect; stio_tmridx_t tmridx_connect;
}; };
@ -90,8 +88,8 @@ struct stio_dev_tcp_make_t
{ {
/* TODO: options: REUSEADDR for binding?? */ /* TODO: options: REUSEADDR for binding?? */
stio_sckadr_t addr; /* binding address. */ stio_sckadr_t addr; /* binding address. */
stio_dev_tcp_on_sent_t on_sent; stio_dev_tcp_on_write_t on_write;
stio_dev_tcp_on_recv_t on_recv; stio_dev_tcp_on_read_t on_read;
}; };
typedef struct stio_dev_tcp_bind_t stio_dev_tcp_bind_t; 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_sckadr_t addr;
stio_ntime_t timeout; /* connect timeout */ stio_ntime_t timeout; /* connect timeout */
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_disconnect_t on_disconnect;
}; };
typedef struct stio_dev_tcp_listen_t stio_dev_tcp_listen_t; typedef struct stio_dev_tcp_listen_t stio_dev_tcp_listen_t;
struct stio_dev_tcp_listen_t struct stio_dev_tcp_listen_t
{ {
int backlogs; int backlogs;
stio_dev_tcp_on_connected_t on_connected; /* optional, but new connections are dropped immediately without this */ stio_dev_tcp_on_connect_t on_connect; /* 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_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; 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; stio_syshnd_t sck;
/* TODO: add timeout */ /* TODO: add timeout */
/*stio_dev_tcp_t* parent;*/
stio_sckadr_t peer; stio_sckadr_t peer;
}; };
@ -156,11 +153,11 @@ STIO_EXPORT int stio_dev_tcp_listen (
stio_dev_tcp_listen_t* lstn 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, stio_dev_tcp_t* tcp,
const void* data, const void* data,
stio_len_t len, stio_len_t len,
void* sendctx void* wrctx
); );
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -25,8 +25,8 @@
*/ */
#include "stio-prv.h"
#include "stio-udp.h" #include "stio-udp.h"
#include "stio-prv.h"
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -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; 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; if (udp->sck == STIO_SCKHND_INVALID) goto oops;
/* some socket options? */ /* some socket options? */
@ -53,14 +53,14 @@ static int udp_make (stio_dev_t* dev, void* ctx)
goto oops; goto oops;
} }
udp->on_sent = arg->on_sent; udp->on_write = arg->on_write;
udp->on_recv = arg->on_recv; udp->on_read = arg->on_read;
return 0; return 0;
oops: oops:
if (udp->sck != STIO_SCKHND_INVALID) if (udp->sck != STIO_SCKHND_INVALID)
{ {
stio_closeasyncsck (udp->sck); stio_closeasyncsck (udp->stio, udp->sck);
udp->sck = STIO_SCKHND_INVALID; udp->sck = STIO_SCKHND_INVALID;
} }
return -1; return -1;
@ -71,7 +71,7 @@ static void udp_kill (stio_dev_t* dev)
stio_dev_udp_t* udp = (stio_dev_udp_t*)dev; stio_dev_udp_t* udp = (stio_dev_udp_t*)dev;
if (udp->sck != STIO_SCKHND_INVALID) if (udp->sck != STIO_SCKHND_INVALID)
{ {
stio_closeasyncsck (udp->sck); stio_closeasyncsck (udp->stio, udp->sck);
udp->sck = STIO_SCKHND_INVALID; 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; 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_dev_udp_t* udp = (stio_dev_udp_t*)dev;
stio_scklen_t addrlen; stio_scklen_t addrlen;
int x; 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"); printf ("UDP RECVFROM...\n");
addrlen = STIO_SIZEOF(udp->peer); addrlen = STIO_SIZEOF(udp->peer);
x = recvfrom (udp->sck, buf, *len, 0, (struct sockaddr*)&udp->peer, &addrlen); x = recvfrom (udp->sck, buf, *len, 0, (struct sockaddr*)&udp->peer, &addrlen);
@ -104,13 +104,13 @@ printf ("UDP RECVFROM...\n");
return 1; 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; stio_dev_udp_t* udp = (stio_dev_udp_t*)udp;
ssize_t x; ssize_t x;
#if 0 #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)); x = sendto (udp->sck, data, *len, skad, stio_getskadlen(skad));
if (x <= -1) 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 = static stio_dev_mth_t udp_mth =
{ {
udp_make, udp_make,
udp_kill, udp_kill,
udp_getsyshnd, udp_getsyshnd,
udp_read,
udp_write,
udp_ioctl, /* ioctl */ udp_ioctl, /* ioctl */
udp_recv,
udp_send
}; };
static int udp_ready (stio_dev_t* dev, int events) 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; 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); printf ("dATA received %d bytes\n", (int)len);
return 0; 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; return 0;
@ -178,8 +176,8 @@ static int udp_on_sent (stio_dev_t* dev, void* msgid)
static stio_dev_evcb_t udp_evcb = static stio_dev_evcb_t udp_evcb =
{ {
udp_ready, udp_ready,
udp_on_recv, udp_on_read,
udp_on_sent udp_on_write
}; };

View File

@ -29,19 +29,20 @@
#define _STIO_UDP_H_ #define _STIO_UDP_H_
#include <stio.h> #include <stio.h>
#include <stio-sck.h>
typedef struct stio_dev_udp_t stio_dev_udp_t; 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_read_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_write_t) (stio_dev_udp_t* dev, void* wrctx);
typedef struct stio_dev_udp_make_t stio_dev_udp_make_t; typedef struct stio_dev_udp_make_t stio_dev_udp_make_t;
struct stio_dev_udp_make_t struct stio_dev_udp_make_t
{ {
/* TODO: options: REUSEADDR for binding?? */ /* TODO: options: REUSEADDR for binding?? */
stio_sckadr_t addr; /* binding address. */ stio_sckadr_t addr; /* binding address. */
stio_dev_udp_on_sent_t on_sent; stio_dev_udp_on_write_t on_write;
stio_dev_udp_on_recv_t on_recv; stio_dev_udp_on_read_t on_read;
}; };
struct stio_dev_udp_t struct stio_dev_udp_t
@ -50,8 +51,8 @@ struct stio_dev_udp_t
stio_sckhnd_t sck; stio_sckhnd_t sck;
stio_sckadr_t peer; stio_sckadr_t peer;
stio_dev_udp_on_sent_t on_sent; stio_dev_udp_on_write_t on_write;
stio_dev_udp_on_recv_t on_recv; stio_dev_udp_on_read_t on_read;
}; };
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -348,7 +348,7 @@ int stio_exec (stio_t* stio)
while (1) while (1)
{ {
len = STIO_COUNTOF(stio->bigbuf); 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) if (x <= -1)
{ {
@ -390,11 +390,11 @@ int stio_exec (stio_t* stio)
} }
else 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 */ * when x == 0 or <= -1. you can */
/* data available */ /* 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); stio_ruindev (stio, dev);
dev = STIO_NULL; dev = STIO_NULL;
@ -421,7 +421,7 @@ int stio_exec (stio_t* stio)
send_leftover: send_leftover:
ulen = urem; ulen = urem;
x = dev->dev_mth->send (dev, uptr, &ulen); x = dev->dev_mth->write (dev, uptr, &ulen);
if (x <= -1) if (x <= -1)
{ {
/* TODO: error handling? call callback? or what? */ /* TODO: error handling? call callback? or what? */
@ -446,7 +446,7 @@ int stio_exec (stio_t* stio)
int y; int y;
STIO_WQ_UNLINK (q); /* STIO_WQ_DEQ(&dev->wq); */ 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); STIO_MMGR_FREE (dev->stio->mmgr, q);
if (y <= -1) 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; 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; const stio_uint8_t* uptr;
stio_len_t urem, ulen; 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) while (urem > 0)
{ {
ulen = urem; ulen = urem;
x = dev->dev_mth->send (dev, data, &ulen); x = dev->dev_mth->write (dev, data, &ulen);
if (x <= -1) return -1; if (x <= -1) return -1;
else if (x == 0) goto enqueue_data; /* enqueue remaining data */ else if (x == 0) goto enqueue_data; /* enqueue remaining data */
else 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; return 0;
enqueue_data: enqueue_data:
@ -633,7 +633,7 @@ enqueue_data:
return -1; return -1;
} }
q->ctx = sendctx; q->ctx = wrctx;
q->ptr = (stio_uint8_t*)(q + 1); q->ptr = (stio_uint8_t*)(q + 1);
q->len = urem; q->len = urem;
STIO_MEMCPY (q->ptr, uptr, urem); STIO_MEMCPY (q->ptr, uptr, urem);
@ -652,6 +652,25 @@ enqueue_data:
return 0; 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) stio_errnum_t stio_syserrtoerrnum (int no)
{ {
switch (no) switch (no)

View File

@ -40,51 +40,14 @@ struct stio_ntime_t
stio_int32_t nsec; /* nanoseconds */ 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) #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_syshnd_t;
typedef stio_uintptr_t qse_sckhnd_t; #define STIO_SYSHND_INVALID (~(stio_uintptr_t)0)
# define STIO_SCKHND_INVALID (~(qse_sck_hnd_t)0)
#else #else
typedef int stio_syshnd_t; typedef int stio_syshnd_t;
typedef int stio_sckhnd_t; #define STIO_SYSHND_INVALID (-1)
# define STIO_SCKHND_INVALID (-1)
#endif #endif
typedef int stio_sckfam_t;
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
typedef struct stio_t stio_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() */ 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. /* 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. * when returning 1, *len must be sent to the length of data read.
* if *len is set to 0, it's treated as EOF. * if *len is set to 0, it's treated as EOF.
* it must not kill the device */ * 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 struct stio_dev_evcb_t
@ -154,11 +119,11 @@ struct stio_dev_evcb_t
/* return -1 on failure, 0 on success /* return -1 on failure, 0 on success
* it must not kill the device */ * 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. /* return -1 on failure, 0 on success.
* it must not kill the device */ * 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 struct stio_wq_t
@ -340,11 +305,11 @@ STIO_EXPORT int stio_dev_watch (
int events int events
); );
STIO_EXPORT int stio_dev_send ( STIO_EXPORT int stio_dev_write (
stio_dev_t* dev, stio_dev_t* dev,
const void* data, const void* data,
stio_len_t len, stio_len_t len,
void* sendctx void* wrctx
); );
#ifdef __cplusplus #ifdef __cplusplus