aboutsummaryrefslogtreecommitdiff
path: root/capture.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-07-22 14:50:01 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2017-07-22 15:13:57 +0300
commit7f5cbd2332df055d8b9e365974f8743f82ad4886 (patch)
tree45a320169d046f5c2ae1ac533c7d9f916ab35608 /capture.c
parent970d2e1f1c540b94443456bbdf1a8d315401b188 (diff)
downloadposixruncapture-7f5cbd2332df055d8b9e365974f8743f82ad4886.tar.gz
posixruncapture-7f5cbd2332df055d8b9e365974f8743f82ad4886.tar.bz2
Implement "input" key and set_input method.
* Capture.xs (capture_new): New keyword "input". (capture_set_input): New method. * MANIFEST: Update. * Makefile.PL: Add the 'check' goal (alias to 'test'). * capture.c (capture_new): Take input SV as 5th parameter. (capture_set_input): New function. (capture_DESTROY): Dereference input, if defined. * capture.h (capture) <input>: New method. (capture_new): Change signature. * t/08input.t: New file. * t/TestCapture.pm: Read content in BEGIN block, instead of hardcoding it. (TestCapture): $argv can be a hash or array ref. All uses changed.
Diffstat (limited to 'capture.c')
-rw-r--r--capture.c57
1 files changed, 55 insertions, 2 deletions
diff --git a/capture.c b/capture.c
index 471b2bf..67f2bcd 100644
--- a/capture.c
+++ b/capture.c
@@ -115,7 +115,7 @@ free_argv(struct capture *cp)
}
struct capture *
-capture_new(SV *program, ARGV argv, unsigned timeout, SV *cb[2])
+capture_new(SV *program, ARGV argv, unsigned timeout, SV *cb[2], SV *input)
{
struct capture *cp;
I32 i, n;
@@ -126,7 +126,7 @@ capture_new(SV *program, ARGV argv, unsigned timeout, SV *cb[2])
memset(cp, 0, sizeof *cp);
cp->rc.rc_argv = argv;
-
+
cp->program = program;
if (program != &PL_sv_undef) {
SvREFCNT_inc(program);
@@ -155,6 +155,9 @@ capture_new(SV *program, ARGV argv, unsigned timeout, SV *cb[2])
cp->rc.rc_cap[RUNCAP_STDERR].sc_monarg = &cp->closure[1];
cp->flags |= RCF_STDOUT_LINEMON;
}
+
+ cp->input = &PL_sv_undef;
+ capture_set_input(cp, input);
return cp;
}
@@ -169,6 +172,8 @@ capture_DESTROY(struct capture *cp)
if (cp->program != &PL_sv_undef)
SvREFCNT_dec(cp->program);
+ if (cp->input != &PL_sv_undef)
+ SvREFCNT_dec(cp->input);
if (cp->closure[0].cv != &PL_sv_undef)
SvREFCNT_dec(cp->closure[0].cv);
@@ -180,6 +185,54 @@ capture_DESTROY(struct capture *cp)
}
void
+capture_set_input(struct capture *cp, SV *inp)
+{
+ if (cp->flags & RCF_STDIN) {
+ cp->flags &= ~RCF_STDIN;
+ if (cp->input != &PL_sv_undef) {
+ SvREFCNT_dec(cp->input);
+ cp->input = &PL_sv_undef;
+ if (cp->rc.rc_cap[0].sc_base) {
+ free(cp->rc.rc_cap[0].sc_base);
+ cp->rc.rc_cap[0].sc_base = NULL;
+ }
+ }
+ }
+ if (inp != &PL_sv_undef) {
+ if (SvROK(inp)) {
+ if (SvTYPE(SvRV(inp)) == SVt_PVGV) {
+ PerlIO *fh = IoIFP(sv_2io(inp));
+ PerlIO_flush(fh);
+ PerlIO_rewind(fh);
+ cp->rc.rc_cap[0].sc_fd = PerlIO_fileno(fh);
+ if (cp->rc.rc_cap[0].sc_fd == -1)
+ croak("no file descriptor associated to hanlde");
+ cp->rc.rc_cap[0].sc_base = NULL;
+ cp->rc.rc_cap[0].sc_size = 0;
+ } else {
+ croak("argument must be a string or file handle");
+ }
+ } else {
+ char *s = SvPV(inp, cp->rc.rc_cap[0].sc_size);
+
+ /* FIXME: Unnecessary allocation due to a design flow
+ in runcap */
+ cp->rc.rc_cap[0].sc_base
+ = malloc(cp->rc.rc_cap[0].sc_size);
+ if (!cp->rc.rc_cap[0].sc_base)
+ croak_nomem();
+ memcpy(cp->rc.rc_cap[0].sc_base, s,
+ cp->rc.rc_cap[0].sc_size);
+
+ cp->rc.rc_cap[0].sc_fd = -1;
+ }
+ SvREFCNT_inc(inp);
+ cp->input = inp;
+ cp->flags |= RCF_STDIN;
+ }
+}
+
+void
capture_set_argv_ref(struct capture *cp, ARGV argv)
{
free_argv(cp);

Return to:

Send suggestions and report system problems to the System administrator.