From 5b2ffd6191fa7496f334964138b63e758937cac3 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Mon, 14 Feb 2022 15:08:28 +0000 Subject: [PATCH] implementing the pty device --- hio/Makefile.in | 1 + hio/bin/Makefile.am | 7 + hio/bin/Makefile.in | 43 ++++- hio/bin/t05.c | 86 +++++++++ hio/configure | 28 ++- hio/configure.ac | 3 +- hio/lib/Makefile.am | 1 + hio/lib/Makefile.in | 35 ++-- hio/lib/hio-cfg.h.in | 9 + hio/lib/hio-pipe.h | 4 +- hio/lib/hio-pty.h | 137 +++++++++++++++ hio/lib/pty.c | 411 +++++++++++++++++++++++++++++++++++++++++++ hio/lib/sck.c | 10 +- hio/t/Makefile.in | 1 + 14 files changed, 747 insertions(+), 29 deletions(-) create mode 100644 hio/bin/t05.c create mode 100644 hio/lib/hio-pty.h create mode 100644 hio/lib/pty.c diff --git a/hio/Makefile.in b/hio/Makefile.in index 6015ee4..4a0d88f 100644 --- a/hio/Makefile.in +++ b/hio/Makefile.in @@ -339,6 +339,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ diff --git a/hio/bin/Makefile.am b/hio/bin/Makefile.am index 07349f4..a3d23e1 100644 --- a/hio/bin/Makefile.am +++ b/hio/bin/Makefile.am @@ -50,6 +50,13 @@ hio_t04_LDFLAGS += $(MARIADB_LDFLAGS) hio_t04_LDADD += $(MARIADB_LIBS) endif +bin_PROGRAMS += hio-t05 +hio_t05_SOURCES = t05.c +hio_t05_CPPFLAGS = $(CPPFLAGS_COMMON) +hio_t05_CFLAGS = $(CFLAGS_COMMON) +hio_t05_LDFLAGS = $(LDFLAGS_COMMON) +hio_t05_LDADD = $(LIBADD_COMMON) + bin_PROGRAMS += hio-t06 hio_t06_SOURCES = t06.c hio_t06_CPPFLAGS = $(CPPFLAGS_COMMON) diff --git a/hio/bin/Makefile.in b/hio/bin/Makefile.in index fe046a1..d155e72 100644 --- a/hio/bin/Makefile.in +++ b/hio/bin/Makefile.in @@ -89,7 +89,8 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = hio-execd$(EXEEXT) hio-t01$(EXEEXT) hio-t02$(EXEEXT) \ - hio-t03$(EXEEXT) hio-t04$(EXEEXT) hio-t06$(EXEEXT) + hio-t03$(EXEEXT) hio-t04$(EXEEXT) hio-t05$(EXEEXT) \ + hio-t06$(EXEEXT) @ENABLE_MARIADB_TRUE@am__append_1 = $(MARIADB_CFLAGS) @ENABLE_MARIADB_TRUE@am__append_2 = $(MARIADB_LDFLAGS) @ENABLE_MARIADB_TRUE@am__append_3 = $(MARIADB_LIBS) @@ -146,6 +147,12 @@ hio_t04_DEPENDENCIES = $(LIBADD_COMMON) $(am__DEPENDENCIES_2) hio_t04_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(hio_t04_CFLAGS) \ $(CFLAGS) $(hio_t04_LDFLAGS) $(LDFLAGS) -o $@ +am_hio_t05_OBJECTS = hio_t05-t05.$(OBJEXT) +hio_t05_OBJECTS = $(am_hio_t05_OBJECTS) +hio_t05_DEPENDENCIES = $(LIBADD_COMMON) +hio_t05_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(hio_t05_CFLAGS) \ + $(CFLAGS) $(hio_t05_LDFLAGS) $(LDFLAGS) -o $@ am_hio_t06_OBJECTS = hio_t06-t06.$(OBJEXT) hio_t06_OBJECTS = $(am_hio_t06_OBJECTS) hio_t06_DEPENDENCIES = $(LIBADD_COMMON) @@ -170,7 +177,7 @@ am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/hio_execd-execd.Po \ ./$(DEPDIR)/hio_t01-t01.Po ./$(DEPDIR)/hio_t02-t02.Po \ ./$(DEPDIR)/hio_t03-t03.Po ./$(DEPDIR)/hio_t04-t04.Po \ - ./$(DEPDIR)/hio_t06-t06.Po + ./$(DEPDIR)/hio_t05-t05.Po ./$(DEPDIR)/hio_t06-t06.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -191,10 +198,11 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(hio_execd_SOURCES) $(hio_t01_SOURCES) $(hio_t02_SOURCES) \ - $(hio_t03_SOURCES) $(hio_t04_SOURCES) $(hio_t06_SOURCES) + $(hio_t03_SOURCES) $(hio_t04_SOURCES) $(hio_t05_SOURCES) \ + $(hio_t06_SOURCES) DIST_SOURCES = $(hio_execd_SOURCES) $(hio_t01_SOURCES) \ $(hio_t02_SOURCES) $(hio_t03_SOURCES) $(hio_t04_SOURCES) \ - $(hio_t06_SOURCES) + $(hio_t05_SOURCES) $(hio_t06_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -351,6 +359,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -395,6 +404,11 @@ hio_t04_CPPFLAGS = $(CPPFLAGS_COMMON) hio_t04_CFLAGS = $(CFLAGS_COMMON) $(am__append_1) hio_t04_LDFLAGS = $(LDFLAGS_COMMON) $(am__append_2) hio_t04_LDADD = $(LIBADD_COMMON) $(am__append_3) +hio_t05_SOURCES = t05.c +hio_t05_CPPFLAGS = $(CPPFLAGS_COMMON) +hio_t05_CFLAGS = $(CFLAGS_COMMON) +hio_t05_LDFLAGS = $(LDFLAGS_COMMON) +hio_t05_LDADD = $(LIBADD_COMMON) hio_t06_SOURCES = t06.c hio_t06_CPPFLAGS = $(CPPFLAGS_COMMON) hio_t06_CFLAGS = $(CFLAGS_COMMON) @@ -503,6 +517,10 @@ hio-t04$(EXEEXT): $(hio_t04_OBJECTS) $(hio_t04_DEPENDENCIES) $(EXTRA_hio_t04_DEP @rm -f hio-t04$(EXEEXT) $(AM_V_CCLD)$(hio_t04_LINK) $(hio_t04_OBJECTS) $(hio_t04_LDADD) $(LIBS) +hio-t05$(EXEEXT): $(hio_t05_OBJECTS) $(hio_t05_DEPENDENCIES) $(EXTRA_hio_t05_DEPENDENCIES) + @rm -f hio-t05$(EXEEXT) + $(AM_V_CCLD)$(hio_t05_LINK) $(hio_t05_OBJECTS) $(hio_t05_LDADD) $(LIBS) + hio-t06$(EXEEXT): $(hio_t06_OBJECTS) $(hio_t06_DEPENDENCIES) $(EXTRA_hio_t06_DEPENDENCIES) @rm -f hio-t06$(EXEEXT) $(AM_V_CCLD)$(hio_t06_LINK) $(hio_t06_OBJECTS) $(hio_t06_LDADD) $(LIBS) @@ -518,6 +536,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hio_t02-t02.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hio_t03-t03.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hio_t04-t04.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hio_t05-t05.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hio_t06-t06.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @@ -620,6 +639,20 @@ hio_t04-t04.obj: t04.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hio_t04_CPPFLAGS) $(CPPFLAGS) $(hio_t04_CFLAGS) $(CFLAGS) -c -o hio_t04-t04.obj `if test -f 't04.c'; then $(CYGPATH_W) 't04.c'; else $(CYGPATH_W) '$(srcdir)/t04.c'; fi` +hio_t05-t05.o: t05.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hio_t05_CPPFLAGS) $(CPPFLAGS) $(hio_t05_CFLAGS) $(CFLAGS) -MT hio_t05-t05.o -MD -MP -MF $(DEPDIR)/hio_t05-t05.Tpo -c -o hio_t05-t05.o `test -f 't05.c' || echo '$(srcdir)/'`t05.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/hio_t05-t05.Tpo $(DEPDIR)/hio_t05-t05.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t05.c' object='hio_t05-t05.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hio_t05_CPPFLAGS) $(CPPFLAGS) $(hio_t05_CFLAGS) $(CFLAGS) -c -o hio_t05-t05.o `test -f 't05.c' || echo '$(srcdir)/'`t05.c + +hio_t05-t05.obj: t05.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hio_t05_CPPFLAGS) $(CPPFLAGS) $(hio_t05_CFLAGS) $(CFLAGS) -MT hio_t05-t05.obj -MD -MP -MF $(DEPDIR)/hio_t05-t05.Tpo -c -o hio_t05-t05.obj `if test -f 't05.c'; then $(CYGPATH_W) 't05.c'; else $(CYGPATH_W) '$(srcdir)/t05.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/hio_t05-t05.Tpo $(DEPDIR)/hio_t05-t05.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t05.c' object='hio_t05-t05.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hio_t05_CPPFLAGS) $(CPPFLAGS) $(hio_t05_CFLAGS) $(CFLAGS) -c -o hio_t05-t05.obj `if test -f 't05.c'; then $(CYGPATH_W) 't05.c'; else $(CYGPATH_W) '$(srcdir)/t05.c'; fi` + hio_t06-t06.o: t06.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hio_t06_CPPFLAGS) $(CPPFLAGS) $(hio_t06_CFLAGS) $(CFLAGS) -MT hio_t06-t06.o -MD -MP -MF $(DEPDIR)/hio_t06-t06.Tpo -c -o hio_t06-t06.o `test -f 't06.c' || echo '$(srcdir)/'`t06.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/hio_t06-t06.Tpo $(DEPDIR)/hio_t06-t06.Po @@ -772,6 +805,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/hio_t02-t02.Po -rm -f ./$(DEPDIR)/hio_t03-t03.Po -rm -f ./$(DEPDIR)/hio_t04-t04.Po + -rm -f ./$(DEPDIR)/hio_t05-t05.Po -rm -f ./$(DEPDIR)/hio_t06-t06.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ @@ -823,6 +857,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/hio_t02-t02.Po -rm -f ./$(DEPDIR)/hio_t03-t03.Po -rm -f ./$(DEPDIR)/hio_t04-t04.Po + -rm -f ./$(DEPDIR)/hio_t05-t05.Po -rm -f ./$(DEPDIR)/hio_t06-t06.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff --git a/hio/bin/t05.c b/hio/bin/t05.c new file mode 100644 index 0000000..6319181 --- /dev/null +++ b/hio/bin/t05.c @@ -0,0 +1,86 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static hio_t* g_hio = HIO_NULL; + +static void handle_sigint (int sig) +{ + if (g_hio) hio_stop (g_hio, HIO_STOPREQ_TERMINATION); +} + +int pty_on_read (hio_dev_pty_t* dev, const void* data, hio_iolen_t len) +{ + hio_iolen_t i; + for (i = 0; i < len; i++) fputc(*((char*)data + i), stdout); + return 0; +} + +int pty_on_write (hio_dev_pty_t* dev, hio_iolen_t wrlen, void* wrctx) +{ + return 0; +} + +void pty_on_close (hio_dev_pty_t* dev) +{ + printf (">> pty closed....\n"); +} + + +int main (int argc, char* argv[]) +{ + hio_t* hio = HIO_NULL; + hio_dev_pty_t* pty; + hio_dev_pty_make_t pi; + struct sigaction sigact; + int xret = -1; + + memset (&sigact, 0, HIO_SIZEOF(sigact)); + sigact.sa_handler = SIG_IGN; + sigaction (SIGPIPE, &sigact, HIO_NULL); + + memset (&sigact, 0, HIO_SIZEOF(sigact)); + sigact.sa_handler = handle_sigint; + sigaction (SIGINT, &sigact, HIO_NULL); + + hio = hio_open(HIO_NULL, 0, HIO_NULL, HIO_FEATURE_ALL, 512, HIO_NULL); + if (!hio) + { + printf ("Cannot open hio\n"); + goto oops; + } + + hio_setoption (hio, HIO_LOG_TARGET_BCSTR, "/dev/stderr"); + + memset (&pi, 0, HIO_SIZEOF(pi)); + pi.on_write = pty_on_write; + pi.on_read = pty_on_read; + pi.on_close = pty_on_close; + pty = hio_dev_pty_make(hio, 0, &pi); + if (!pty) goto oops; + + g_hio = hio; + + hio_loop (hio); + + xret = 0; + +oops: + + memset (&sigact, 0, HIO_SIZEOF(sigact)); + sigact.sa_handler = SIG_IGN; + sigaction (SIGINT, &sigact, HIO_NULL); + + if (hio) hio_close (hio); + return xret; +} + diff --git a/hio/configure b/hio/configure index 0d24aeb..3659183 100755 --- a/hio/configure +++ b/hio/configure @@ -761,6 +761,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -851,6 +852,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1103,6 +1105,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1240,7 +1251,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1393,6 +1404,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -14004,7 +14016,7 @@ fi done -for ac_header in quadmath.h crt_externs.h sys/prctl.h +for ac_header in quadmath.h crt_externs.h sys/prctl.h pty.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -14163,6 +14175,18 @@ _ACEOF fi done +for ac_func in openpty posix_openpt +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + for ac_func in makecontext swapcontext getcontext setcontext do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` diff --git a/hio/configure.ac b/hio/configure.ac index 16d7ce9..dbd5f8a 100644 --- a/hio/configure.ac +++ b/hio/configure.ac @@ -113,7 +113,7 @@ AC_CHECK_HEADERS([net/if.h net/if_dl.h netpacket/packet.h net/bpf.h], [], [], [ #include #include ]) AC_CHECK_HEADERS([sys/stropts.h sys/macstat.h linux/ethtool.h linux/sockios.h]) -AC_CHECK_HEADERS([quadmath.h crt_externs.h sys/prctl.h]) +AC_CHECK_HEADERS([quadmath.h crt_externs.h sys/prctl.h pty.h]) dnl check data types dnl AC_CHECK_TYPE([wchar_t], @@ -135,6 +135,7 @@ AC_CHECK_FUNCS([utime utimes futimes lutimes futimens]) AC_CHECK_FUNCS([sysconf prctl fdopendir setrlimit getrlimit getpgid getpgrp]) AC_CHECK_FUNCS([backtrace backtrace_symbols]) AC_CHECK_FUNCS([fork vfork posix_spawn gettid nanosleep select]) +AC_CHECK_FUNCS([openpty posix_openpt]) AC_CHECK_FUNCS([makecontext swapcontext getcontext setcontext]) AC_CHECK_FUNCS([snprintf _vsnprintf _vsnwprintf]) AC_CHECK_FUNCS([pipe2 accept4 paccept sendmsg recvmsg writev readv]) diff --git a/hio/lib/Makefile.am b/hio/lib/Makefile.am index dbd1284..fafe7b9 100644 --- a/hio/lib/Makefile.am +++ b/hio/lib/Makefile.am @@ -88,6 +88,7 @@ libhio_la_SOURCES = \ path.c \ pipe.c \ pro.c \ + pty.c \ rad-msg.c \ sck.c \ skad.c \ diff --git a/hio/lib/Makefile.in b/hio/lib/Makefile.in index 97ca283..fe85f83 100644 --- a/hio/lib/Makefile.in +++ b/hio/lib/Makefile.in @@ -151,10 +151,10 @@ 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 \ 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 \ - path.c pipe.c pro.c rad-msg.c sck.c skad.c sys.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 utl-str.c \ - mar.c mar-cli.c + path.c pipe.c pro.c pty.c rad-msg.c sck.c skad.c sys.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 \ + utl-str.c mar.c mar-cli.c @ENABLE_MARIADB_TRUE@am__objects_1 = libhio_la-mar.lo \ @ENABLE_MARIADB_TRUE@ libhio_la-mar-cli.lo am_libhio_la_OBJECTS = libhio_la-chr.lo libhio_la-dhcp-svr.lo \ @@ -166,12 +166,12 @@ am_libhio_la_OBJECTS = libhio_la-chr.lo libhio_la-dhcp-svr.lo \ libhio_la-http-txt.lo libhio_la-json.lo libhio_la-hio.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-rad-msg.lo libhio_la-sck.lo libhio_la-skad.lo \ - libhio_la-sys.lo libhio_la-sys-ass.lo libhio_la-sys-err.lo \ - libhio_la-sys-log.lo libhio_la-sys-mux.lo libhio_la-sys-tim.lo \ - libhio_la-thr.lo libhio_la-tmr.lo libhio_la-utf8.lo \ - libhio_la-utl.lo libhio_la-utl-siph.lo libhio_la-utl-str.lo \ - $(am__objects_1) + 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-sys-err.lo libhio_la-sys-log.lo libhio_la-sys-mux.lo \ + libhio_la-sys-tim.lo libhio_la-thr.lo libhio_la-tmr.lo \ + libhio_la-utf8.lo libhio_la-utl.lo libhio_la-utl-siph.lo \ + libhio_la-utl-str.lo $(am__objects_1) libhio_la_OBJECTS = $(am_libhio_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -212,7 +212,7 @@ am__depfiles_remade = ./$(DEPDIR)/libhio_la-chr.Plo \ ./$(DEPDIR)/libhio_la-mar.Plo ./$(DEPDIR)/libhio_la-md5.Plo \ ./$(DEPDIR)/libhio_la-nwif.Plo ./$(DEPDIR)/libhio_la-opt.Plo \ ./$(DEPDIR)/libhio_la-path.Plo ./$(DEPDIR)/libhio_la-pipe.Plo \ - ./$(DEPDIR)/libhio_la-pro.Plo \ + ./$(DEPDIR)/libhio_la-pro.Plo ./$(DEPDIR)/libhio_la-pty.Plo \ ./$(DEPDIR)/libhio_la-rad-msg.Plo \ ./$(DEPDIR)/libhio_la-sck.Plo ./$(DEPDIR)/libhio_la-skad.Plo \ ./$(DEPDIR)/libhio_la-sys-ass.Plo \ @@ -410,6 +410,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -458,7 +459,7 @@ 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 \ 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 \ - pro.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 skad.c sys.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 utl-str.c \ $(am__append_2) @@ -587,6 +588,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-path.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-pipe.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-pro.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-sck.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-skad.Plo@am__quote@ # am--include-marker @@ -801,6 +803,13 @@ libhio_la-pro.lo: pro.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) $(libhio_la_CPPFLAGS) $(CPPFLAGS) $(libhio_la_CFLAGS) $(CFLAGS) -c -o libhio_la-pro.lo `test -f 'pro.c' || echo '$(srcdir)/'`pro.c +libhio_la-pty.lo: pty.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-pty.lo -MD -MP -MF $(DEPDIR)/libhio_la-pty.Tpo -c -o libhio_la-pty.lo `test -f 'pty.c' || echo '$(srcdir)/'`pty.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhio_la-pty.Tpo $(DEPDIR)/libhio_la-pty.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pty.c' object='libhio_la-pty.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-pty.lo `test -f 'pty.c' || echo '$(srcdir)/'`pty.c + libhio_la-rad-msg.lo: rad-msg.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-rad-msg.lo -MD -MP -MF $(DEPDIR)/libhio_la-rad-msg.Tpo -c -o libhio_la-rad-msg.lo `test -f 'rad-msg.c' || echo '$(srcdir)/'`rad-msg.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhio_la-rad-msg.Tpo $(DEPDIR)/libhio_la-rad-msg.Plo @@ -1101,6 +1110,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libhio_la-path.Plo -rm -f ./$(DEPDIR)/libhio_la-pipe.Plo -rm -f ./$(DEPDIR)/libhio_la-pro.Plo + -rm -f ./$(DEPDIR)/libhio_la-pty.Plo -rm -f ./$(DEPDIR)/libhio_la-rad-msg.Plo -rm -f ./$(DEPDIR)/libhio_la-sck.Plo -rm -f ./$(DEPDIR)/libhio_la-skad.Plo @@ -1188,6 +1198,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libhio_la-path.Plo -rm -f ./$(DEPDIR)/libhio_la-pipe.Plo -rm -f ./$(DEPDIR)/libhio_la-pro.Plo + -rm -f ./$(DEPDIR)/libhio_la-pty.Plo -rm -f ./$(DEPDIR)/libhio_la-rad-msg.Plo -rm -f ./$(DEPDIR)/libhio_la-sck.Plo -rm -f ./$(DEPDIR)/libhio_la-skad.Plo diff --git a/hio/lib/hio-cfg.h.in b/hio/lib/hio-cfg.h.in index c4e8ded..1c15eec 100644 --- a/hio/lib/hio-cfg.h.in +++ b/hio/lib/hio-cfg.h.in @@ -226,6 +226,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_H +/* Define to 1 if you have the `openpty' function. */ +#undef HAVE_OPENPTY + /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_ENGINE_H @@ -244,6 +247,9 @@ /* Define to 1 if you have the `posix_fadvise' function. */ #undef HAVE_POSIX_FADVISE +/* Define to 1 if you have the `posix_openpt' function. */ +#undef HAVE_POSIX_OPENPT + /* Define to 1 if you have the `posix_spawn' function. */ #undef HAVE_POSIX_SPAWN @@ -262,6 +268,9 @@ /* Have PTHREAD_PRIO_INHERIT. */ #undef HAVE_PTHREAD_PRIO_INHERIT +/* Define to 1 if you have the header file. */ +#undef HAVE_PTY_H + /* Define to 1 if you have the header file. */ #undef HAVE_QUADMATH_H diff --git a/hio/lib/hio-pipe.h b/hio/lib/hio-pipe.h index abb7f58..d80f762 100644 --- a/hio/lib/hio-pipe.h +++ b/hio/lib/hio-pipe.h @@ -2,13 +2,13 @@ Copyright (c) 2016-2020 Chung, Hyung-Hwan. All rights reserved. Redistribution and use in source and binary forms, with or without - modification, are permitted pipevided that the following conditions + 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 pipevided with the distribution. + 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 diff --git a/hio/lib/hio-pty.h b/hio/lib/hio-pty.h new file mode 100644 index 0000000..47aad51 --- /dev/null +++ b/hio/lib/hio-pty.h @@ -0,0 +1,137 @@ +/* + 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_PTY_H_ +#define _HIO_PTY_H_ + +#include + +typedef struct hio_dev_pty_t hio_dev_pty_t; + +typedef int (*hio_dev_pty_on_read_t) ( + hio_dev_pty_t* dev, + const void* data, + hio_iolen_t len +); + +typedef int (*hio_dev_pty_on_write_t) ( + hio_dev_pty_t* dev, + hio_iolen_t wrlen, + void* wrctx +); + +typedef void (*hio_dev_pty_on_close_t) ( + hio_dev_pty_t* dev +); + +struct hio_dev_pty_t +{ + HIO_DEV_HEADER; + + hio_syshnd_t pfd; + + hio_dev_pty_on_read_t on_read; + hio_dev_pty_on_write_t on_write; + hio_dev_pty_on_close_t on_close; +}; + +typedef struct hio_dev_pty_make_t hio_dev_pty_make_t; +struct hio_dev_pty_make_t +{ + hio_dev_pty_on_write_t on_write; /* mandatory */ + hio_dev_pty_on_read_t on_read; /* mandatory */ + hio_dev_pty_on_close_t on_close; /* optional */ +}; + +enum hio_dev_pty_ioctl_cmd_t +{ + HIO_DEV_PTY_CLOSE +}; +typedef enum hio_dev_pty_ioctl_cmd_t hio_dev_pty_ioctl_cmd_t; + +#if defined(__cplusplus) +extern "C" { +#endif + +HIO_EXPORT hio_dev_pty_t* hio_dev_pty_make ( + hio_t* hio, + hio_oow_t xtnsize, + const hio_dev_pty_make_t* data +); + +#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); } +#else +# define hio_dev_pty_gethio(pty) hio_dev_gethio(pty) +#endif + +#if defined(HIO_HAVE_INLINE) +static HIO_INLINE void* hio_dev_pty_getxtn (hio_dev_pty_t* pty) { return (void*)(pty + 1); } +#else +# define hio_dev_pty_getxtn(pty) ((void*)(((hio_dev_pty_t*)pty) + 1)) +#endif + +HIO_EXPORT void hio_dev_pty_kill ( + hio_dev_pty_t* pty +); + +HIO_EXPORT void hio_dev_pty_halt ( + hio_dev_pty_t* pty +); + +HIO_EXPORT int hio_dev_pty_read ( + hio_dev_pty_t* pty, + int enabled +); + +HIO_EXPORT int hio_dev_pty_timedread ( + hio_dev_pty_t* pty, + int enabled, + const hio_ntime_t* tmout +); + +HIO_EXPORT int hio_dev_pty_write ( + hio_dev_pty_t* pty, + const void* data, + hio_iolen_t len, + void* wrctx +); + +HIO_EXPORT int hio_dev_pty_timedwrite ( + hio_dev_pty_t* pty, + const void* data, + hio_iolen_t len, + const hio_ntime_t* tmout, + void* wrctx +); + +HIO_EXPORT int hio_dev_pty_close ( + hio_dev_pty_t* pty +); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/hio/lib/pty.c b/hio/lib/pty.c new file mode 100644 index 0000000..465f4f1 --- /dev/null +++ b/hio/lib/pty.c @@ -0,0 +1,411 @@ +/* + 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 +#include "hio-prv.h" + +#include +#include +#include + +#include +#include + +#if defined(HAVE_PTY_H) +# include +#endif + +/* ========================================================================= */ + +static int dev_pty_make (hio_dev_t* dev, void* ctx) +{ + hio_t* hio = dev->hio; + hio_dev_pty_t* rdev = (hio_dev_pty_t*)dev; + hio_dev_pty_make_t* info = (hio_dev_pty_make_t*)ctx; + hio_syshnd_t pfds[2] = { HIO_SYSHND_INVALID, HIO_SYSHND_INVALID }; + int i, fd; + pid_t pid; + +#if defined(HAVE_POSIX_OPENPT) + + /* open a pty master unused */ + fd = posix_openpt(O_RDWR | O_NOCTTY); + if (fd == -1) + { + hio_seterrwithsyserr (hio, 0, errno); + goto oops; + } + + pfds[0] = fd; + + if (grantpt(pfds[0]) == -1 || unlockpt(pfds[0]) == -1) + { + hio_seterrwithsyserr (hio, 0, errno); + goto oops; + } + else + { + char pts_name_buf[128]; + char* ptr = pts_name_buf; + hio_oow_t capa = HIO_COUNTOF(pts_name_buf); + + /* open a pty slave device name */ + if (ptsname_r(pfds[0], ptr, capa) != 0) + { + if (errno == ERANGE) + { + char* tmp; + tmp = hio_reallocmem(hio, (ptr == pts_name_buf? HIO_NULL: ptr), capa + 128); + if (HIO_UNLIKELY(!tmp)) + { + if (ptr != pts_name_buf) hio_freemem (hio, ptr); + goto oops; + } + ptr = tmp; + capa += 128; + } + hio_seterrwithsyserr (hio, 0, errno); + goto oops; + } + + /* open a pty slave */ + pfds[1] = open(ptr, O_RDWR | O_NOCTTY); + if (pfds[1] == -1) + { + hio_seterrwithsyserr (hio, 0, errno); + if (ptr != pts_name_buf) hio_freemem (hio, ptr); + goto oops; + } + + if (ptr != pts_name_buf) hio_freemem (hio, ptr); + } + +#elif defined(HAVE_OPENPTY) + if (openpty(&pfds[0], &pfds[1], HIO_NULL, HIO_NULL, HIO_NULL) == -1) + { + hio_seterrwithsyserr (hio, 0, errno); + goto oops; + } +#else +# error NOT IMPLEMENTED YET +#endif + + if (hio_makesyshndcloexec(hio, pfds[0]) <= -1) goto oops; + if (hio_makesyshndcloexec(hio, pfds[1]) <= -1) goto oops; + + pid = fork(); + if (pid == -1) + { + hio_seterrwithsyserr (hio, 0, errno); + goto oops; + } + + if (pid == 0) + { + /* child */ + close (pfds[0]); /* close the pty master */ + pfds[0] = HIO_SYSHND_INVALID; + + /*TODO: close all open file descriptors */ + + setsid (); /* TODO: error check? */ + setpgid (0, 0); + if (ioctl(pfds[1], TIOCSCTTY, HIO_NULL) == -1) goto slave_oops; + + if (dup2(pfds[1], 0) == -1 || dup2(pfds[1], 1) == -1 || dup2(pfds[1], 2) == -1) goto slave_oops; + + close (pfds[1]); + pfds[1] == HIO_SYSHND_INVALID; + +/* TODO: no hard-coding of the executed program */ + execl ("/bin/bash", "bin/bash", "/tmp/a.sh", HIO_NULL); + + slave_oops: + if (pfds[1] != HIO_SYSHND_INVALID) close(pfds[1]); + _exit (128); + } + + close (pfds[1]); /* close the pty slave */ + pfds[1] = HIO_SYSHND_INVALID; + + if (hio_makesyshndasync(hio, pfds[0]) <= -1) goto oops; + + rdev->pfd = pfds[0]; + rdev->dev_cap = HIO_DEV_CAP_OUT | HIO_DEV_CAP_IN | HIO_DEV_CAP_STREAM; + rdev->on_read = info->on_read; + rdev->on_write = info->on_write; + rdev->on_close = info->on_close; + return 0; + +oops: + if (pfds[0] != HIO_SYSHND_INVALID) close (pfds[0]); + if (pfds[1] != HIO_SYSHND_INVALID) close (pfds[0]); + return -1; +} + +static int dev_pty_kill (hio_dev_t* dev, int force) +{ + /*hio_t* hio = dev->hio;*/ + hio_dev_pty_t* rdev = (hio_dev_pty_t*)dev; + + if (rdev->on_close) rdev->on_close (rdev); + + if (rdev->pfd != HIO_SYSHND_INVALID) + { + close (rdev->pfd); + rdev->pfd = HIO_SYSHND_INVALID; + } + return 0; +} + +static int dev_pty_read (hio_dev_t* dev, void* buf, hio_iolen_t* len, hio_devaddr_t* srcaddr) +{ + hio_dev_pty_t* pty = (hio_dev_pty_t*)dev; + ssize_t x; + + if (HIO_UNLIKELY(pty->pfd == HIO_SYSHND_INVALID)) + { + hio_seterrnum (pty->hio, HIO_EBADHND); + return -1; + } + + x = read(pty->pfd, buf, *len); + if (x <= -1) + { + if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data available */ + if (errno == EINTR) return 0; + hio_seterrwithsyserr (pty->hio, 0, errno); + return -1; + } + + *len = x; + return 1; +} + +static int dev_pty_write (hio_dev_t* dev, const void* data, hio_iolen_t* len, const hio_devaddr_t* dstaddr) +{ + hio_dev_pty_t* pty = (hio_dev_pty_t*)dev; + ssize_t x; + + if (HIO_UNLIKELY(pty->pfd == HIO_SYSHND_INVALID)) + { + hio_seterrnum (pty->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(pty->pfd != HIO_SYSHND_INVALID)) /* halt() doesn't close the pty immediately. so close the underlying pty */ + { + hio_dev_watch (dev, HIO_DEV_WATCH_STOP, 0); + close (pty->pfd); + pty->pfd = HIO_SYSHND_INVALID; + } + return 1; /* indicate that the operation got successful. the core will execute on_write() with 0. */ + } + + x = write(pty->pfd, data, *len); + if (x <= -1) + { + if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) return 0; /* no data can be written */ + if (errno == EINTR) return 0; + hio_seterrwithsyserr (pty->hio, 0, errno); + return -1; + } + + *len = x; + return 1; +} + +static int dev_pty_writev (hio_dev_t* dev, const hio_iovec_t* iov, hio_iolen_t* iovcnt, const hio_devaddr_t* dstaddr) +{ + hio_dev_pty_t* pty = (hio_dev_pty_t*)dev; + ssize_t x; + + if (HIO_UNLIKELY(pty->pfd == HIO_SYSHND_INVALID)) + { + hio_seterrnum (pty->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(pty->pfd != HIO_SYSHND_INVALID)) /* halt() doesn't close the pty immediately. so close the underlying pty */ + { + hio_dev_watch (dev, HIO_DEV_WATCH_STOP, 0); + close (pty->pfd); + pty->pfd = HIO_SYSHND_INVALID; + } + return 1; /* indicate that the operation got successful. the core will execute on_write() with 0. */ + } + + x = writev(pty->pfd, 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 (pty->hio, 0, errno); + return -1; + } + + *iovcnt = x; + return 1; +} + +static hio_syshnd_t dev_pty_getsyshnd (hio_dev_t* dev) +{ + hio_dev_pty_t* rdev = (hio_dev_pty_t*)dev; + return rdev->pfd; +} + +static int dev_pty_ioctl (hio_dev_t* dev, int cmd, void* arg) +{ + hio_t* hio = dev->hio; + hio_dev_pty_t* rdev = (hio_dev_pty_t*)dev; + + switch (cmd) + { + case HIO_DEV_PTY_CLOSE: + { + hio_dev_kill ((hio_dev_t*)rdev); + return 0; + } + + default: + hio_seterrnum (hio, HIO_EINVAL); + return -1; + } +} + +static hio_dev_mth_t dev_pty_methods = +{ + dev_pty_make, + dev_pty_kill, + HIO_NULL, + dev_pty_getsyshnd, + HIO_NULL, + dev_pty_ioctl, + + dev_pty_read, + dev_pty_write, + dev_pty_writev, + HIO_NULL, /* sendfile */ +}; + +/* ========================================================================= */ + +static int pty_ready (hio_dev_t* dev, int events) +{ + hio_t* hio = dev->hio; + /*hio_dev_pty_t* pty = (hio_dev_pty_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)) + { + /* ptybably half-open? */ + return 1; + } + + hio_seterrnum (hio, HIO_EDEVHUP); + return -1; + } + + return 1; /* the device is ok. carry on reading or writing */ +} + +static int pty_on_read (hio_dev_t* dev, const void* data, hio_iolen_t len, const hio_devaddr_t* srcaddr) +{ + hio_dev_pty_t* pty = (hio_dev_pty_t*)dev; + return pty->on_read(pty, data, len); +} + +static int pty_on_write (hio_dev_t* dev, hio_iolen_t wrlen, void* wrctx, const hio_devaddr_t* dstaddr) +{ + hio_dev_pty_t* pty = (hio_dev_pty_t*)dev; + return pty->on_write(pty, wrlen, wrctx); +} + + +static hio_dev_evcb_t dev_pty_event_callbacks = +{ + pty_ready, + pty_on_read, + pty_on_write +}; + +/* ========================================================================= */ + +hio_dev_pty_t* hio_dev_pty_make (hio_t* hio, hio_oow_t xtnsize, const hio_dev_pty_make_t* info) +{ + return (hio_dev_pty_t*)hio_dev_make( + hio, HIO_SIZEOF(hio_dev_pty_t) + xtnsize, + &dev_pty_methods, &dev_pty_event_callbacks, (void*)info); +} + +void hio_dev_pty_kill (hio_dev_pty_t* dev) +{ + hio_dev_kill ((hio_dev_t*)dev); +} + +void hio_dev_pty_halt (hio_dev_pty_t* dev) +{ + hio_dev_halt ((hio_dev_t*)dev); +} + +int hio_dev_pty_read (hio_dev_pty_t* dev, int enabled) +{ + return hio_dev_read((hio_dev_t*)dev, enabled); +} + +int hio_dev_pty_timedread (hio_dev_pty_t* dev, int enabled, const hio_ntime_t* tmout) +{ + return hio_dev_timedread((hio_dev_t*)dev, enabled, tmout); +} + +int hio_dev_pty_write (hio_dev_pty_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_pty_timedwrite (hio_dev_pty_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); +} + +int hio_dev_pty_close (hio_dev_pty_t* dev) +{ + return hio_dev_ioctl((hio_dev_t*)dev, HIO_DEV_PTY_CLOSE, HIO_NULL); +} + diff --git a/hio/lib/sck.c b/hio/lib/sck.c index 960405c..21c3c19 100644 --- a/hio/lib/sck.c +++ b/hio/lib/sck.c @@ -443,14 +443,8 @@ static int dev_sck_make (hio_dev_t* dev, void* ctx) return 0; oops: - if (hnd != HIO_SYSHND_INVALID) - { - close (hnd); - } - if (side_chan != HIO_SYSHND_INVALID) - { - close (side_chan); - } + if (hnd != HIO_SYSHND_INVALID) close (hnd); + if (side_chan != HIO_SYSHND_INVALID) close (side_chan); return -1; } diff --git a/hio/t/Makefile.in b/hio/t/Makefile.in index f995043..924c472 100644 --- a/hio/t/Makefile.in +++ b/hio/t/Makefile.in @@ -538,6 +538,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@