renamed recv and send to read and write respectively
added some code for process pipes
This commit is contained in:
		@ -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 \
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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");
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										259
									
								
								stio/lib/stio-pro.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										259
									
								
								stio/lib/stio-pro.c
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										111
									
								
								stio/lib/stio-pro.h
									
									
									
									
									
										Normal 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
 | 
			
		||||
@ -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
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,9 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "stio-sck.h"
 | 
			
		||||
#include "stio-prv.h"
 | 
			
		||||
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
@ -34,7 +36,7 @@
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------ */
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										109
									
								
								stio/lib/stio-sck.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								stio/lib/stio-sck.h
									
									
									
									
									
										Normal 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
 | 
			
		||||
@ -25,8 +25,8 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "stio-prv.h"
 | 
			
		||||
#include "stio-tcp.h"
 | 
			
		||||
#include "stio-prv.h"
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -28,6 +28,7 @@
 | 
			
		||||
#define _STIO_TCP_H_
 | 
			
		||||
 | 
			
		||||
#include <stio.h>
 | 
			
		||||
#include <stio-sck.h>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
@ -25,8 +25,8 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "stio-prv.h"
 | 
			
		||||
#include "stio-udp.h"
 | 
			
		||||
#include "stio-prv.h"
 | 
			
		||||
 | 
			
		||||
#include <sys/socket.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;
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -29,19 +29,20 @@
 | 
			
		||||
#define _STIO_UDP_H_
 | 
			
		||||
 | 
			
		||||
#include <stio.h>
 | 
			
		||||
#include <stio-sck.h>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user