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

# Content
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 /* 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 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 # ifdef CLONE_NEWCGROUP
126 const_iv (NEWCGROUP)
127 # endif
128 };
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 if (!stacksize)
138 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 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