diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2017-07-19 23:27:00 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2017-07-19 23:27:00 +0300 |
commit | cf87f3c78915f9cbfd900c9c34033cb924f912e7 (patch) | |
tree | 36488371ea611d2b721f87f3983a7ec64f44128e | |
parent | 99d911104d7c03608398d47c74f1ce3c39bff211 (diff) | |
download | runcap-cf87f3c78915f9cbfd900c9c34033cb924f912e7.tar.gz runcap-cf87f3c78915f9cbfd900c9c34033cb924f912e7.tar.bz2 |
Invokee linemon for partial lines as well
-rw-r--r-- | runcap.3 | 11 | ||||
-rw-r--r-- | runcap.c | 20 | ||||
-rwxr-xr-x | t/02two.t | 2 | ||||
-rwxr-xr-x | t/07mon.t | 101 | ||||
-rw-r--r-- | t/rt.c | 28 |
5 files changed, 149 insertions, 13 deletions
@@ -155,3 +155,3 @@ A pointer to the line monitor function. If set, the The line monitor function allows the caller to monitor the arrival of -each input line in the corresponding stream. Its signature is: +the new data in the corresponding stream. Its signature is: .sp @@ -162,2 +162,11 @@ length, and \fIdata\fR is an opaque pointer to application-specific 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. .TP @@ -115,2 +115,6 @@ stream_capture_flush(struct stream_capture *cap) return 0; + if (cap->sc_linemon && cap->sc_cur < cap->sc_level) + cap->sc_linemon(cap->sc_base + cap->sc_cur, + cap->sc_level - cap->sc_cur, + cap->sc_monarg); if (cap->sc_storfd == -1) { @@ -157,4 +161,4 @@ stream_capture_get(struct stream_capture *cap, int *feof) cap->sc_linemon(cap->sc_base + cap->sc_cur, - cap->sc_level - cap->sc_cur, - cap->sc_monarg); + cap->sc_level - cap->sc_cur, + cap->sc_monarg); cap->sc_cur = cap->sc_level; @@ -441,3 +445,4 @@ runcap_init(struct runcap *rc, int flags) else - res = stream_capture_init(&rc->rc_cap[RUNCAP_STDOUT], STRCAP_BUFSIZE); + res = stream_capture_init(&rc->rc_cap[RUNCAP_STDOUT], + STRCAP_BUFSIZE); if (res) @@ -454,3 +459,4 @@ runcap_init(struct runcap *rc, int flags) else - res = stream_capture_init(&rc->rc_cap[RUNCAP_STDERR], STRCAP_BUFSIZE); + res = stream_capture_init(&rc->rc_cap[RUNCAP_STDERR], + STRCAP_BUFSIZE); if (res) @@ -528,3 +534,7 @@ runcap(struct runcap *rc, int flags) } - return rc->rc_errno == 0 ? 0 : -1; + if (rc->rc_errno) { + errno = rc->rc_errno; + return -1; + } + return 0; } @@ -17,3 +17,3 @@ -TC_TITLE capture both stdout and stder +TC_TITLE capture both stdout and stderr diff --git a/t/07mon.t b/t/07mon.t new file mode 100755 index 0000000..4224f87 --- /dev/null +++ b/t/07mon.t @@ -0,0 +1,101 @@ +#! ./testsuite +# testsuite for runcap - run program and capture its output +# Copyright (C) 2017 Sergey Poznyakoff +# +# Runcap is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +# option) any later version. +# +# Runcap is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Runcap. If not, see <http://www.gnu.org/licenses/>. + +TC_TITLE line monitor, short buffer + +TC_EXPECT out <<EOT +[stdout]: CHAPTER I. Down the Rabbit-Hole +[stdout]: +[stdout]: Alice was beginning to get very tired of sitting by her sister on the +[stdout]: bank, and of having nothing to do: once or twice she had peeped into the +[stdout]: book her sister was reading, but it had no pictures or conversations +[stdout]: in it, 'and what is the use of a book,' thought Alice 'without +[stdout]: pictures or conversations?' +[stdout]: +[stdout]: So she was considering in her own mind (as well as she could, for the +[stdout]: hot day made her feel very sleepy and stupid), whether the pleasure of +[stdout]: making a daisy-chain would be worth the trouble of getting up and picking +[stdout]: the daisies, when suddenly a White Rabbit with pink eyes ran close by her. +[stdout]: +[stdout]: There was nothing so very remarkable in that; nor did Alice think it +[stdout]: so very much out of the way to hear the Rabbit say to itself, 'Oh +[stdout]: dear! Oh dear! I shall be late!' (when she thought it over afterwards, +[stdout]: it occurred to her that she ought to have wondered at this, but at the +[stdout]: time it all seemed quite natural); but when the Rabbit actually took a +[stdout]: watch out of its waistcoat-pocket, and looked at it, and then hurried on, +[stdout]: Alice started to her feet, for it flashed across her mind that she had +[stdout]: never before seen a rabbit with either a waistcoat-pocket, or a watch +[stdout]: to take out of it, and burning with curiosity, she ran across the field +[stdout]: after it, and fortunately was just in time to see it pop down a large +[stdout]: rabbit-hole under the hedge. +[stdout]: +[stdout]: In another moment down went Alice after it, never once considering how +[stdout]: in the world she was to get out again. +[stdout]: +[stdout]: The rabbit-hole went straight on like a tunnel for some way, and then +[stdout]: dipped suddenly down, so suddenly that Alice had not a moment to think +[stdout]: about stopping herself before she found herself falling down a very +[stdout]: deep well. +[stdout]: +[stdout]: Either the well was very deep, or she fell very slowly, for she had plenty +[stdout]: of time as she went down to look about her and to wonder what was going +[stdout]: to happen next. First, she tried to look down and make out what she was +[stdout]: coming to, but it was too dark to see anything; then she looked at the +[stdout]: sides of the well, and noticed that they were filled with cupboards +[stdout]: and book-shelves; here and there she saw maps and pictures hung upon +[stdout]: pegs. She took down a jar from one of the shelves as she passed; it was +[stdout]: labelled 'ORANGE MARMALADE', but to her great disappointment it was +[stdout]: empty: she did not like to drop the jar for fear of killing somebody, +[stdout]: so managed to put it into one of the cupboards as she fell past it. +[stdout]: +[stdout]: 'Well!' thought Alice to herself, 'after such a fall as this, +[stdout]: I shall think nothing of tumbling down stairs! How brave they'll all +[stdout]: think me at home! Why, I wouldn't say anything about it, even if I +[stdout]: fell off the top of the house!' (Which was very likely true.) +[stdout]: +[stdout]: Down, down, down. Would the fall never come to an end! 'I wonder how +[stdout]: many miles I've fallen by this time?' she said aloud. 'I must be +[stdout]: getting somewhere near the centre of the earth. Let me see: that would be +[stdout]: four thousand miles down, I think--' (for, you see, Alice had learnt +[stdout]: several things of this sort in her lessons in the schoolroom, and though +[stdout]: this was not a very good opportunity for showing off her knowledge, +[stdout]: as there was no one to listen to her, still it was good practice to +[stdout]: say it over) '--yes, that's about the right distance--but then I +[stdout]: wonder what Latitude or Longitude I've got to?' (Alice had no idea +[stdout]: what Latitude was, or Longitude either, but thought they were nice grand +[stdout]: words to say.) +[stdout]: +[stdout]: Presently she began again. 'I wonder if I shall fall right through +[stdout]: the earth! How funny it'll seem to come out among the people that +[stdout]: walk with their heads downward! The Antipathies, I think--' (she was +[stdout]: rather glad there was no one listening, this time, as it didn't sound +[stdout]: at all the right word) '--but I shall have to ask them what the name +[stdout]: of the country is, you know. Please, Ma'am, is this New Zealand or +[stdout]: Australia?' (and she tried to curtsey as she spoke--fancy curtseying +[stdout]: as you're falling through the air! Do you think you could manage +[stdout]: it?) 'And what an ignorant little girl she'll think me for asking! No, +[stdout]: it'll never do to ask: perhaps I shall see it written up somewhere.' +res=0 +exit code: 0 +stdout: 71 lines, 4051 bytes +stderr: 0 lines, 0 bytes +EOT + +rt -s 16 -m -- genout $testdir/INPUT + + + @@ -78,2 +78,8 @@ whatarg(char const *arg) +struct linemon_closure +{ + char const *prefix; + int cont; +}; + static void @@ -81,5 +87,8 @@ linemon(const char *ptr, size_t len, void *data) { - fprintf(stdout, "[%s]: ", (char*) data); - fwrite(ptr, len-1, 1, stdout); - fputc('\n', stdout); + struct linemon_closure *clos = data; + + if (!clos->cont) + fprintf(stdout, "[%s]: ", clos->prefix); + fwrite(ptr, len, 1, stdout); + clos->cont = ptr[len-1] != '\n'; } @@ -124,3 +133,8 @@ main(int argc, char **argv) unsigned long size; - + + static struct linemon_closure cl[] = { + { "stdout" }, + { "stderr" } + }; + progname = strrchr(argv[0], '/'); @@ -191,3 +205,4 @@ main(int argc, char **argv) rc.rc_cap[RUNCAP_STDOUT].sc_linemon = linemon; - rc.rc_cap[RUNCAP_STDOUT].sc_monarg = "stdout"; + rc.rc_cap[RUNCAP_STDOUT].sc_monarg = + &cl[RUNCAP_STDOUT-1]; rcf |= RCF_STDOUT_LINEMON; @@ -196,3 +211,4 @@ main(int argc, char **argv) rc.rc_cap[RUNCAP_STDERR].sc_linemon = linemon; - rc.rc_cap[RUNCAP_STDERR].sc_monarg = "stderr"; + rc.rc_cap[RUNCAP_STDERR].sc_monarg = + &cl[RUNCAP_STDERR-1]; rcf |= RCF_STDERR_LINEMON; |