aboutsummaryrefslogtreecommitdiff
path: root/read.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2019-08-17 11:14:43 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2019-08-17 11:15:18 +0300
commit9faece352b572fd65e4579e178c4df8fc0c53c35 (patch)
tree0630ccb0804719a174de7c95e4e0c6972b3c34ea /read.c
parent12c5eac517cb62728b5525cab25aff245086525c (diff)
downloadruncap-1.2.tar.gz
runcap-1.2.tar.bz2
Implement runcap_read functionv1.2
* Make.am (RUNCAP_SRC): Add read.c * read.c: New file * runcap.h (runcap_read): New proto. * t/rt: Expand read request to include a flag for selecting * t/read.at: New file. * t/nocap.at: New file * t/nocap00.at: Remove. * t/nocap01.at: Remove. * t/Makefile.am (TESTSUITE_AT): Add new test. Merge two nocap tests to one. * t/testsuite.at: Likewise.
Diffstat (limited to 'read.c')
-rw-r--r--read.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/read.c b/read.c
new file mode 100644
index 0000000..a57d9b9
--- /dev/null
+++ b/read.c
@@ -0,0 +1,69 @@
+/* runcap - run program and capture its output
+ Copyright (C) 2019 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/>. */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include "runcap.h"
+
+ssize_t
+runcap_read(struct runcap *rc, int sd, char *buf, size_t size)
+{
+ struct stream_capture *cap;
+ ssize_t nread = 0;
+
+ if (!buf) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (size == 0)
+ return 0;
+
+ cap = runcap_get_capture(rc, sd);
+ if (!cap)
+ return -1;
+
+ while (size) {
+ size_t avail = cap->sc_level - cap->sc_cur;
+ if (avail == 0) {
+ if (cap->sc_storfd != -1) {
+ ssize_t r = read(cap->sc_storfd,
+ cap->sc_base,
+ cap->sc_size);
+ if (r < 0)
+ return -1;
+ else if (r == 0)
+ break;
+ avail = r;
+ cap->sc_level = r;
+ cap->sc_cur = 0;
+ } else {
+ break;
+ }
+ }
+
+ if (avail > size)
+ avail = size;
+ memcpy(buf + nread, cap->sc_base + cap->sc_cur, avail);
+
+ cap->sc_cur += avail;
+ nread += avail;
+ size -= avail;
+ }
+
+ return nread;
+}

Return to:

Send suggestions and report system problems to the System administrator.