File Coverage

Pipe.xs
Criterion Covered Total %
statement 21 22 95.4
total 21 22 95.4


line stmt code
1   #define PERL_NO_GET_CONTEXT
2    
3   #include "EXTERN.h"
4   #include "perl.h"
5   #include "XSUB.h"
6    
7   #include "ppport.h"
8    
9   #include
10   #include
11    
12   #include
13    
14   // CopSTASH isn’t documented as part of the API but is heavily used
15   // on CPAN. There is PL_curstash, but that doesn’t work with, e.g.,
16   // “perl -e'package Foo; _print_pl_curstash()'”, whereas PL_curcop does.
17   #define SP_CUR_STASH ( (HV*)CopSTASH(PL_curcop) )
18    
19   #define SP_CUR_PKGNAME HvNAME( SP_CUR_STASH )
20    
21   //----------------------------------------------------------------------
22    
23 6 static inline void _fd2sv( pTHX_ int fd, bool is_read, SV* sv ) {
24 6 PerlIO *pio = PerlIO_fdopen(fd, is_read ? "r" : "w");
25    
26 6 GV* gv = newGVgen( SP_CUR_PKGNAME );
27 6 IO* io = GvIOn(gv);
28    
29 6 SvUPGRADE(sv, SVt_IV);
30 6 SvROK_on(sv);
31 6 SvRV_set(sv, (SV*)gv);
32    
33 6 IoTYPE(io) = is_read ? '<' : '>';
34 6 IoIFP(io) = pio;
35 6 IoOFP(io) = pio;
36 6 }
37    
38 3 int _sp_pipe( pTHX_ SV* infh, SV* outfh, int flags ) {
39   int fds[2];
40    
41   // This macro comes from Makefile.PL:
42   #ifdef SP_HAS_PIPE2
43 3 int ret = pipe2(fds, flags);
44   #else
45   if (flags != 0) {
46   croak("This system lacks pipe2 support, so pipe() cannot accept flags.");
47   }
48    
49   int ret = pipe(fds);
50   #endif
51    
52 3 if (!ret) {
53    
54   // These don’t seem to be available to extensions,
55   // but apparently they’re unneeded anyway.
56   //
57   // Perl_setfd_cloexec_for_nonsysfd(fds[0]);
58   // Perl_setfd_cloexec_for_nonsysfd(fds[1]);
59    
60 3 _fd2sv( aTHX_ fds[0], true, infh );
61 3 _fd2sv( aTHX_ fds[1], false, outfh );
62   }
63    
64 3 return ret;
65   }
66    
67   //----------------------------------------------------------------------
68   //----------------------------------------------------------------------
69    
70   MODULE = Sys::Pipe PACKAGE = Sys::Pipe
71    
72   PROTOTYPES: DISABLE
73    
74   BOOT:
75 2 HV *stash = gv_stashpv("Sys::Pipe", FALSE);
76 2 newCONSTSUB(stash, "has_pipe2", newSVuv(
77   #if SP_HAS_PIPE2
78   1
79   #else
80   0
81   #endif
82   ));
83    
84   SV*
85   pipe( SV *infh, SV *outfh, int flags = 0 )
86   CODE:
87 3 if (_sp_pipe(aTHX_ infh, outfh, flags)) {
88 0 RETVAL = &PL_sv_undef;
89   }
90   else {
91 3 RETVAL = newSVuv(1);
92   }
93    
94   OUTPUT:
95   RETVAL
96