ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Linux-Clone/Clone.xs
Revision: 1.2
Committed: Wed Aug 24 03:34:24 2016 UTC (7 years, 8 months ago) by root
Branch: MAIN
CVS Tags: rel-1_0
Changes since 1.1: +32 -8 lines
Log Message:
1.0

File Contents

# User Rev Content
1 root 1.1 #include "EXTERN.h"
2     #include "perl.h"
3     #include "XSUB.h"
4    
5     #include <sys/errno.h>
6     #include <sys/mman.h>
7    
8     #undef _GNU_SOURCE
9     #define _GNU_SOURCE
10     #include <sched.h>
11    
12 root 1.2 /* from schmorp.h */
13     static int
14     s_fileno (SV *fh, int wr)
15     {
16     dTHX;
17     SvGETMAGIC (fh);
18    
19     if (SvROK (fh))
20     {
21     fh = SvRV (fh);
22     SvGETMAGIC (fh);
23     }
24    
25     if (SvTYPE (fh) == SVt_PVGV)
26     return PerlIO_fileno (wr ? IoOFP (sv_2io (fh)) : IoIFP (sv_2io (fh)));
27    
28     if (SvOK (fh) && (SvIV (fh) >= 0) && (SvIV (fh) < 0x7fffffffL))
29     return SvIV (fh);
30    
31     return -1;
32     }
33    
34 root 1.1 static int
35     clone_cb (void *arg)
36     {
37     dSP;
38    
39     PUSHMARK (SP);
40    
41     PUTBACK;
42     int count = call_sv (sv_2mortal ((SV *)arg), G_SCALAR);
43     SPAGAIN;
44     int retval = count ? SvIV (POPs) : 0;
45     PUTBACK;
46    
47     return retval;
48     }
49    
50     MODULE = Linux::Clone PACKAGE = Linux::Clone
51    
52     PROTOTYPES: ENABLE
53    
54     BOOT:
55     HV *stash = gv_stashpv ("Linux::Clone", 1);
56    
57     static const struct {
58     const char *name;
59     IV iv;
60     } *civ, const_iv[] = {
61     # define const_iv(name) { # name, (IV) CLONE_ ## name },
62     # ifdef CLONE_FILES
63     const_iv (FILES)
64     # endif
65     # ifdef CLONE_FS
66     const_iv (FS)
67     # endif
68     # ifdef CLONE_NEWNS
69     const_iv (NEWNS)
70     # endif
71     # ifdef CLONE_VM
72     const_iv (VM)
73     # endif
74     # ifdef CLONE_THREAD
75     const_iv (THREAD)
76     # endif
77     # ifdef CLONE_SIGHAND
78     const_iv (SIGHAND)
79     # endif
80     # ifdef CLONE_SYSVSEM
81     const_iv (SYSVSEM)
82     # endif
83     # ifdef CLONE_NEWUTS
84     const_iv (NEWUTS)
85     # endif
86     # ifdef CLONE_NEWIPC
87     const_iv (NEWIPC)
88     # endif
89     # ifdef CLONE_NEWNET
90     const_iv (NEWNET)
91     # endif
92     # ifdef CLONE_PTRACE
93     const_iv (PTRACE)
94     # endif
95     # ifdef CLONE_VFORK
96     const_iv (VFORK)
97     # endif
98     # ifdef CLONE_SETTLS
99     const_iv (SETTLS)
100     # endif
101     # ifdef CLONE_PARENT_SETTID
102     const_iv (PARENT_SETTID)
103     # endif
104     # ifdef CLONE_CHILD_CLEARTID
105     const_iv (CHILD_CLEARTID)
106     # endif
107     # ifdef CLONE_DETACHED
108     const_iv (DETACHED)
109     # endif
110     # ifdef CLONE_UNTRACED
111     const_iv (UNTRACED)
112     # endif
113     # ifdef CLONE_CHILD_SETTID
114     const_iv (CHILD_SETTID)
115     # endif
116     # ifdef CLONE_NEWUSER
117     const_iv (NEWUSER)
118     # endif
119     # ifdef CLONE_NEWPID
120     const_iv (NEWPID)
121     # endif
122     # ifdef CLONE_IO
123     const_iv (IO)
124     # endif
125 root 1.2 # ifdef CLONE_NEWCGROUP
126     const_iv (NEWCGROUP)
127     # endif
128 root 1.1 };
129    
130     for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
131     newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
132    
133     int
134     clone (SV *sub, IV stacksize, int flags, SV *ptid = 0, SV *tls = &PL_sv_undef)
135     CODE:
136     {
137 root 1.2 if (!stacksize)
138 root 1.1 stacksize = 4 << 20;
139    
140     pid_t ptid_;
141     char *stack_ptr = mmap (0, stacksize, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN | MAP_STACK, -1, 0);
142    
143     #ifndef __hppa
144     stack_ptr += stacksize - 16; /* be safe and put the sp at 16 bytes below the end */
145     #endif
146    
147     RETVAL = -1;
148     if (stack_ptr != (void *)-1)
149     {
150     SV *my_sub = newSVsv (sub);
151    
152     RETVAL = clone (clone_cb, (void *)stack_ptr, flags, (void *)my_sub, &ptid, SvOK (tls) ? SvPV_nolen (tls) : 0, 0);
153    
154     if (ptid) sv_setiv (ptid, (IV)ptid_);
155    
156     if ((flags & (CLONE_VM | CLONE_VFORK)) != CLONE_VM)
157     {
158     int old_errno = errno;
159     munmap (stack_ptr, stacksize);
160     errno = old_errno;
161     }
162     }
163     }
164     OUTPUT:
165     RETVAL
166    
167 root 1.2 int
168     unshare (int flags)
169    
170     int
171     setns (SV *fh_or_fd, int nstype = 0)
172     C_ARGS: s_fileno (fh_or_fd, 0), nstype