implemented a primitive wrapper device for a system handle
This commit is contained in:
parent
5cfc34daaa
commit
10123109b0
@ -52,6 +52,7 @@ include_HEADERS = \
|
|||||||
hio-pty.h \
|
hio-pty.h \
|
||||||
hio-rad.h \
|
hio-rad.h \
|
||||||
hio-sck.h \
|
hio-sck.h \
|
||||||
|
hio-shw.h \
|
||||||
hio-skad.h \
|
hio-skad.h \
|
||||||
hio-thr.h \
|
hio-thr.h \
|
||||||
hio-upac.h \
|
hio-upac.h \
|
||||||
@ -92,6 +93,7 @@ libhio_la_SOURCES = \
|
|||||||
pty.c \
|
pty.c \
|
||||||
rad-msg.c \
|
rad-msg.c \
|
||||||
sck.c \
|
sck.c \
|
||||||
|
shw.c \
|
||||||
skad.c \
|
skad.c \
|
||||||
sys.c \
|
sys.c \
|
||||||
sys-ass.c \
|
sys-ass.c \
|
||||||
|
@ -151,7 +151,7 @@ am__libhio_la_SOURCES_DIST = chr.c dhcp-svr.c dns.c dns-cli.c ecs.c \
|
|||||||
ecs-imp.h err.c fmt.c fmt-imp.h htb.c htrd.c htre.c http.c \
|
ecs-imp.h err.c fmt.c fmt-imp.h htb.c htrd.c htre.c http.c \
|
||||||
http-cgi.c http-fil.c http-prv.h http-svr.c http-thr.c \
|
http-cgi.c http-fil.c http-prv.h http-svr.c http-thr.c \
|
||||||
http-txt.c json.c hio-prv.h hio.c md5.c nwif.c opt.c opt-imp.h \
|
http-txt.c json.c hio-prv.h hio.c md5.c nwif.c opt.c opt-imp.h \
|
||||||
path.c pipe.c pro.c pty.c rad-msg.c sck.c skad.c sys.c \
|
path.c pipe.c pro.c pty.c rad-msg.c sck.c shw.c skad.c sys.c \
|
||||||
sys-ass.c sys-err.c sys-log.c sys-mux.c sys-prv.h sys-tim.c \
|
sys-ass.c sys-err.c sys-log.c sys-mux.c sys-prv.h sys-tim.c \
|
||||||
thr.c uch-case.h uch-prop.h tmr.c utf8.c utl.c utl-siph.c \
|
thr.c uch-case.h uch-prop.h tmr.c utf8.c utl.c utl-siph.c \
|
||||||
utl-str.c mar.c mar-cli.c
|
utl-str.c mar.c mar-cli.c
|
||||||
@ -167,11 +167,11 @@ am_libhio_la_OBJECTS = libhio_la-chr.lo libhio_la-dhcp-svr.lo \
|
|||||||
libhio_la-md5.lo libhio_la-nwif.lo libhio_la-opt.lo \
|
libhio_la-md5.lo libhio_la-nwif.lo libhio_la-opt.lo \
|
||||||
libhio_la-path.lo libhio_la-pipe.lo libhio_la-pro.lo \
|
libhio_la-path.lo libhio_la-pipe.lo libhio_la-pro.lo \
|
||||||
libhio_la-pty.lo libhio_la-rad-msg.lo libhio_la-sck.lo \
|
libhio_la-pty.lo libhio_la-rad-msg.lo libhio_la-sck.lo \
|
||||||
libhio_la-skad.lo libhio_la-sys.lo libhio_la-sys-ass.lo \
|
libhio_la-shw.lo libhio_la-skad.lo libhio_la-sys.lo \
|
||||||
libhio_la-sys-err.lo libhio_la-sys-log.lo libhio_la-sys-mux.lo \
|
libhio_la-sys-ass.lo libhio_la-sys-err.lo libhio_la-sys-log.lo \
|
||||||
libhio_la-sys-tim.lo libhio_la-thr.lo libhio_la-tmr.lo \
|
libhio_la-sys-mux.lo libhio_la-sys-tim.lo libhio_la-thr.lo \
|
||||||
libhio_la-utf8.lo libhio_la-utl.lo libhio_la-utl-siph.lo \
|
libhio_la-tmr.lo libhio_la-utf8.lo libhio_la-utl.lo \
|
||||||
libhio_la-utl-str.lo $(am__objects_1)
|
libhio_la-utl-siph.lo libhio_la-utl-str.lo $(am__objects_1)
|
||||||
libhio_la_OBJECTS = $(am_libhio_la_OBJECTS)
|
libhio_la_OBJECTS = $(am_libhio_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@)
|
||||||
@ -214,7 +214,8 @@ am__depfiles_remade = ./$(DEPDIR)/libhio_la-chr.Plo \
|
|||||||
./$(DEPDIR)/libhio_la-path.Plo ./$(DEPDIR)/libhio_la-pipe.Plo \
|
./$(DEPDIR)/libhio_la-path.Plo ./$(DEPDIR)/libhio_la-pipe.Plo \
|
||||||
./$(DEPDIR)/libhio_la-pro.Plo ./$(DEPDIR)/libhio_la-pty.Plo \
|
./$(DEPDIR)/libhio_la-pro.Plo ./$(DEPDIR)/libhio_la-pty.Plo \
|
||||||
./$(DEPDIR)/libhio_la-rad-msg.Plo \
|
./$(DEPDIR)/libhio_la-rad-msg.Plo \
|
||||||
./$(DEPDIR)/libhio_la-sck.Plo ./$(DEPDIR)/libhio_la-skad.Plo \
|
./$(DEPDIR)/libhio_la-sck.Plo ./$(DEPDIR)/libhio_la-shw.Plo \
|
||||||
|
./$(DEPDIR)/libhio_la-skad.Plo \
|
||||||
./$(DEPDIR)/libhio_la-sys-ass.Plo \
|
./$(DEPDIR)/libhio_la-sys-ass.Plo \
|
||||||
./$(DEPDIR)/libhio_la-sys-err.Plo \
|
./$(DEPDIR)/libhio_la-sys-err.Plo \
|
||||||
./$(DEPDIR)/libhio_la-sys-log.Plo \
|
./$(DEPDIR)/libhio_la-sys-log.Plo \
|
||||||
@ -255,7 +256,8 @@ am__include_HEADERS_DIST = hio-chr.h hio-cmn.h hio-dhcp.h hio-dns.h \
|
|||||||
hio-ecs.h hio-fmt.h hio-htb.h hio-htrd.h hio-htre.h hio-http.h \
|
hio-ecs.h hio-fmt.h hio-htb.h hio-htrd.h hio-htre.h hio-http.h \
|
||||||
hio-json.h hio-md5.h hio-nwif.h hio-opt.h hio-pac1.h \
|
hio-json.h hio-md5.h hio-nwif.h hio-opt.h hio-pac1.h \
|
||||||
hio-path.h hio-pipe.h hio-pro.h hio-pty.h hio-rad.h hio-sck.h \
|
hio-path.h hio-pipe.h hio-pro.h hio-pty.h hio-rad.h hio-sck.h \
|
||||||
hio-skad.h hio-thr.h hio-upac.h hio-utl.h hio.h hio-mar.h
|
hio-shw.h hio-skad.h hio-thr.h hio-upac.h hio-utl.h hio.h \
|
||||||
|
hio-mar.h
|
||||||
HEADERS = $(include_HEADERS)
|
HEADERS = $(include_HEADERS)
|
||||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
|
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
|
||||||
hio-cfg.h.in
|
hio-cfg.h.in
|
||||||
@ -453,16 +455,16 @@ include_HEADERS = hio-chr.h hio-cmn.h hio-dhcp.h hio-dns.h hio-ecs.h \
|
|||||||
hio-fmt.h hio-htb.h hio-htrd.h hio-htre.h hio-http.h \
|
hio-fmt.h hio-htb.h hio-htrd.h hio-htre.h hio-http.h \
|
||||||
hio-json.h hio-md5.h hio-nwif.h hio-opt.h hio-pac1.h \
|
hio-json.h hio-md5.h hio-nwif.h hio-opt.h hio-pac1.h \
|
||||||
hio-path.h hio-pipe.h hio-pro.h hio-pty.h hio-rad.h hio-sck.h \
|
hio-path.h hio-pipe.h hio-pro.h hio-pty.h hio-rad.h hio-sck.h \
|
||||||
hio-skad.h hio-thr.h hio-upac.h hio-utl.h hio.h \
|
hio-shw.h hio-skad.h hio-thr.h hio-upac.h hio-utl.h hio.h \
|
||||||
$(am__append_1)
|
$(am__append_1)
|
||||||
lib_LTLIBRARIES = libhio.la
|
lib_LTLIBRARIES = libhio.la
|
||||||
libhio_la_SOURCES = chr.c dhcp-svr.c dns.c dns-cli.c ecs.c ecs-imp.h \
|
libhio_la_SOURCES = chr.c dhcp-svr.c dns.c dns-cli.c ecs.c ecs-imp.h \
|
||||||
err.c fmt.c fmt-imp.h htb.c htrd.c htre.c http.c http-cgi.c \
|
err.c fmt.c fmt-imp.h htb.c htrd.c htre.c http.c http-cgi.c \
|
||||||
http-fil.c http-prv.h http-svr.c http-thr.c http-txt.c json.c \
|
http-fil.c http-prv.h http-svr.c http-thr.c http-txt.c json.c \
|
||||||
hio-prv.h hio.c md5.c nwif.c opt.c opt-imp.h path.c pipe.c \
|
hio-prv.h hio.c md5.c nwif.c opt.c opt-imp.h path.c pipe.c \
|
||||||
pro.c pty.c rad-msg.c sck.c skad.c sys.c sys-ass.c sys-err.c \
|
pro.c pty.c rad-msg.c sck.c shw.c skad.c sys.c sys-ass.c \
|
||||||
sys-log.c sys-mux.c sys-prv.h sys-tim.c thr.c uch-case.h \
|
sys-err.c sys-log.c sys-mux.c sys-prv.h sys-tim.c thr.c \
|
||||||
uch-prop.h tmr.c utf8.c utl.c utl-siph.c utl-str.c \
|
uch-case.h uch-prop.h tmr.c utf8.c utl.c utl-siph.c utl-str.c \
|
||||||
$(am__append_2)
|
$(am__append_2)
|
||||||
libhio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
|
libhio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
|
||||||
libhio_la_CFLAGS = $(CFLAGS_LIB_COMMON) $(am__append_3)
|
libhio_la_CFLAGS = $(CFLAGS_LIB_COMMON) $(am__append_3)
|
||||||
@ -592,6 +594,7 @@ distclean-compile:
|
|||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-pty.Plo@am__quote@ # am--include-marker
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-pty.Plo@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-rad-msg.Plo@am__quote@ # am--include-marker
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-rad-msg.Plo@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-sck.Plo@am__quote@ # am--include-marker
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-sck.Plo@am__quote@ # am--include-marker
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-shw.Plo@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-skad.Plo@am__quote@ # am--include-marker
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-skad.Plo@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-sys-ass.Plo@am__quote@ # am--include-marker
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-sys-ass.Plo@am__quote@ # am--include-marker
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-sys-err.Plo@am__quote@ # am--include-marker
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-sys-err.Plo@am__quote@ # am--include-marker
|
||||||
@ -825,6 +828,13 @@ libhio_la-sck.lo: sck.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) $(libhio_la_CPPFLAGS) $(CPPFLAGS) $(libhio_la_CFLAGS) $(CFLAGS) -c -o libhio_la-sck.lo `test -f 'sck.c' || echo '$(srcdir)/'`sck.c
|
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhio_la_CPPFLAGS) $(CPPFLAGS) $(libhio_la_CFLAGS) $(CFLAGS) -c -o libhio_la-sck.lo `test -f 'sck.c' || echo '$(srcdir)/'`sck.c
|
||||||
|
|
||||||
|
libhio_la-shw.lo: shw.c
|
||||||
|
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhio_la_CPPFLAGS) $(CPPFLAGS) $(libhio_la_CFLAGS) $(CFLAGS) -MT libhio_la-shw.lo -MD -MP -MF $(DEPDIR)/libhio_la-shw.Tpo -c -o libhio_la-shw.lo `test -f 'shw.c' || echo '$(srcdir)/'`shw.c
|
||||||
|
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhio_la-shw.Tpo $(DEPDIR)/libhio_la-shw.Plo
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='shw.c' object='libhio_la-shw.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) $(libhio_la_CPPFLAGS) $(CPPFLAGS) $(libhio_la_CFLAGS) $(CFLAGS) -c -o libhio_la-shw.lo `test -f 'shw.c' || echo '$(srcdir)/'`shw.c
|
||||||
|
|
||||||
libhio_la-skad.lo: skad.c
|
libhio_la-skad.lo: skad.c
|
||||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhio_la_CPPFLAGS) $(CPPFLAGS) $(libhio_la_CFLAGS) $(CFLAGS) -MT libhio_la-skad.lo -MD -MP -MF $(DEPDIR)/libhio_la-skad.Tpo -c -o libhio_la-skad.lo `test -f 'skad.c' || echo '$(srcdir)/'`skad.c
|
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhio_la_CPPFLAGS) $(CPPFLAGS) $(libhio_la_CFLAGS) $(CFLAGS) -MT libhio_la-skad.lo -MD -MP -MF $(DEPDIR)/libhio_la-skad.Tpo -c -o libhio_la-skad.lo `test -f 'skad.c' || echo '$(srcdir)/'`skad.c
|
||||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhio_la-skad.Tpo $(DEPDIR)/libhio_la-skad.Plo
|
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhio_la-skad.Tpo $(DEPDIR)/libhio_la-skad.Plo
|
||||||
@ -1114,6 +1124,7 @@ distclean: distclean-am
|
|||||||
-rm -f ./$(DEPDIR)/libhio_la-pty.Plo
|
-rm -f ./$(DEPDIR)/libhio_la-pty.Plo
|
||||||
-rm -f ./$(DEPDIR)/libhio_la-rad-msg.Plo
|
-rm -f ./$(DEPDIR)/libhio_la-rad-msg.Plo
|
||||||
-rm -f ./$(DEPDIR)/libhio_la-sck.Plo
|
-rm -f ./$(DEPDIR)/libhio_la-sck.Plo
|
||||||
|
-rm -f ./$(DEPDIR)/libhio_la-shw.Plo
|
||||||
-rm -f ./$(DEPDIR)/libhio_la-skad.Plo
|
-rm -f ./$(DEPDIR)/libhio_la-skad.Plo
|
||||||
-rm -f ./$(DEPDIR)/libhio_la-sys-ass.Plo
|
-rm -f ./$(DEPDIR)/libhio_la-sys-ass.Plo
|
||||||
-rm -f ./$(DEPDIR)/libhio_la-sys-err.Plo
|
-rm -f ./$(DEPDIR)/libhio_la-sys-err.Plo
|
||||||
@ -1202,6 +1213,7 @@ maintainer-clean: maintainer-clean-am
|
|||||||
-rm -f ./$(DEPDIR)/libhio_la-pty.Plo
|
-rm -f ./$(DEPDIR)/libhio_la-pty.Plo
|
||||||
-rm -f ./$(DEPDIR)/libhio_la-rad-msg.Plo
|
-rm -f ./$(DEPDIR)/libhio_la-rad-msg.Plo
|
||||||
-rm -f ./$(DEPDIR)/libhio_la-sck.Plo
|
-rm -f ./$(DEPDIR)/libhio_la-sck.Plo
|
||||||
|
-rm -f ./$(DEPDIR)/libhio_la-shw.Plo
|
||||||
-rm -f ./$(DEPDIR)/libhio_la-skad.Plo
|
-rm -f ./$(DEPDIR)/libhio_la-skad.Plo
|
||||||
-rm -f ./$(DEPDIR)/libhio_la-sys-ass.Plo
|
-rm -f ./$(DEPDIR)/libhio_la-sys-ass.Plo
|
||||||
-rm -f ./$(DEPDIR)/libhio_la-sys-err.Plo
|
-rm -f ./$(DEPDIR)/libhio_la-sys-err.Plo
|
||||||
|
@ -103,6 +103,7 @@ enum hio_dev_pro_make_flag_t
|
|||||||
HIO_DEV_PRO_DROPOUT = (1 << 9),
|
HIO_DEV_PRO_DROPOUT = (1 << 9),
|
||||||
HIO_DEV_PRO_DROPERR = (1 << 10),
|
HIO_DEV_PRO_DROPERR = (1 << 10),
|
||||||
|
|
||||||
|
HIO_DEV_PRO_UCMD = (1 << 12), /* cmd is hio_uch_t* */
|
||||||
HIO_DEV_PRO_SHELL = (1 << 13),
|
HIO_DEV_PRO_SHELL = (1 << 13),
|
||||||
|
|
||||||
/* perform no waitpid() on a child process upon device destruction.
|
/* perform no waitpid() on a child process upon device destruction.
|
||||||
@ -120,7 +121,7 @@ typedef struct hio_dev_pro_make_t hio_dev_pro_make_t;
|
|||||||
struct hio_dev_pro_make_t
|
struct hio_dev_pro_make_t
|
||||||
{
|
{
|
||||||
int flags; /**< bitwise-ORed of hio_dev_pro_make_flag_t enumerators */
|
int flags; /**< bitwise-ORed of hio_dev_pro_make_flag_t enumerators */
|
||||||
const void* cmd;
|
const void* cmd; /* the actual type is determined by HIO_DEV_PRO_UCMD */
|
||||||
hio_dev_pro_on_write_t on_write; /* mandatory */
|
hio_dev_pro_on_write_t on_write; /* mandatory */
|
||||||
hio_dev_pro_on_read_t on_read; /* mandatory */
|
hio_dev_pro_on_read_t on_read; /* mandatory */
|
||||||
hio_dev_pro_on_close_t on_close; /* optional */
|
hio_dev_pro_on_close_t on_close; /* optional */
|
||||||
|
@ -54,7 +54,7 @@ struct hio_dev_pty_t
|
|||||||
{
|
{
|
||||||
HIO_DEV_HEADER;
|
HIO_DEV_HEADER;
|
||||||
|
|
||||||
hio_syshnd_t pfd;
|
hio_syshnd_t hnd;
|
||||||
hio_intptr_t child_pid;
|
hio_intptr_t child_pid;
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
@ -65,6 +65,7 @@ struct hio_dev_pty_t
|
|||||||
|
|
||||||
enum hio_dev_pty_make_flag_t
|
enum hio_dev_pty_make_flag_t
|
||||||
{
|
{
|
||||||
|
HIO_DEV_PTY_UCMD = (1 << 12), /* cmd is hio_uch_t* */
|
||||||
HIO_DEV_PTY_SHELL = (1 << 13),
|
HIO_DEV_PTY_SHELL = (1 << 13),
|
||||||
/* perform no waitpid() on a child process upon device destruction.
|
/* perform no waitpid() on a child process upon device destruction.
|
||||||
* you should set this flag if your application has automatic child
|
* you should set this flag if your application has automatic child
|
||||||
@ -79,7 +80,7 @@ typedef struct hio_dev_pty_make_t hio_dev_pty_make_t;
|
|||||||
struct hio_dev_pty_make_t
|
struct hio_dev_pty_make_t
|
||||||
{
|
{
|
||||||
int flags; /**< bitwise-ORed of hio_dev_pty_make_flag_t enumerators */
|
int flags; /**< bitwise-ORed of hio_dev_pty_make_flag_t enumerators */
|
||||||
const void* cmd;
|
const void* cmd; /* the actual type is determined by HIO_DEV_PTY_UCMD */
|
||||||
|
|
||||||
hio_dev_pty_on_write_t on_write; /* mandatory */
|
hio_dev_pty_on_write_t on_write; /* mandatory */
|
||||||
hio_dev_pty_on_read_t on_read; /* mandatory */
|
hio_dev_pty_on_read_t on_read; /* mandatory */
|
||||||
@ -107,14 +108,16 @@ HIO_EXPORT hio_dev_pty_t* hio_dev_pty_make (
|
|||||||
|
|
||||||
#if defined(HIO_HAVE_INLINE)
|
#if defined(HIO_HAVE_INLINE)
|
||||||
static HIO_INLINE hio_t* hio_dev_pty_gethio (hio_dev_pty_t* pty) { return hio_dev_gethio((hio_dev_t*)pty); }
|
static HIO_INLINE hio_t* hio_dev_pty_gethio (hio_dev_pty_t* pty) { return hio_dev_gethio((hio_dev_t*)pty); }
|
||||||
|
static HIO_INLINE void* hio_dev_pty_getxtn (hio_dev_pty_t* pty) { return (void*)(pty + 1); }
|
||||||
|
static HIO_INLINE hio_syshnd_t hio_dev_pty_getsyshnd (hio_dev_pty_t* pty) { return pty->hnd; }
|
||||||
#else
|
#else
|
||||||
# define hio_dev_pty_gethio(pty) hio_dev_gethio(pty)
|
# define hio_dev_pty_gethio(pty) hio_dev_gethio(pty)
|
||||||
|
# define hio_dev_pty_getxtn(pty) ((void*)(((hio_dev_pty_t*)pty) + 1))
|
||||||
|
# define hio_dev_pty_getsyshnd(pty) (((hio_dev_pty_t*)pty)->hnd)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HIO_HAVE_INLINE)
|
#if defined(HIO_HAVE_INLINE)
|
||||||
static HIO_INLINE void* hio_dev_pty_getxtn (hio_dev_pty_t* pty) { return (void*)(pty + 1); }
|
|
||||||
#else
|
#else
|
||||||
# define hio_dev_pty_getxtn(pty) ((void*)(((hio_dev_pty_t*)pty) + 1))
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HIO_EXPORT void hio_dev_pty_kill (
|
HIO_EXPORT void hio_dev_pty_kill (
|
||||||
|
150
hio/lib/hio-shw.h
Normal file
150
hio/lib/hio-shw.h
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2016-2020 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 repipeduce 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 PIPEVIDED 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, PIPECUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PIPEFITS; 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 _HIO_SHW_H_
|
||||||
|
#define _HIO_SHW_H_
|
||||||
|
|
||||||
|
/* system handle wrapper -
|
||||||
|
* turn a raw system handle/file descript to a device object
|
||||||
|
*/
|
||||||
|
#include <hio.h>
|
||||||
|
|
||||||
|
typedef struct hio_dev_shw_t hio_dev_shw_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef int (*hio_dev_shw_on_ready_t) (
|
||||||
|
hio_dev_shw_t* dev,
|
||||||
|
int events
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
typedef int (*hio_dev_shw_on_read_t) (
|
||||||
|
hio_dev_shw_t* dev,
|
||||||
|
const void* data,
|
||||||
|
hio_iolen_t len
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef int (*hio_dev_shw_on_write_t) (
|
||||||
|
hio_dev_shw_t* dev,
|
||||||
|
hio_iolen_t wrlen,
|
||||||
|
void* wrctx
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef void (*hio_dev_shw_on_close_t) (
|
||||||
|
hio_dev_shw_t* dev
|
||||||
|
);
|
||||||
|
|
||||||
|
struct hio_dev_shw_t
|
||||||
|
{
|
||||||
|
HIO_DEV_HEADER;
|
||||||
|
|
||||||
|
hio_syshnd_t hnd;
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
hio_dev_shw_on_ready_t on_ready;
|
||||||
|
hio_dev_shw_on_read_t on_read;
|
||||||
|
hio_dev_shw_on_write_t on_write;
|
||||||
|
hio_dev_shw_on_close_t on_close;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum hio_dev_shw_make_flag_t
|
||||||
|
{
|
||||||
|
HIO_DEV_SHW_KEEP_OPEN_ON_CLOSE = (1 << 0),
|
||||||
|
HIO_DEV_SHW_DISABLE_OUT = (1 << 1),
|
||||||
|
HIO_DEV_SHW_DISABLE_IN = (1 << 2),
|
||||||
|
HIO_DEV_SHW_DISABLE_STREAM = (1 << 3)
|
||||||
|
};
|
||||||
|
typedef enum hio_dev_shw_make_flag_t hio_dev_shw_make_flag_t;
|
||||||
|
|
||||||
|
typedef struct hio_dev_shw_make_t hio_dev_shw_make_t;
|
||||||
|
struct hio_dev_shw_make_t
|
||||||
|
{
|
||||||
|
hio_syshnd_t hnd;
|
||||||
|
int flags; /**< bitwise-ORed of hio_dev_shw_make_flag_t enumerators */
|
||||||
|
|
||||||
|
hio_dev_shw_on_write_t on_write; /* mandatory */
|
||||||
|
hio_dev_shw_on_read_t on_read; /* mandatory */
|
||||||
|
hio_dev_shw_on_close_t on_close; /* optional */
|
||||||
|
hio_dev_shw_on_ready_t on_ready; /* optional */
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HIO_EXPORT hio_dev_shw_t* hio_dev_shw_make (
|
||||||
|
hio_t* hio,
|
||||||
|
hio_oow_t xtnsize,
|
||||||
|
const hio_dev_shw_make_t* data
|
||||||
|
);
|
||||||
|
|
||||||
|
#if defined(HIO_HAVE_INLINE)
|
||||||
|
static HIO_INLINE hio_t* hio_dev_shw_gethio (hio_dev_shw_t* shw) { return hio_dev_gethio((hio_dev_t*)shw); }
|
||||||
|
static HIO_INLINE void* hio_dev_shw_getxtn (hio_dev_shw_t* shw) { return (void*)(shw + 1); }
|
||||||
|
static HIO_INLINE hio_syshnd_t hio_dev_shw_getsyshnd (hio_dev_shw_t* shw) { return shw->hnd; }
|
||||||
|
#else
|
||||||
|
# define hio_dev_shw_gethio(shw) hio_dev_gethio(shw)
|
||||||
|
# define hio_dev_shw_getxtn(shw) ((void*)(((hio_dev_shw_t*)shw) + 1))
|
||||||
|
# define hio_dev_shw_getsyshnd(shw) (((hio_dev_shw_t*)shw)->hnd)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HIO_EXPORT void hio_dev_shw_kill (
|
||||||
|
hio_dev_shw_t* shw
|
||||||
|
);
|
||||||
|
|
||||||
|
HIO_EXPORT void hio_dev_shw_halt (
|
||||||
|
hio_dev_shw_t* shw
|
||||||
|
);
|
||||||
|
|
||||||
|
HIO_EXPORT int hio_dev_shw_read (
|
||||||
|
hio_dev_shw_t* shw,
|
||||||
|
int enabled
|
||||||
|
);
|
||||||
|
|
||||||
|
HIO_EXPORT int hio_dev_shw_timedread (
|
||||||
|
hio_dev_shw_t* shw,
|
||||||
|
int enabled,
|
||||||
|
const hio_ntime_t* tmout
|
||||||
|
);
|
||||||
|
|
||||||
|
HIO_EXPORT int hio_dev_shw_write (
|
||||||
|
hio_dev_shw_t* shw,
|
||||||
|
const void* data,
|
||||||
|
hio_iolen_t len,
|
||||||
|
void* wrctx
|
||||||
|
);
|
||||||
|
|
||||||
|
HIO_EXPORT int hio_dev_shw_timedwrite (
|
||||||
|
hio_dev_shw_t* shw,
|
||||||
|
const void* data,
|
||||||
|
hio_iolen_t len,
|
||||||
|
const hio_ntime_t* tmout,
|
||||||
|
void* wrctx
|
||||||
|
);
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -64,7 +64,7 @@ static void free_param (hio_t* hio, param_t* param)
|
|||||||
HIO_MEMSET (param, 0, HIO_SIZEOF(*param));
|
HIO_MEMSET (param, 0, HIO_SIZEOF(*param));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int make_param (hio_t* hio, const hio_bch_t* cmd, int flags, param_t* param)
|
static int make_param (hio_t* hio, const void* cmd, int flags, param_t* param)
|
||||||
{
|
{
|
||||||
int fcnt = 0;
|
int fcnt = 0;
|
||||||
hio_bch_t* mcmd = HIO_NULL;
|
hio_bch_t* mcmd = HIO_NULL;
|
||||||
@ -73,7 +73,15 @@ static int make_param (hio_t* hio, const hio_bch_t* cmd, int flags, param_t* par
|
|||||||
|
|
||||||
if (flags & HIO_DEV_PRO_SHELL)
|
if (flags & HIO_DEV_PRO_SHELL)
|
||||||
{
|
{
|
||||||
mcmd = (hio_bch_t*)cmd;
|
if (flags & HIO_DEV_PRO_UCMD)
|
||||||
|
{
|
||||||
|
mcmd = hio_duputobcstr(hio, cmd, HIO_NULL);
|
||||||
|
if (HIO_UNLIKELY(!mcmd)) goto oops;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mcmd = (hio_bch_t*)cmd;
|
||||||
|
}
|
||||||
|
|
||||||
param->argv = param->fixed_argv;
|
param->argv = param->fixed_argv;
|
||||||
param->argv[0] = "/bin/sh";
|
param->argv[0] = "/bin/sh";
|
||||||
@ -87,7 +95,9 @@ static int make_param (hio_t* hio, const hio_bch_t* cmd, int flags, param_t* par
|
|||||||
hio_bch_t** argv;
|
hio_bch_t** argv;
|
||||||
hio_bch_t* mcmdptr;
|
hio_bch_t* mcmdptr;
|
||||||
|
|
||||||
mcmd = hio_dupbcstr(hio, cmd, HIO_NULL);
|
mcmd = (flags & HIO_DEV_PRO_UCMD)?
|
||||||
|
hio_duputobcstr(hio, cmd, HIO_NULL):
|
||||||
|
hio_dupbcstr(hio, cmd, HIO_NULL);
|
||||||
if (HIO_UNLIKELY(!mcmd)) goto oops;
|
if (HIO_UNLIKELY(!mcmd)) goto oops;
|
||||||
|
|
||||||
fcnt = hio_split_bcstr(mcmd, "", '\"', '\"', '\\');
|
fcnt = hio_split_bcstr(mcmd, "", '\"', '\"', '\\');
|
||||||
|
@ -45,6 +45,8 @@ struct param_t
|
|||||||
hio_bch_t* mcmd;
|
hio_bch_t* mcmd;
|
||||||
hio_bch_t* fixed_argv[4];
|
hio_bch_t* fixed_argv[4];
|
||||||
hio_bch_t** argv;
|
hio_bch_t** argv;
|
||||||
|
|
||||||
|
hio_bch_t* fixed_env[2];
|
||||||
};
|
};
|
||||||
typedef struct param_t param_t;
|
typedef struct param_t param_t;
|
||||||
|
|
||||||
@ -56,16 +58,28 @@ static void free_param (hio_t* hio, param_t* param)
|
|||||||
HIO_MEMSET (param, 0, HIO_SIZEOF(*param));
|
HIO_MEMSET (param, 0, HIO_SIZEOF(*param));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int make_param (hio_t* hio, const hio_bch_t* cmd, int flags, param_t* param)
|
static int make_param (hio_t* hio, const void* cmd, int flags, param_t* param)
|
||||||
{
|
{
|
||||||
int fcnt = 0;
|
int fcnt = 0;
|
||||||
hio_bch_t* mcmd = HIO_NULL;
|
hio_bch_t* mcmd = HIO_NULL;
|
||||||
|
|
||||||
HIO_MEMSET (param, 0, HIO_SIZEOF(*param));
|
HIO_MEMSET (param, 0, HIO_SIZEOF(*param));
|
||||||
|
|
||||||
|
/* TODO: make this configurable */
|
||||||
|
param->fixed_env[0] = "TERM=dumb";
|
||||||
|
param->fixed_env[1] = HIO_NULL;
|
||||||
|
|
||||||
if (flags & HIO_DEV_PTY_SHELL)
|
if (flags & HIO_DEV_PTY_SHELL)
|
||||||
{
|
{
|
||||||
mcmd = (hio_bch_t*)cmd;
|
if (flags & HIO_DEV_PTY_UCMD)
|
||||||
|
{
|
||||||
|
mcmd = hio_duputobcstr(hio, cmd, HIO_NULL);
|
||||||
|
if (HIO_UNLIKELY(!mcmd)) goto oops;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mcmd = (hio_bch_t*)cmd;
|
||||||
|
}
|
||||||
|
|
||||||
param->argv = param->fixed_argv;
|
param->argv = param->fixed_argv;
|
||||||
param->argv[0] = "/bin/sh";
|
param->argv[0] = "/bin/sh";
|
||||||
@ -79,7 +93,9 @@ static int make_param (hio_t* hio, const hio_bch_t* cmd, int flags, param_t* par
|
|||||||
hio_bch_t** argv;
|
hio_bch_t** argv;
|
||||||
hio_bch_t* mcmdptr;
|
hio_bch_t* mcmdptr;
|
||||||
|
|
||||||
mcmd = hio_dupbcstr(hio, cmd, HIO_NULL);
|
mcmd = (flags & HIO_DEV_PTY_UCMD)?
|
||||||
|
hio_duputobcstr(hio, cmd, HIO_NULL):
|
||||||
|
hio_dupbcstr(hio, cmd, HIO_NULL);
|
||||||
if (HIO_UNLIKELY(!mcmd)) goto oops;
|
if (HIO_UNLIKELY(!mcmd)) goto oops;
|
||||||
|
|
||||||
fcnt = hio_split_bcstr(mcmd, "", '\"', '\"', '\\');
|
fcnt = hio_split_bcstr(mcmd, "", '\"', '\"', '\\');
|
||||||
@ -149,8 +165,7 @@ static pid_t standard_fork_and_exec (hio_dev_pty_t* dev, int pfds[], hio_dev_pty
|
|||||||
close (pfds[1]);
|
close (pfds[1]);
|
||||||
pfds[1] = HIO_SYSHND_INVALID;
|
pfds[1] = HIO_SYSHND_INVALID;
|
||||||
|
|
||||||
/* TODO: pass environment like TERM */
|
execve (param->argv[0], param->argv, param->fixed_env);
|
||||||
execv (param->argv[0], param->argv);
|
|
||||||
|
|
||||||
/* if exec fails, free 'param' parameter which is an inherited pointer */
|
/* if exec fails, free 'param' parameter which is an inherited pointer */
|
||||||
free_param (hio, param);
|
free_param (hio, param);
|
||||||
@ -252,7 +267,7 @@ static int dev_pty_make (hio_dev_t* dev, void* ctx)
|
|||||||
|
|
||||||
if (hio_makesyshndasync(hio, pfds[0]) <= -1) goto oops;
|
if (hio_makesyshndasync(hio, pfds[0]) <= -1) goto oops;
|
||||||
|
|
||||||
rdev->pfd = pfds[0];
|
rdev->hnd = pfds[0];
|
||||||
rdev->child_pid = pid;
|
rdev->child_pid = pid;
|
||||||
rdev->flags = info->flags;
|
rdev->flags = info->flags;
|
||||||
rdev->dev_cap = HIO_DEV_CAP_OUT | HIO_DEV_CAP_IN | HIO_DEV_CAP_STREAM;
|
rdev->dev_cap = HIO_DEV_CAP_OUT | HIO_DEV_CAP_IN | HIO_DEV_CAP_STREAM;
|
||||||
@ -314,10 +329,10 @@ static int dev_pty_kill (hio_dev_t* dev, int force)
|
|||||||
|
|
||||||
if (rdev->on_close) rdev->on_close (rdev);
|
if (rdev->on_close) rdev->on_close (rdev);
|
||||||
|
|
||||||
if (rdev->pfd != HIO_SYSHND_INVALID)
|
if (rdev->hnd != HIO_SYSHND_INVALID)
|
||||||
{
|
{
|
||||||
close (rdev->pfd);
|
close (rdev->hnd);
|
||||||
rdev->pfd = HIO_SYSHND_INVALID;
|
rdev->hnd = HIO_SYSHND_INVALID;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -327,13 +342,13 @@ static int dev_pty_read (hio_dev_t* dev, void* buf, hio_iolen_t* len, hio_devadd
|
|||||||
hio_dev_pty_t* pty = (hio_dev_pty_t*)dev;
|
hio_dev_pty_t* pty = (hio_dev_pty_t*)dev;
|
||||||
ssize_t x;
|
ssize_t x;
|
||||||
|
|
||||||
if (HIO_UNLIKELY(pty->pfd == HIO_SYSHND_INVALID))
|
if (HIO_UNLIKELY(pty->hnd == HIO_SYSHND_INVALID))
|
||||||
{
|
{
|
||||||
hio_seterrnum (pty->hio, HIO_EBADHND);
|
hio_seterrnum (pty->hio, HIO_EBADHND);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
x = read(pty->pfd, buf, *len);
|
x = read(pty->hnd, buf, *len);
|
||||||
if (x <= -1)
|
if (x <= -1)
|
||||||
{
|
{
|
||||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data available */
|
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data available */
|
||||||
@ -351,7 +366,7 @@ static int dev_pty_write (hio_dev_t* dev, const void* data, hio_iolen_t* len, co
|
|||||||
hio_dev_pty_t* pty = (hio_dev_pty_t*)dev;
|
hio_dev_pty_t* pty = (hio_dev_pty_t*)dev;
|
||||||
ssize_t x;
|
ssize_t x;
|
||||||
|
|
||||||
if (HIO_UNLIKELY(pty->pfd == HIO_SYSHND_INVALID))
|
if (HIO_UNLIKELY(pty->hnd == HIO_SYSHND_INVALID))
|
||||||
{
|
{
|
||||||
hio_seterrnum (pty->hio, HIO_EBADHND);
|
hio_seterrnum (pty->hio, HIO_EBADHND);
|
||||||
return -1;
|
return -1;
|
||||||
@ -361,16 +376,16 @@ static int dev_pty_write (hio_dev_t* dev, const void* data, hio_iolen_t* len, co
|
|||||||
{
|
{
|
||||||
/* this is an EOF indicator */
|
/* this is an EOF indicator */
|
||||||
/*hio_dev_halt (dev);*/ /* halt this slave device to indicate EOF on the lower-level handle */
|
/*hio_dev_halt (dev);*/ /* halt this slave device to indicate EOF on the lower-level handle */
|
||||||
if (HIO_LIKELY(pty->pfd != HIO_SYSHND_INVALID)) /* halt() doesn't close the pty immediately. so close the underlying pty */
|
if (HIO_LIKELY(pty->hnd != HIO_SYSHND_INVALID)) /* halt() doesn't close the pty immediately. so close the underlying pty */
|
||||||
{
|
{
|
||||||
hio_dev_watch (dev, HIO_DEV_WATCH_STOP, 0);
|
hio_dev_watch (dev, HIO_DEV_WATCH_STOP, 0);
|
||||||
close (pty->pfd);
|
close (pty->hnd);
|
||||||
pty->pfd = HIO_SYSHND_INVALID;
|
pty->hnd = HIO_SYSHND_INVALID;
|
||||||
}
|
}
|
||||||
return 1; /* indicate that the operation got successful. the core will execute on_write() with 0. */
|
return 1; /* indicate that the operation got successful. the core will execute on_write() with 0. */
|
||||||
}
|
}
|
||||||
|
|
||||||
x = write(pty->pfd, data, *len);
|
x = write(pty->hnd, data, *len);
|
||||||
if (x <= -1)
|
if (x <= -1)
|
||||||
{
|
{
|
||||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */
|
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */
|
||||||
@ -388,7 +403,7 @@ static int dev_pty_writev (hio_dev_t* dev, const hio_iovec_t* iov, hio_iolen_t*
|
|||||||
hio_dev_pty_t* pty = (hio_dev_pty_t*)dev;
|
hio_dev_pty_t* pty = (hio_dev_pty_t*)dev;
|
||||||
ssize_t x;
|
ssize_t x;
|
||||||
|
|
||||||
if (HIO_UNLIKELY(pty->pfd == HIO_SYSHND_INVALID))
|
if (HIO_UNLIKELY(pty->hnd == HIO_SYSHND_INVALID))
|
||||||
{
|
{
|
||||||
hio_seterrnum (pty->hio, HIO_EBADHND);
|
hio_seterrnum (pty->hio, HIO_EBADHND);
|
||||||
return -1;
|
return -1;
|
||||||
@ -398,16 +413,16 @@ static int dev_pty_writev (hio_dev_t* dev, const hio_iovec_t* iov, hio_iolen_t*
|
|||||||
{
|
{
|
||||||
/* this is an EOF indicator */
|
/* this is an EOF indicator */
|
||||||
/*hio_dev_halt (dev);*/ /* halt this slave device to indicate EOF on the lower-level handle */
|
/*hio_dev_halt (dev);*/ /* halt this slave device to indicate EOF on the lower-level handle */
|
||||||
if (HIO_LIKELY(pty->pfd != HIO_SYSHND_INVALID)) /* halt() doesn't close the pty immediately. so close the underlying pty */
|
if (HIO_LIKELY(pty->hnd != HIO_SYSHND_INVALID)) /* halt() doesn't close the pty immediately. so close the underlying pty */
|
||||||
{
|
{
|
||||||
hio_dev_watch (dev, HIO_DEV_WATCH_STOP, 0);
|
hio_dev_watch (dev, HIO_DEV_WATCH_STOP, 0);
|
||||||
close (pty->pfd);
|
close (pty->hnd);
|
||||||
pty->pfd = HIO_SYSHND_INVALID;
|
pty->hnd = HIO_SYSHND_INVALID;
|
||||||
}
|
}
|
||||||
return 1; /* indicate that the operation got successful. the core will execute on_write() with 0. */
|
return 1; /* indicate that the operation got successful. the core will execute on_write() with 0. */
|
||||||
}
|
}
|
||||||
|
|
||||||
x = writev(pty->pfd, iov, *iovcnt);
|
x = writev(pty->hnd, iov, *iovcnt);
|
||||||
if (x <= -1)
|
if (x <= -1)
|
||||||
{
|
{
|
||||||
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */
|
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */
|
||||||
@ -423,7 +438,7 @@ static int dev_pty_writev (hio_dev_t* dev, const hio_iovec_t* iov, hio_iolen_t*
|
|||||||
static hio_syshnd_t dev_pty_getsyshnd (hio_dev_t* dev)
|
static hio_syshnd_t dev_pty_getsyshnd (hio_dev_t* dev)
|
||||||
{
|
{
|
||||||
hio_dev_pty_t* rdev = (hio_dev_pty_t*)dev;
|
hio_dev_pty_t* rdev = (hio_dev_pty_t*)dev;
|
||||||
return rdev->pfd;
|
return rdev->hnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_pty_ioctl (hio_dev_t* dev, int cmd, void* arg)
|
static int dev_pty_ioctl (hio_dev_t* dev, int cmd, void* arg)
|
||||||
|
287
hio/lib/shw.c
Normal file
287
hio/lib/shw.c
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2016-2020 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 <hio-shw.h>
|
||||||
|
#include "hio-prv.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
|
||||||
|
static int dev_shw_make (hio_dev_t* dev, void* ctx)
|
||||||
|
{
|
||||||
|
hio_t* hio = dev->hio;
|
||||||
|
hio_dev_shw_t* rdev = (hio_dev_shw_t*)dev;
|
||||||
|
hio_dev_shw_make_t* info = (hio_dev_shw_make_t*)ctx;
|
||||||
|
|
||||||
|
rdev->hnd = info->hnd;
|
||||||
|
rdev->flags = info->flags;
|
||||||
|
|
||||||
|
rdev->dev_cap = HIO_DEV_CAP_OUT | HIO_DEV_CAP_IN | HIO_DEV_CAP_STREAM;
|
||||||
|
if (info->flags & HIO_DEV_SHW_DISABLE_OUT) rdev->dev_cap &= ~HIO_DEV_CAP_OUT;
|
||||||
|
if (info->flags & HIO_DEV_SHW_DISABLE_IN) rdev->dev_cap &= ~HIO_DEV_CAP_IN;
|
||||||
|
if (info->flags & HIO_DEV_SHW_DISABLE_STREAM) rdev->dev_cap &= ~HIO_DEV_CAP_STREAM;
|
||||||
|
|
||||||
|
rdev->on_ready = info->on_ready;
|
||||||
|
rdev->on_read = info->on_read;
|
||||||
|
rdev->on_write = info->on_write;
|
||||||
|
rdev->on_close = info->on_close;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
/* don't close the handle regardless of HIO_DEV_SHW_KEEP_OPEN_ON_CLOSE.
|
||||||
|
* the device is not created. so no ownership of the handle is passed to this wrapper device */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dev_shw_kill (hio_dev_t* dev, int force)
|
||||||
|
{
|
||||||
|
hio_t* hio = dev->hio;
|
||||||
|
hio_dev_shw_t* rdev = (hio_dev_shw_t*)dev;
|
||||||
|
|
||||||
|
if (rdev->on_close) rdev->on_close (rdev);
|
||||||
|
|
||||||
|
if (rdev->hnd != HIO_SYSHND_INVALID)
|
||||||
|
{
|
||||||
|
if (!(rdev->flags & HIO_DEV_SHW_KEEP_OPEN_ON_CLOSE))
|
||||||
|
{
|
||||||
|
close (rdev->hnd);
|
||||||
|
rdev->hnd = HIO_SYSHND_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dev_shw_read (hio_dev_t* dev, void* buf, hio_iolen_t* len, hio_devaddr_t* srcaddr)
|
||||||
|
{
|
||||||
|
hio_dev_shw_t* shw = (hio_dev_shw_t*)dev;
|
||||||
|
ssize_t x;
|
||||||
|
|
||||||
|
if (HIO_UNLIKELY(shw->hnd == HIO_SYSHND_INVALID))
|
||||||
|
{
|
||||||
|
hio_seterrnum (shw->hio, HIO_EBADHND);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = read(shw->hnd, buf, *len);
|
||||||
|
if (x <= -1)
|
||||||
|
{
|
||||||
|
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data available */
|
||||||
|
if (errno == EINTR) return 0;
|
||||||
|
hio_seterrwithsyserr (shw->hio, 0, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*len = x;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dev_shw_write (hio_dev_t* dev, const void* data, hio_iolen_t* len, const hio_devaddr_t* dstaddr)
|
||||||
|
{
|
||||||
|
hio_dev_shw_t* shw = (hio_dev_shw_t*)dev;
|
||||||
|
ssize_t x;
|
||||||
|
|
||||||
|
if (HIO_UNLIKELY(shw->hnd == HIO_SYSHND_INVALID))
|
||||||
|
{
|
||||||
|
hio_seterrnum (shw->hio, HIO_EBADHND);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HIO_UNLIKELY(*len <= 0))
|
||||||
|
{
|
||||||
|
/* this is an EOF indicator */
|
||||||
|
/*hio_dev_halt (dev);*/ /* halt this slave device to indicate EOF on the lower-level handle */
|
||||||
|
if (HIO_LIKELY(shw->hnd != HIO_SYSHND_INVALID)) /* halt() doesn't close the handle immediately. so close the underlying handle */
|
||||||
|
{
|
||||||
|
hio_dev_watch (dev, HIO_DEV_WATCH_STOP, 0);
|
||||||
|
if (!(shw->flags & HIO_DEV_SHW_KEEP_OPEN_ON_CLOSE))
|
||||||
|
{
|
||||||
|
close (shw->hnd);
|
||||||
|
shw->hnd = HIO_SYSHND_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1; /* indicate that the operation got successful. the core will execute on_write() with 0. */
|
||||||
|
}
|
||||||
|
|
||||||
|
x = write(shw->hnd, data, *len);
|
||||||
|
if (x <= -1)
|
||||||
|
{
|
||||||
|
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */
|
||||||
|
if (errno == EINTR) return 0;
|
||||||
|
hio_seterrwithsyserr (shw->hio, 0, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*len = x;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dev_shw_writev (hio_dev_t* dev, const hio_iovec_t* iov, hio_iolen_t* iovcnt, const hio_devaddr_t* dstaddr)
|
||||||
|
{
|
||||||
|
hio_dev_shw_t* shw = (hio_dev_shw_t*)dev;
|
||||||
|
ssize_t x;
|
||||||
|
|
||||||
|
if (HIO_UNLIKELY(shw->hnd == HIO_SYSHND_INVALID))
|
||||||
|
{
|
||||||
|
hio_seterrnum (shw->hio, HIO_EBADHND);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HIO_UNLIKELY(*iovcnt <= 0))
|
||||||
|
{
|
||||||
|
/* this is an EOF indicator */
|
||||||
|
/*hio_dev_halt (dev);*/ /* halt this slave device to indicate EOF on the lower-level handle */
|
||||||
|
if (HIO_LIKELY(shw->hnd != HIO_SYSHND_INVALID)) /* halt() doesn't close the handle immediately. so close the underlying handle */
|
||||||
|
{
|
||||||
|
hio_dev_watch (dev, HIO_DEV_WATCH_STOP, 0);
|
||||||
|
if (!(shw->flags & HIO_DEV_SHW_KEEP_OPEN_ON_CLOSE))
|
||||||
|
{
|
||||||
|
close (shw->hnd);
|
||||||
|
shw->hnd = HIO_SYSHND_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1; /* indicate that the operation got successful. the core will execute on_write() with 0. */
|
||||||
|
}
|
||||||
|
|
||||||
|
x = writev(shw->hnd, iov, *iovcnt);
|
||||||
|
if (x <= -1)
|
||||||
|
{
|
||||||
|
if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */
|
||||||
|
if (errno == EINTR) return 0;
|
||||||
|
hio_seterrwithsyserr (shw->hio, 0, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*iovcnt = x;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hio_syshnd_t dev_shw_getsyshnd (hio_dev_t* dev)
|
||||||
|
{
|
||||||
|
hio_dev_shw_t* rdev = (hio_dev_shw_t*)dev;
|
||||||
|
return rdev->hnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hio_dev_mth_t dev_shw_methods =
|
||||||
|
{
|
||||||
|
dev_shw_make,
|
||||||
|
dev_shw_kill,
|
||||||
|
HIO_NULL,
|
||||||
|
dev_shw_getsyshnd,
|
||||||
|
HIO_NULL,
|
||||||
|
HIO_NULL, /* ioctl */
|
||||||
|
|
||||||
|
dev_shw_read,
|
||||||
|
dev_shw_write,
|
||||||
|
dev_shw_writev,
|
||||||
|
HIO_NULL, /* sendfile */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ========================================================================= */
|
||||||
|
|
||||||
|
static int shw_ready (hio_dev_t* dev, int events)
|
||||||
|
{
|
||||||
|
hio_t* hio = dev->hio;
|
||||||
|
hio_dev_shw_t* shw = (hio_dev_shw_t*)dev;
|
||||||
|
|
||||||
|
if (events & HIO_DEV_EVENT_ERR)
|
||||||
|
{
|
||||||
|
hio_seterrnum (hio, HIO_EDEVERR);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (events & HIO_DEV_EVENT_HUP)
|
||||||
|
{
|
||||||
|
if (events & (HIO_DEV_EVENT_PRI | HIO_DEV_EVENT_IN | HIO_DEV_EVENT_OUT))
|
||||||
|
{
|
||||||
|
/* probably half-open? */
|
||||||
|
return shw->on_ready? shw->on_ready(shw, events): 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
hio_seterrnum (hio, HIO_EDEVHUP);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1 - the device is ok. carry on reading or writing */
|
||||||
|
return shw->on_ready? shw->on_ready(shw, events): 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int shw_on_read (hio_dev_t* dev, const void* data, hio_iolen_t len, const hio_devaddr_t* srcaddr)
|
||||||
|
{
|
||||||
|
hio_dev_shw_t* shw = (hio_dev_shw_t*)dev;
|
||||||
|
return shw->on_read(shw, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int shw_on_write (hio_dev_t* dev, hio_iolen_t wrlen, void* wrctx, const hio_devaddr_t* dstaddr)
|
||||||
|
{
|
||||||
|
hio_dev_shw_t* shw = (hio_dev_shw_t*)dev;
|
||||||
|
return shw->on_write(shw, wrlen, wrctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static hio_dev_evcb_t dev_shw_event_callbacks =
|
||||||
|
{
|
||||||
|
shw_ready,
|
||||||
|
shw_on_read,
|
||||||
|
shw_on_write
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ========================================================================= */
|
||||||
|
|
||||||
|
hio_dev_shw_t* hio_dev_shw_make (hio_t* hio, hio_oow_t xtnsize, const hio_dev_shw_make_t* info)
|
||||||
|
{
|
||||||
|
return (hio_dev_shw_t*)hio_dev_make(
|
||||||
|
hio, HIO_SIZEOF(hio_dev_shw_t) + xtnsize,
|
||||||
|
&dev_shw_methods, &dev_shw_event_callbacks, (void*)info);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hio_dev_shw_kill (hio_dev_shw_t* dev)
|
||||||
|
{
|
||||||
|
hio_dev_kill ((hio_dev_t*)dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hio_dev_shw_halt (hio_dev_shw_t* dev)
|
||||||
|
{
|
||||||
|
hio_dev_halt ((hio_dev_t*)dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
int hio_dev_shw_read (hio_dev_shw_t* dev, int enabled)
|
||||||
|
{
|
||||||
|
return hio_dev_read((hio_dev_t*)dev, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
int hio_dev_shw_timedread (hio_dev_shw_t* dev, int enabled, const hio_ntime_t* tmout)
|
||||||
|
{
|
||||||
|
return hio_dev_timedread((hio_dev_t*)dev, enabled, tmout);
|
||||||
|
}
|
||||||
|
|
||||||
|
int hio_dev_shw_write (hio_dev_shw_t* dev, const void* data, hio_iolen_t dlen, void* wrctx)
|
||||||
|
{
|
||||||
|
return hio_dev_write((hio_dev_t*)dev, data, dlen, wrctx, HIO_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int hio_dev_shw_timedwrite (hio_dev_shw_t* dev, const void* data, hio_iolen_t dlen, const hio_ntime_t* tmout, void* wrctx)
|
||||||
|
{
|
||||||
|
return hio_dev_timedwrite((hio_dev_t*)dev, data, dlen, tmout, wrctx, HIO_NULL);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user