aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-07-21 18:34:23 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2017-07-21 18:50:53 +0300
commit969dab4c1af666d381124fd481821bc936fc94ed (patch)
treeb7bc4b2e75b8cc3f64e240162f3bedff23e9c58b
parent0c0ae29bc7a71fc2cb6d0acf403b1e72715fbe48 (diff)
downloadruncap-969dab4c1af666d381124fd481821bc936fc94ed.tar.gz
runcap-969dab4c1af666d381124fd481821bc936fc94ed.tar.bz2
Fix tell/seek operations
* Makefile (clean): descend into t as well. * t/Makefile (clean): New goal. * runcap.h (runcap_seek): Return off_t. * seek.c (runcap_seek): Change return value. Fix operation. * tell.c (runcap_tell): Bugfix. * t/rt.c: New option -r for testing seek. * t/08seek.t: New testcase. * t/09seek.t: New testcase.
-rw-r--r--Makefile5
-rw-r--r--runcap.h4
-rw-r--r--seek.c10
-rwxr-xr-xt/08seek.t43
-rwxr-xr-xt/09seek.t44
-rw-r--r--t/Makefile11
-rw-r--r--t/rt.c113
-rw-r--r--tell.c1
8 files changed, 218 insertions, 13 deletions
diff --git a/Makefile b/Makefile
index e0a8f06..47bcf17 100644
--- a/Makefile
+++ b/Makefile
@@ -53,5 +53,8 @@ libruncap.a: $(OBJECTS)
-clean:
+clean: subdirs-clean
rm -f libruncap.a $(OBJECTS)
+subdirs-clean:
+ @$(MAKE) -C t clean
+
install: install-lib install-headers install-man
diff --git a/runcap.h b/runcap.h
index 3ed907d..0ece8e7 100644
--- a/runcap.h
+++ b/runcap.h
@@ -92,3 +92,3 @@ ssize_t runcap_getline(struct runcap *rc, int stream, char **pstr, size_t *psize
off_t runcap_tell(struct runcap *rc, int stream);
-int runcap_seek(struct runcap *rc, int stream, off_t off, int whence);
+off_t runcap_seek(struct runcap *rc, int stream, off_t off, int whence);
@@ -97,3 +97,3 @@ runcap_rewind(struct runcap *rc, int stream)
{
- return runcap_seek(rc, stream, 0, 0);
+ return runcap_seek(rc, stream, 0, 0) != 0;
}
diff --git a/seek.c b/seek.c
index dfa3d1d..acb42e9 100644
--- a/seek.c
+++ b/seek.c
@@ -21,3 +21,3 @@
-int
+off_t
runcap_seek(struct runcap *rc, int sd, off_t off, int whence)
@@ -34,3 +34,3 @@ runcap_seek(struct runcap *rc, int sd, off_t off, int whence)
case SEEK_CUR:
- off = cur;
+ off = cur + off;
break;
@@ -54,4 +54,4 @@ runcap_seek(struct runcap *rc, int sd, off_t off, int whence)
- cur -= cap->sc_level;
-
+ cur -= cap->sc_cur;
+
if (cur <= off && off <= cur + cap->sc_level) {
@@ -67,3 +67,3 @@ runcap_seek(struct runcap *rc, int sd, off_t off, int whence)
}
- return 0;
+ return off;
}
diff --git a/t/08seek.t b/t/08seek.t
new file mode 100755
index 0000000..c2312bd
--- /dev/null
+++ b/t/08seek.t
@@ -0,0 +1,43 @@
+#! ./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 seek
+
+TC_EXPECT out <<EOT
+res=0
+exit code: 0
+stdout: 71 lines, 4051 bytes
+stderr: 0 lines, 0 bytes
+READ 0:
+ the Rabbit-Hole
+
+Alice was beginning to get very tired of sitting by her sister on the
+bank, and of
+READ 1:
+ on the
+ba
+READ 2:
+nk, and of
+READ 3:
+tten up so
+EOT
+
+rt -r stdout:100:15:0\
+ -r stdout:10:-20:1\
+ -r stdout:10:0:1\
+ -r stdout:10:-20:2\
+ -- genout $testdir/INPUT
diff --git a/t/09seek.t b/t/09seek.t
new file mode 100755
index 0000000..87628f1
--- /dev/null
+++ b/t/09seek.t
@@ -0,0 +1,44 @@
+#! ./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 seek, short buffer
+
+TC_EXPECT out <<EOT
+res=0
+exit code: 0
+stdout: 71 lines, 4051 bytes
+stderr: 0 lines, 0 bytes
+READ 0:
+ the Rabbit-Hole
+
+Alice was beginning to get very tired of sitting by her sister on the
+bank, and of
+READ 1:
+ on the
+ba
+READ 2:
+nk, and of
+READ 3:
+tten up so
+EOT
+
+rt -s 16\
+ -r stdout:100:15:0\
+ -r stdout:10:-20:1\
+ -r stdout:10:0:1\
+ -r stdout:10:-20:2\
+ -- genout $testdir/INPUT
diff --git a/t/Makefile b/t/Makefile
index c24d98e..7a3bb62 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -16,3 +16,4 @@
-check: genout rt
+TESTPROGS=genout rt
+check: $(TESTPROGS)
@./testsuite
@@ -39,3 +40,5 @@ TESTSUITE =\
05stdin.t\
- 06mon.t
+ 06mon.t\
+ 08seek.t\
+ 09seek.t
@@ -44,3 +47,3 @@ DISTDIR = $(TOPDISTDIR)/t
DISTFILES = Makefile rt.c genout.c $(TESTSUITE) INPUT
-.PHONY: distdir
+.PHONY: distdir clean
distdir:
@@ -49 +52,3 @@ distdir:
+clean:
+ rm -rf $(TESTPROGS) testsuite.log testsuite.dir
diff --git a/t/rt.c b/t/rt.c
index 9dbbfa8..12a3232 100644
--- a/t/rt.c
+++ b/t/rt.c
@@ -52,4 +52,9 @@ usage(int code)
fprintf(fp, " -i inline read (use before -f)\n");
+ fprintf(fp, " -n all|stderr|stdout print lines from the requested capture\n");
fprintf(fp, " -m monitors each line recevied from the program (see -S)\n");
fprintf(fp, " -p PROGNAME sets program name to use instead of COMMAND\n");
+ fprintf(fp, " -r STREAM[:COUNT:OFF:WHENCE]\n");
+ fprintf(fp, " read and print COUNT bytes from STREAM (stdout or\n");
+ fprintf(fp, " stderr) starting from OFFset located using WHENCE\n");
+ fprintf(fp, " (0, 1, 2).\n");
fprintf(fp, " -s SIZE sets capture size (see -S)\n");
@@ -121,2 +126,90 @@ nl(struct runcap *rc, int stream)
+struct readreq
+{
+ int what;
+ unsigned long count;
+ long off;
+ int whence;
+};
+
+void
+readreq_parse(struct readreq *req, char *arg)
+{
+ char *s;
+ int i = 0;
+
+ s = strchr(arg, ':');
+ if (s)
+ *s = 0;
+ req->what = whatarg(arg);
+ req->count = 0;
+ req->off = 0;
+ req->whence = 0;
+ if (s)
+ *s++ = ':';
+
+ arg = s;
+ while (*arg) {
+ switch (i++) {
+ case 0:
+ req->count = strtoul(arg, &s, 10);
+ break;
+
+ case 1:
+ req->off = strtol(arg, &s, 10);
+ break;
+
+ case 2:
+ req->whence = strtol(arg, &s, 10);
+ if (!(0 <= req->whence && req->whence <= 2)) {
+ error("bad whence: %s", arg);
+ exit(1);
+ }
+ break;
+
+ default:
+ error("too many parts in argument: %s", arg);
+ exit(1);
+ }
+
+ if (*s == ':')
+ arg = s + 1;
+ else if (*s) {
+ error("malformed argument: %s", arg);
+ exit(1);
+ } else
+ arg = s;
+ }
+}
+
+void
+readreq_do(struct runcap *rc, struct readreq *req)
+{
+ int res;
+ size_t i;
+
+ if (runcap_seek(rc, req->what, req->off, req->whence) == -1) {
+ perror("runcap_seek");
+ exit(1);
+ }
+
+ if (req->count == 0)
+ req->count = rc->rc_cap[req->what].sc_size;
+
+ for (i = 0; i < req->count; i++) {
+ char c;
+
+ res = runcap_getc(rc, req->what, &c);
+ if (res == 0) {
+ error("unexpected eof at byte %zu\n", i);
+ break;
+ }
+ if (res == -1) {
+ error("%s at byte %zu\n", strerror (errno), i);
+ break;
+ }
+ putchar(c);
+ }
+}
+
int
@@ -129,2 +222,4 @@ main(int argc, char **argv)
int numlines = WA_NONE;
+ struct readreq rq[10];
+ int rqn = 0, i;
@@ -144,3 +239,3 @@ main(int argc, char **argv)
progname = argv[0];
- while ((c = getopt(argc, argv, "?f:in:mp:S:s:t:")) != EOF) {
+ while ((c = getopt(argc, argv, "?f:in:mp:r:S:s:t:")) != EOF) {
switch (c) {
@@ -202,2 +297,10 @@ main(int argc, char **argv)
break;
+ case 'r':
+ /* -r WHAT:N[:OFF:WHENCE] */
+ if (rqn == sizeof(rq)/sizeof(rq[0])) {
+ error("too many read requests");
+ break;
+ }
+ readreq_parse(&rq[rqn++], optarg);
+ break;
case 'm':
@@ -279,3 +382,9 @@ main(int argc, char **argv)
nl(&rc, RUNCAP_STDERR);
-
+
+ for (i = 0; i < rqn; i++) {
+ printf("READ %d:\n", i);
+ readreq_do(&rc, &rq[i]);
+ putchar('\n');
+ }
+
return 0;
diff --git a/tell.c b/tell.c
index d16110c..337e990 100644
--- a/tell.c
+++ b/tell.c
@@ -35,2 +35,3 @@ runcap_tell(struct runcap *rc, int sd)
return -1;
+ off -= cap->sc_level;
} else

Return to:

Send suggestions and report system problems to the System administrator.