aboutsummaryrefslogtreecommitdiff
path: root/Capture.xs
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-07-21 13:25:07 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2017-07-21 13:33:04 +0300
commitec78df167efca7feba360b29700ef052eccf4b69 (patch)
tree1bcad85c0bc4696c0d87b45faefb9f00daef01cb /Capture.xs
parent9565c4d075158f27b5bfd6eab500f0e3f6d8c9ed (diff)
downloadposixruncapture-ec78df167efca7feba360b29700ef052eccf4b69.tar.gz
posixruncapture-ec78df167efca7feba360b29700ef052eccf4b69.tar.bz2
Improve constructor calling convention; implement timeout and line monitoring
* Capture.xs: Rewrite constructor to optionally take named arguments. * Makefile.PL: Remove 'subdirs-test_.*' rules. * capture.h (capture): New structure. All capture_ functions operate on it. * capture.c (capture_new): Change signature. Set line monitoring features if required. (capture_DESTROY): Free line buffers and dereference callback references. * lib/POSIX/Run/Capture.pm: Fix trivial error (get_lines): New method.
Diffstat (limited to 'Capture.xs')
-rw-r--r--Capture.xs112
1 files changed, 85 insertions, 27 deletions
diff --git a/Capture.xs b/Capture.xs
index ac80697..df47544 100644
--- a/Capture.xs
+++ b/Capture.xs
@@ -3,72 +3,130 @@
MODULE = POSIX::Run::Capture PACKAGE = POSIX::Run::Capture PREFIX = capture_
PROTOTYPES: ENABLE
+=head2 new POSIX::Run::Capture
+
+ new POSIX::Run::Capture([ $command, @args ]);
+
+ new POSIX::Run::Capture(argv => [ $command, @args ],
+ stdout => sub { ... },
+ stderr => sub { ... },
+ timeout => N)
+
+
+=cut
+
POSIX::Run::Capture
-capture_new(package, argv)
+capture_new(package, ...)
char *package;
- AV *argv;
+ PREINIT:
+ AV *argv = NULL;
+ unsigned timeout = 0;
+ SV *cb[2] = { &PL_sv_undef, &PL_sv_undef };
CODE:
- RETVAL = capture_new(argv);
+ if (items == 2) {
+ SV *sv = ST(1);
+ if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVAV) {
+ argv = (AV*) SvRV(sv);
+ } else
+ croak("single argument must be an array ref");
+ } else if (items % 2 == 0)
+ croak("Bad number of arguments");
+ else {
+ int i;
+ for (i = 1; i < items; i += 2) {
+ char *kw;
+ SV *sv = ST(i);
+ SV *val = ST(i+1);
+
+ if (!SvPOK(sv))
+ croak("bad arguments near #%d", i);
+ kw = SvPV_nolen(sv);
+ if (strcmp(kw, "argv") == 0) {
+ if (SvROK(val)
+ && SvTYPE(SvRV(val)) == SVt_PVAV) {
+ argv = (AV*) SvRV(val);
+ } else
+ croak("argv must be an array ref");
+ } else if (strcmp(kw, "stdout") == 0
+ || strcmp(kw, "stderr") == 0) {
+ if (SvROK(val)
+ && SvTYPE(SvRV(val)) == SVt_PVCV) {
+ cb[kw[3] == 'o' ? 0 : 1] = SvRV(val);
+ } else
+ croak("%s must be a code ref", kw);
+ } else if (strcmp(kw, "timeout") == 0) {
+ if (SvIOK(val)) {
+ timeout = SvUV(val);
+ } else
+ croak("timeout must be a number of seconds");
+ } else
+ croak("unknown keyword argument %s", kw);
+ }
+ }
+ if (!argv)
+ croak("argv not defined");
+ RETVAL = capture_new(argv, timeout, cb);
if (!RETVAL)
croak("Out of memory!");
OUTPUT:
RETVAL
void
-capture_DESTROY(rc)
- POSIX::Run::Capture rc;
+capture_DESTROY(cp)
+ POSIX::Run::Capture cp;
int
-capture_run(rc)
- POSIX::Run::Capture rc;
- CODE:
- if (!rc->rc_argv)
- croak("no command line given");
- RETVAL = runcap(rc, 0);
- OUTPUT:
- RETVAL
+capture_run(cp)
+ POSIX::Run::Capture cp;
int
-capture_status(rc)
- POSIX::Run::Capture rc;
+capture_status(cp)
+ POSIX::Run::Capture cp;
CODE:
- RETVAL = rc->rc_status;
+ RETVAL = cp->rc.rc_status;
OUTPUT:
RETVAL
int
-capture_errno(rc)
- POSIX::Run::Capture rc;
+capture_errno(cp)
+ POSIX::Run::Capture cp;
CODE:
- RETVAL = rc->rc_errno;
+ RETVAL = cp->rc.rc_errno;
OUTPUT:
RETVAL
size_t
-capture_nlines(rc, n)
- POSIX::Run::Capture rc;
+capture_nlines(cp, n)
+ POSIX::Run::Capture cp;
int n;
CODE:
if (n != RUNCAP_STDOUT && n != RUNCAP_STDERR) {
croak("invalid stream number: %d", n);
}
- RETVAL = rc->rc_cap[n].sc_nlines;
+ RETVAL = cp->rc.rc_cap[n].sc_nlines;
OUTPUT:
RETVAL
size_t
-capture_length(rc, n)
- POSIX::Run::Capture rc;
+capture_length(cp, n)
+ POSIX::Run::Capture cp;
int n;
CODE:
if (n != RUNCAP_STDOUT && n != RUNCAP_STDERR) {
croak("invalid stream number: %d", n);
}
- RETVAL = rc->rc_cap[n].sc_leng;
+ RETVAL = cp->rc.rc_cap[n].sc_leng;
OUTPUT:
RETVAL
char *
-capture_next_line(rc, n)
- POSIX::Run::Capture rc;
+capture_next_line(cp, n)
+ POSIX::Run::Capture cp;
+ int n;
+
+void
+capture_rewind(cp, n)
+ POSIX::Run::Capture cp;
int n;
+ CODE:
+ runcap_rewind(&cp->rc, n);

Return to:

Send suggestions and report system problems to the System administrator.