diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2019-08-16 14:32:23 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2019-08-16 14:36:33 +0300 |
commit | 86d62d746d8e2586e1b3a2995f7119d0562145b8 (patch) | |
tree | 592ee9b7e7ea2e2dc4dfd2320f895a3097168e43 | |
parent | b40125990e923f743fa4a1b53c7af05feda422cc (diff) | |
download | runcap-86d62d746d8e2586e1b3a2995f7119d0562145b8.tar.gz runcap-86d62d746d8e2586e1b3a2995f7119d0562145b8.tar.bz2 |
Explicitly indicate EOF when sc_linemon is initialized.
* runcap.3: Document changes.
* runcap.c (stream_capture_get): Indicate EOF explicitly by
calling sc_linemon function with 0 as line length.
* t/rt.c (linemon): Update to handle this case.
-rw-r--r-- | runcap.3 | 93 | ||||
-rw-r--r-- | runcap.c | 15 | ||||
-rw-r--r-- | t/rt.c | 19 |
3 files changed, 82 insertions, 45 deletions
@@ -104,3 +104,3 @@ array. Its elements correspond to the standard input, output and error streams. Upon successful return, the captured -data from stdin and stdout can be retrieved using the \fBruncap_getc\fR, and +data from stdout and stderr can be retrieved using the \fBruncap_getc\fR, and \fBruncap_getline\fR functions (see below). For convenience, the @@ -112,4 +112,4 @@ corresponding streams: .PP -The following fields are warranted to be present in \fBstruct -stream_capture\fR: +The \fBstream_capture\fR structure contains the following members +accessible to the caller: .PP @@ -127,5 +127,5 @@ struct stream_capture - /* The following two are available only in \fBrc_cap[RUNCAP_STDIN]\fR, - see the subsection \fBSupplying standard input\fR below, for - details). */ + /* The following two are available only in \fBrc_cap[RUNCAP_STDIN]\fR + For details. see the subsection \fBSupplying standard input\fR. + */ size_t sc_fd; /* Input file descriptor */ @@ -158,3 +158,3 @@ A pointer to the line monitor function. If set, the .sp -The line monitor function allows the caller to monitor the arrival of +Line monitor function allows the caller to monitor the arrival of the new data in the corresponding stream. It is declared as follows: @@ -167,10 +167,41 @@ data, supplied in the \fBsc_monarg\fR member. .sp -The line monitor function is invoked each time a newline character is -encountered in the stream, or when the stream buffer becomes full (and, -therefore is about to be flushed into the storage file) and some -characters remain unreported. This means that, if the -\fBsc_linemon\fR function is designed to log each input line, it -should keep the state of processing (e.g. in the \fIdata\fR argument), -and concatenate the \fIline\fR parameters until -\fBline[size-1] == '\\n'\fR. +The line monitor function is invoked to notify the caller about +arrival of new data on the stream. There are 4 cases: +.RS +8 +.nr step 1 1 +.IP \n[step]. +A newline newline character is encountered in the stream. +.sp +The \fIline\fR argument points to the beginning of the captured +line. The \fIsize\fR argument contains number of characters in the +line, including the newline character. +.IP \n+[step]. +The stream buffer is full (and therefore is about to be flushed into +the storage file) and contains unfinished line. +.sp +The \fIline\fR +argument points to the beginning of the captured line fragment. The +\fIsize\fR argument contains number of characters in the +fragment. +.IP \n+[step]. +No more characters are available in the stream and the +stream buffer contains unreported characters. +.sp +Argument assignment is the same as in previous case. +.IP \n+[step]. +The stream reached EOF. +.sp +The \fIsize\fR argument is 0. The +\fIline\fR argument is not meaningful, although it does point to a +valid memory location. +.PP +Consequently, if the \fBsc_linemon\fR function needs to process full +lines. it has to keep the state of processing (e.g. in the \fBdata\fR +argument), and concatenate the line parameters until the following +condition is met: +.sp +.EX + size == 0 || line[size-1] == '\\n' +.EE +.RE .TP @@ -178,4 +209,3 @@ and concatenate the \fIline\fR parameters until The value of the \fIdata\fR parameter for the \fBsc_linemon\fR -function. It can be initialized only if \fBsc_linemon\fR is -initialized as well. +function. .SS Supplying standard input @@ -228,3 +258,7 @@ Number of lines in the captured stderr. .PP -The actual data can be retrieved using the \fBruncap_getc\fR, and +The last captured line can be partial, i.e. not terminated with a +newline character. It will be counted in the stream's \fBsc_nlines\fR +anyways. +.PP +Captured data can be retrieved using the \fBruncap_getc\fR, and \fBruncap_getline\fR functions, described below. @@ -232,3 +266,3 @@ The actual data can be retrieved using the \fBruncap_getc\fR, and Upon return from \fBruncap\fR the following functions can be used to -retrieve the captured data from the \fBstruct runcap\fR object pointed +retrieve captured data from the \fBstruct runcap\fR object pointed to by its \fIrc\fR argument. The stream to retrieve data from is @@ -310,5 +344,5 @@ First, you can set the \fBsc_size\fR member of the corresponding \fBRCF_STDOUT_SIZE\fR (for stdout) or \fBRCF_STDERR_SIZE\fR (for -stderr) bit. This was the method used in first releases of runcap. +stderr) flag. This was the method used in first releases of runcap. .PP -The second method is to use the \fBRCF_STDOUT_NOCAP\fR and/or +Another way is to use the \fBRCF_STDOUT_NOCAP\fR and/or \fBRCF_STDERR_NOCAP\fR flag in the call to \fBruncap\fR. @@ -317,7 +351,8 @@ Both methods are equivalent. .PP -If capturing is disabled for a particular stream, the corresponding -file descriptor of the program being invoked remains unchanged. This -means, e.g., that if you disable stderr capturing, error diagnostics -from the programs that \fBruncap\fR runs will appear at the stderr of -your program. Upon return from \fBruncap\fR both +When capturing of a particular stream is disabled, the corresponding +file descriptor of the program being invoked is inherited from the +calling program. This means, e.g., that if you disable stderr +capturing, error diagnostics from the programs that \fBruncap\fR runs +will appear at the stderr of your program. Upon return from +\fBruncap\fR both .B sc_leng @@ -336,6 +371,2 @@ will reflect the actual length in bytes and number of lines in the processed material. -.SS Last line handling -If the last line of the output is not terminated with a newline, it -will be passed to the line monitor function (if such is defined) -verbatim and will be counted in the .B sc_nlines @@ -422,3 +453,3 @@ Sergey Poznyakoff .SH COPYRIGHT -Copyright \(co 2017 Sergey Poznyakoff +Copyright \(co 2017--2019 Sergey Poznyakoff .br @@ -163,8 +163,11 @@ stream_capture_get(struct stream_capture *cap, int *feof) if (rc == 0) { - if (cap->sc_linemon && cap->sc_level > cap->sc_cur) { - cap->sc_linemon(cap->sc_base + cap->sc_cur, - cap->sc_level - cap->sc_cur, - cap->sc_monarg); - cap->sc_cur = cap->sc_level; - cap->sc_nlines++; + if (cap->sc_linemon) { + if (cap->sc_level > cap->sc_cur) { + cap->sc_linemon(cap->sc_base + cap->sc_cur, + cap->sc_level - cap->sc_cur, + cap->sc_monarg); + cap->sc_cur = cap->sc_level; + cap->sc_nlines++; + } + cap->sc_linemon(cap->sc_base, 0, cap->sc_monarg); } @@ -94,10 +94,13 @@ linemon(const char *ptr, size_t len, void *data) struct linemon_closure *clos = data; - - if (!clos->cont) { - printf("%s:", clos->prefix); - if (!(len == 1 && ptr[0] == '\n')) - putchar(' '); - } - fwrite(ptr, len, 1, stdout); - clos->cont = ptr[len-1] != '\n'; + + if (len) { + if (!clos->cont) { + printf("%s:", clos->prefix); + if (!(len == 1 && ptr[0] == '\n')) + putchar(' '); + } + fwrite(ptr, len, 1, stdout); + } else + fflush(stdout); + clos->cont = !(len == 0 || ptr[len-1] == '\n'); } |