File Coverage

Clone.xs
Criterion Covered Total %
statement 3 38 7.8
branch 2 58 3.4
condition n/a
subroutine n/a
pod n/a
total 5 96 5.2


line stmt bran cond sub pod time code
1             #include "EXTERN.h"
2             #include "perl.h"
3             #include "XSUB.h"
4              
5             #include
6             #include
7              
8             #undef _GNU_SOURCE
9             #define _GNU_SOURCE
10             #include
11             #include
12             #include
13              
14             #ifdef __has_include
15             #if !__has_include("linux/kcmp.h") // use "" as GCC wrongly expands macros
16             #undef SYS_kcmp
17             #endif
18             #endif
19              
20             #ifdef SYS_kcmp
21             #include "linux/kcmp.h"
22             #define kcmp(pid1,pid2,type,idx1,idx2) \
23             syscall (SYS_kcmp, (pid_t)pid1, (pid_t)pid2, \
24             (int)type, (unsigned long)idx1, (unsigned long)idx2)
25             #else
26             #define kcmp(pid1,pid2,type,idx1,idx2) \
27             (errno = ENOSYS, -1)
28             #endif
29              
30             /* from schmorp.h */
31             static int
32 0           s_fileno (SV *fh, int wr)
33             {
34             dTHX;
35 0 0         SvGETMAGIC (fh);
    0          
36              
37 0 0         if (SvROK (fh))
38             {
39 0           fh = SvRV (fh);
40 0 0         SvGETMAGIC (fh);
    0          
41             }
42              
43 0 0         if (SvTYPE (fh) == SVt_PVGV)
44 0 0         return PerlIO_fileno (wr ? IoOFP (sv_2io (fh)) : IoIFP (sv_2io (fh)));
45              
46 0 0         if (SvOK (fh) && (SvIV (fh) >= 0) && (SvIV (fh) < 0x7fffffffL))
    0          
    0          
    0          
    0          
    0          
    0          
47 0 0         return SvIV (fh);
48              
49 0           return -1;
50             }
51              
52             static int
53 0           clone_cb (void *arg)
54             {
55 0           dSP;
56              
57 0 0         PUSHMARK (SP);
58              
59 0           PUTBACK;
60 0           int count = call_sv (sv_2mortal ((SV *)arg), G_SCALAR);
61 0           SPAGAIN;
62 0 0         int retval = count ? SvIV (POPs) : 0;
    0          
63 0           PUTBACK;
64              
65 0           return retval;
66             }
67              
68             MODULE = Linux::Clone PACKAGE = Linux::Clone
69              
70             PROTOTYPES: ENABLE
71              
72             BOOT:
73 1           HV *stash = gv_stashpv ("Linux::Clone", 1);
74              
75             static const struct {
76             const char *name;
77             IV iv;
78             } *civ, const_iv[] = {
79             # define const_iv(name) { # name, (IV)name },
80             # define const_iv_clone(name) { # name, (IV) CLONE_ ## name },
81             # ifdef CLONE_FILES
82             const_iv_clone (FILES)
83             # endif
84             # ifdef CLONE_FS
85             const_iv_clone (FS)
86             # endif
87             # ifdef CLONE_NEWNS
88             const_iv_clone (NEWNS)
89             # endif
90             # ifdef CLONE_VM
91             const_iv_clone (VM)
92             # endif
93             # ifdef CLONE_THREAD
94             const_iv_clone (THREAD)
95             # endif
96             # ifdef CLONE_SIGHAND
97             const_iv_clone (SIGHAND)
98             # endif
99             # ifdef CLONE_SYSVSEM
100             const_iv_clone (SYSVSEM)
101             # endif
102             # ifdef CLONE_NEWUTS
103             const_iv_clone (NEWUTS)
104             # endif
105             # ifdef CLONE_NEWIPC
106             const_iv_clone (NEWIPC)
107             # endif
108             # ifdef CLONE_NEWNET
109             const_iv_clone (NEWNET)
110             # endif
111             # ifdef CLONE_PTRACE
112             const_iv_clone (PTRACE)
113             # endif
114             # ifdef CLONE_VFORK
115             const_iv_clone (VFORK)
116             # endif
117             # ifdef CLONE_SETTLS
118             const_iv_clone (SETTLS)
119             # endif
120             # ifdef CLONE_PARENT_SETTID
121             const_iv_clone (PARENT_SETTID)
122             # endif
123             # ifdef CLONE_CHILD_CLEARTID
124             const_iv_clone (CHILD_CLEARTID)
125             # endif
126             # ifdef CLONE_DETACHED
127             const_iv_clone (DETACHED)
128             # endif
129             # ifdef CLONE_UNTRACED
130             const_iv_clone (UNTRACED)
131             # endif
132             # ifdef CLONE_CHILD_SETTID
133             const_iv_clone (CHILD_SETTID)
134             # endif
135             # ifdef CLONE_NEWUSER
136             const_iv_clone (NEWUSER)
137             # endif
138             # ifdef CLONE_NEWPID
139             const_iv_clone (NEWPID)
140             # endif
141             # ifdef CLONE_IO
142             const_iv_clone (IO)
143             # endif
144             # ifdef CLONE_NEWCGROUP
145             const_iv_clone (NEWCGROUP)
146             # endif
147             # ifdef SYS_kcmp
148             const_iv (KCMP_FILE)
149             const_iv (KCMP_VM)
150             const_iv (KCMP_FILES)
151             const_iv (KCMP_FS)
152             const_iv (KCMP_SIGHAND)
153             const_iv (KCMP_IO)
154             const_iv (KCMP_SYSVSEM)
155             const_iv (KCMP_FILE)
156             # endif
157             };
158              
159 30 100         for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
160 29           newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
161              
162             int
163             clone (SV *sub, IV stacksize, int flags, SV *ptid = 0, SV *tls = &PL_sv_undef)
164             CODE:
165             {
166 0 0         if (!stacksize)
167 0           stacksize = 4 << 20;
168              
169             pid_t ptid_;
170 0           char *stack_ptr = mmap (0, stacksize, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN | MAP_STACK, -1, 0);
171              
172 0           #ifndef __hppa
173             stack_ptr += stacksize - 16; /* be safe and put the sp at 16 bytes below the end */
174 0           #endif
175 0 0          
176             RETVAL = -1;
177 0           if (stack_ptr != (void *)-1)
178             {
179 0 0         SV *my_sub = newSVsv (sub);
    0          
    0          
    0          
180            
181 0 0         RETVAL = clone (clone_cb, (void *)stack_ptr, flags, (void *)my_sub, &ptid, SvOK (tls) ? SvPV_nolen (tls) : 0, 0);
182              
183 0 0         if (ptid) sv_setiv (ptid, (IV)ptid_);
184              
185 0           if ((flags & (CLONE_VM | CLONE_VFORK)) != CLONE_VM)
186 0           {
187 0           int old_errno = errno;
188             munmap (stack_ptr, stacksize);
189             errno = old_errno;
190             }
191             }
192             }
193             OUTPUT:
194             RETVAL
195              
196             int
197             unshare (int flags)
198              
199             int
200             setns (SV *fh_or_fd, int nstype = 0)
201             C_ARGS: s_fileno (fh_or_fd, 0), nstype
202              
203             int
204             pivot_root (SV *new_root, SV *old_root)
205             CODE:
206 0 0         RETVAL = syscall (SYS_pivot_root,
    0          
207 0           (const char *)SvPVbyte_nolen (new_root),
208 0           (const char *)SvPVbyte_nolen (old_root));
209             OUTPUT:
210             RETVAL
211              
212             int
213             kcmp (IV pid1, IV pid2, IV type, UV idx1 = 0, UV idx2 = 0)
214