diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-07-22 14:50:01 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-07-22 15:13:57 +0300 |
commit | 7f5cbd2332df055d8b9e365974f8743f82ad4886 (patch) | |
tree | 45a320169d046f5c2ae1ac533c7d9f916ab35608 /capture.c | |
parent | 970d2e1f1c540b94443456bbdf1a8d315401b188 (diff) | |
download | posixruncapture-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.c | 57 |
1 files changed, 55 insertions, 2 deletions
@@ -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); |