diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-07-21 13:25:07 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-07-21 13:33:04 +0300 |
commit | ec78df167efca7feba360b29700ef052eccf4b69 (patch) | |
tree | 1bcad85c0bc4696c0d87b45faefb9f00daef01cb /Capture.xs | |
parent | 9565c4d075158f27b5bfd6eab500f0e3f6d8c9ed (diff) | |
download | posixruncapture-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.xs | 112 |
1 files changed, 85 insertions, 27 deletions
@@ -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); |