From c2635714ea54953aab27c2e180ffa7d0d43edaf4 Mon Sep 17 00:00:00 2001 From: "Steffen (Daode) Nurpmeso" Date: Mon, 14 Aug 2017 23:29:12 +0200 Subject: [PATCH] Add `readall' command --- cc-test.sh | 12 ++++++++++ cmd-misc.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cmd-tab.h | 2 ++ go.c | 2 +- nail.1 | 26 ++++++++++++++++++++- nailfuns.h | 3 +++ 6 files changed, 120 insertions(+), 2 deletions(-) diff --git a/cc-test.sh b/cc-test.sh index 6c78e598..1a4b4f97 100755 --- a/cc-test.sh +++ b/cc-test.sh @@ -2150,6 +2150,18 @@ t_behave_read() { __EOT check behave:read-ifs 0 "${MBOX}" '890153490 298' + ${cat} <<- '__EOT' | ${MAILX} ${ARGS} > "${MBOX}" 2>&1 + readctl create .tin + readall d; echo $?/$^ERRNAME / <$d> + wysh set d;readall d;echo $?/$^ERRNAME / <$d> + readctl create .tin2 + readall d; echo $?/$^ERRNAME / <$d> + wysh set d;readall d;echo $?/$^ERRNAME / <$d> + readctl remove .tin;echo $?/$^ERRNAME;\ + readctl remove .tin2;echo $?/$^ERRNAME + __EOT + check behave:readall 0 "${MBOX}" '860434889 333' + t_epilog } diff --git a/cmd-misc.c b/cmd-misc.c index 2d44d8e4..ee6fbcf9 100644 --- a/cmd-misc.c +++ b/cmd-misc.c @@ -504,6 +504,83 @@ jleave: } FL int +c_readall(void * vp){ /* TODO 64-bit retval */ + struct n_sigman sm; + struct n_string s, *sp; + char *linebuf; + size_t linesize; + int rv; + char const **argv; + NYD2_ENTER; + + sp = n_string_creat_auto(&s); + sp = n_string_reserve(sp, 64 -1); + + linesize = 0; + linebuf = NULL; + argv = vp; + + n_SIGMAN_ENTER_SWITCH(&sm, n_SIGMAN_ALL){ + case 0: + break; + default: + n_pstate_err_no = n_ERR_INTR; + rv = -1; + goto jleave; + } + + n_pstate_err_no = n_ERR_NONE; + + for(;;){ + rv = n_go_input(((n_pstate & n_PS_COMPOSE_MODE + ? n_GO_INPUT_CTX_COMPOSE : n_GO_INPUT_CTX_DEFAULT) | + n_GO_INPUT_FORCE_STDIN | /*n_GO_INPUT_NL_ESC |*/ + n_GO_INPUT_PROMPT_NONE), + NULL, &linebuf, &linesize, NULL, NULL); + if(rv < 0){ + if(!n_go_input_is_eof()){ + n_pstate_err_no = n_ERR_BADF; + goto jleave; + } + if(sp->s_len == 0) + goto jleave; + break; + }else if(rv == 0){ /* xxx will not get*/ + if(n_go_input_is_eof()){ + if(sp->s_len == 0){ + rv = -1; + goto jleave; + } + break; + } + }else if(UICMP(32, SI32_MAX - sp->s_len, <=, rv)){ + n_pstate_err_no = n_ERR_OVERFLOW; + rv = -1; + goto jleave; + }else{ + sp = n_string_push_buf(sp, linebuf, rv); + if(n_pstate & n_PS_READLINE_NL) + sp = n_string_push_c(sp, '\n'); + } + } + + if(!a_cmisc_read_set(argv[0], n_string_cp(sp))){ + n_pstate_err_no = n_ERR_NOTSUP; + rv = -1; + goto jleave; + } + rv = sp->s_len; + + n_sigman_cleanup_ping(&sm); +jleave: + if(linebuf != NULL) + n_free(linebuf); + NYD2_LEAVE; + n_sigman_leave(&sm, n_SIGMAN_VIPSIGS_NTTYOUT); + return rv; +} + +FL int c_version(void *vp){ int longest, rv; char *iop; diff --git a/cmd-tab.h b/cmd-tab.h index 741cba01..17d5182b 100644 --- a/cmd-tab.h +++ b/cmd-tab.h @@ -521,6 +521,8 @@ n_CMD_ARG_DESC_SUBCLASS_DEF(vpospar, 2, a_ctab_cad_vpospar){ { "read", &c_read, (G | M | X | EM | TWYSH), 1, MAC, NULL DS(N_("Read a line from standard input into (s)")) }, + { "readall", &c_readall, (G | M | X | EM | TWYSH), 1, 1, NULL + DS(N_("Read anything from standard input until EOF into ")) }, { "readctl", &c_readctl, (G | M | X | EM | TARG), 0, 0, n_CMD_ARG_DESC_SUBCLASS_CAST(&a_ctab_cad_readctl) DS(N_( diff --git a/go.c b/go.c index 1db7f7c9..cc59302f 100644 --- a/go.c +++ b/go.c @@ -1013,7 +1013,7 @@ a_go_file(char const *file, bool_t silent_open_error){ if((fip = Popen(nbuf /* #if 0 above = savestrbuf(file, nlen)*/, "r", ok_vlook(SHELL), NULL, n_CHILD_FD_NULL)) == NULL) goto jeopencheck; - }else if((nbuf = fexpand(file, FEXP_LOCAL)) == NULL) + }else if((nbuf = fexpand(file, FEXP_LOCAL | FEXP_NVAR)) == NULL) goto jeopencheck; else if((fip = Fopen(nbuf, "r")) == NULL){ jeopencheck: diff --git a/nail.1 b/nail.1 index 0e76d10a..f9457ad3 100644 --- a/nail.1 +++ b/nail.1 @@ -5888,9 +5888,33 @@ hey2.0,:"'you ",:world!:mars.: .Ed . .Mx +.It Ic readall +\*(NQ Read anything from standard input, or the channel set active via +.Ic readctl , +and assign the data to the given variable. +The variable name is checked by the same rules as documented for +.Cm vput , +and the same error codes will be seen in +.Va \&! ; +the exit status +.Va \&? +indicates the number of bytes read, it will be +.Ql -1 +with the error number +.Va \&! +set to +.Va ^ERR Ns -BADF +in case of I/O errors, or +.Va ^ERR Ns -NONE +upon End-Of-File. +\*(ID The input data length is restricted to 31-bits. +. +.Mx .It Ic readctl \*(NQ Manages input channels for -.Ic read , +.Ic read +and +.Ic readall , to be used to avoid complicated or impracticable code, like calling .Ic \&\&read from within a macro in non-interactive mode. diff --git a/nailfuns.h b/nailfuns.h index c3263263..a975e79b 100644 --- a/nailfuns.h +++ b/nailfuns.h @@ -608,6 +608,9 @@ FL int c_echoerrn(void *v); /* `read' */ FL int c_read(void *vp); +/* `readall' */ +FL int c_readall(void *vp); + /* `version' */ FL int c_version(void *vp); -- 2.11.4.GIT