line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#define PERL_NO_GET_CONTEXT |
2
|
|
|
|
|
|
|
#include "easyxs/easyxs.h" |
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
// Cribbed from Socket.xs: |
5
|
|
|
|
|
|
|
/* STRUCT_OFFSET should have come from from perl.h, but if not, |
6
|
|
|
|
|
|
|
* roll our own (not using offsetof() since that is C99). */ |
7
|
|
|
|
|
|
|
#ifndef STRUCT_OFFSET |
8
|
|
|
|
|
|
|
# define STRUCT_OFFSET(s,m) (Size_t)(&(((s *)0)->m)) |
9
|
|
|
|
|
|
|
#endif |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
#define STRUCT_MEMBER_SIZE(s,m) sizeof(((s *)0)->m) |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
// Modern Win32 releases do support UNIX sockets via afunix.h, |
14
|
|
|
|
|
|
|
// but that header file isn’t available on MinGW. Socket.xs defines |
15
|
|
|
|
|
|
|
// the necessary structs and constants directly; if needed we could |
16
|
|
|
|
|
|
|
// take that approach, but for now let’s just forgo UNIX socket support |
17
|
|
|
|
|
|
|
// unless there’s sys/un.h. |
18
|
|
|
|
|
|
|
#ifdef I_SYS_UN // cf. perl5 Porting/Glossary |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
#define HAS_UNIX_SOCKETS 1 |
21
|
|
|
|
|
|
|
#include |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
#define SA_FAMILY_END_OFFSET ( \ |
24
|
|
|
|
|
|
|
STRUCT_OFFSET(struct sockaddr, sa_family) \ |
25
|
|
|
|
|
|
|
+ STRUCT_MEMBER_SIZE(struct sockaddr, sa_family) \ |
26
|
|
|
|
|
|
|
) |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
#else |
29
|
|
|
|
|
|
|
#define HAS_UNIX_SOCKETS 0 |
30
|
|
|
|
|
|
|
#endif |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
#include |
33
|
|
|
|
|
|
|
#include |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
#include "ppport.h" |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
#define DEBUG 0 |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
/* A duplicate of PL_ppaddr as we find it at BOOT time. |
40
|
|
|
|
|
|
|
We can thus overwrite PL_ppaddr with our own wrapper functions. |
41
|
|
|
|
|
|
|
This interacts better with wrap_op_checker(), which doesn’t provide |
42
|
|
|
|
|
|
|
a good way to call the op’s (now-overwritten) op_ppaddr callback. |
43
|
|
|
|
|
|
|
*/ |
44
|
|
|
|
|
|
|
static Perl_ppaddr_t ORIG_PL_ppaddr[OP_max]; |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
#define MYPKG "Filesys::Restrict" |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
/* An idempotent variant of dMARK that allows us to inspect the |
49
|
|
|
|
|
|
|
mark stack without changing it: */ |
50
|
|
|
|
|
|
|
#ifndef dMARK_TOPMARK |
51
|
|
|
|
|
|
|
#define dMARK_TOPMARK SV **mark = PL_stack_base + TOPMARK |
52
|
|
|
|
|
|
|
#endif |
53
|
|
|
|
|
|
|
|
54
|
160
|
|
|
|
|
|
static inline SV* _get_callback(pTHX) { |
55
|
160
|
|
|
|
|
|
SV* callback = get_sv(MYPKG "::_AUTHORIZE", 0); |
56
|
|
|
|
|
|
|
|
57
|
160
|
50
|
|
|
|
|
if (callback && !SvOK(callback)) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
58
|
5
|
|
|
|
|
|
callback = NULL; |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
160
|
|
|
|
|
|
return callback; |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
#define _IS_FILEHANDLE(expr) ( \ |
65
|
|
|
|
|
|
|
(SvTYPE(expr) == SVt_PVGV) || \ |
66
|
|
|
|
|
|
|
(SvROK(expr) && SvTYPE(SvRV(expr)) == SVt_PVGV) || \ |
67
|
|
|
|
|
|
|
(SvTYPE(expr) == SVt_PVIO) || \ |
68
|
|
|
|
|
|
|
(SvROK(expr) && SvTYPE(SvRV(expr)) == SVt_PVIO) \ |
69
|
|
|
|
|
|
|
) |
70
|
|
|
|
|
|
|
|
71
|
25
|
|
|
|
|
|
bool _is_pipe_open(pTHX_ const char* str, STRLEN len) { |
72
|
25
|
100
|
|
|
|
|
if (len >= 2) { |
73
|
17
|
50
|
|
|
|
|
if (memEQ("|-", str, 2)) return true; |
74
|
17
|
50
|
|
|
|
|
if (memEQ("-|", str, 2)) return true; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
25
|
|
|
|
|
|
return false; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
#define _IS_SCALAR_REF(sv) (SvROK(sv) && (SvTYPE(SvRV(sv)) < SVt_PVGV)) |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
// Returns NULL to indicate no path. |
83
|
13
|
|
|
|
|
|
static SV* _get_path_from_3arg_open(pTHX_ SV* mode, SV* expr) { |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
// 3-arg open with undef 3rd arg opens an anonymous tempfile. |
86
|
13
|
100
|
|
|
|
|
if (!SvOK(expr)) return NULL; |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
// Ignore scalar-reference paths, which indicate an “open” |
89
|
|
|
|
|
|
|
// of a Perl scalar. |
90
|
12
|
100
|
|
|
|
|
if (_IS_SCALAR_REF(expr)) return NULL; |
|
|
50
|
|
|
|
|
|
91
|
|
|
|
|
|
|
|
92
|
12
|
50
|
|
|
|
|
if (!SvPOK(mode)) croak("mode isn’t a string?!?"); |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
STRLEN modelen; |
95
|
12
|
50
|
|
|
|
|
const char* modestr = SvPVbyte(mode, modelen); |
96
|
|
|
|
|
|
|
|
97
|
12
|
50
|
|
|
|
|
if (_is_pipe_open(aTHX_ modestr, modelen)) return NULL; |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
// If the last character of the mode is '=' then expr is a |
100
|
|
|
|
|
|
|
// file descriptor or filehandle, so we shouldn’t care. |
101
|
12
|
100
|
|
|
|
|
if (NULL != strchr(modestr, '&')) return NULL; |
102
|
|
|
|
|
|
|
|
103
|
13
|
|
|
|
|
|
return expr; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
13
|
|
|
|
|
|
static SV* _get_path_from_2arg_open(pTHX_ SV* expr) { |
107
|
|
|
|
|
|
|
STRLEN len; |
108
|
13
|
50
|
|
|
|
|
const char* str = SvPVbyte(expr, len); |
109
|
|
|
|
|
|
|
|
110
|
13
|
50
|
|
|
|
|
if (_is_pipe_open(aTHX_ str, len)) return NULL; |
111
|
|
|
|
|
|
|
|
112
|
13
|
50
|
|
|
|
|
if (len < 1) return NULL; |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
// Special cases: |
115
|
13
|
50
|
|
|
|
|
if (len == 2) { |
116
|
0
|
0
|
|
|
|
|
if (memEQ(str, ">-", 2)) return NULL; // opens STDOUT |
117
|
0
|
0
|
|
|
|
|
if (memEQ(str, "<-", 2)) return NULL; // opens STDIN |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
13
|
|
|
|
|
|
STRLEN idx = 0; |
121
|
|
|
|
|
|
|
|
122
|
13
|
100
|
|
|
|
|
if (str[idx] == '+') idx++; |
123
|
|
|
|
|
|
|
|
124
|
13
|
100
|
|
|
|
|
if (str[idx] == '<') { |
125
|
5
|
|
|
|
|
|
idx++; |
126
|
|
|
|
|
|
|
} |
127
|
8
|
50
|
|
|
|
|
else if (str[idx] == '>') { |
128
|
8
|
|
|
|
|
|
idx++; |
129
|
|
|
|
|
|
|
|
130
|
8
|
100
|
|
|
|
|
if (str[idx] == '>') idx++; |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
else { |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
// For now ignore anything that isn’t +>, +>>, +<, >, >>, or <. |
135
|
0
|
|
|
|
|
|
return NULL; |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
// Duplicating a filehandle or file descriptor is always OK. |
139
|
13
|
50
|
|
|
|
|
if (str[idx] == '&') return NULL; |
140
|
|
|
|
|
|
|
|
141
|
13
|
|
|
|
|
|
return newSVpvn_flags( |
142
|
|
|
|
|
|
|
str + idx, |
143
|
|
|
|
|
|
|
len - idx, |
144
|
|
|
|
|
|
|
SVs_TEMP |
145
|
|
|
|
|
|
|
); |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
|
148
|
194
|
|
|
|
|
|
static inline void _prep_stack(pTHX_ SV** args, unsigned argscount) { |
149
|
194
|
|
|
|
|
|
dSP; |
150
|
|
|
|
|
|
|
|
151
|
194
|
|
|
|
|
|
ENTER; |
152
|
194
|
|
|
|
|
|
SAVETMPS; |
153
|
|
|
|
|
|
|
|
154
|
194
|
50
|
|
|
|
|
PUSHMARK(SP); |
155
|
194
|
50
|
|
|
|
|
EXTEND(SP, argscount); |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
unsigned a; |
158
|
|
|
|
|
|
|
|
159
|
582
|
100
|
|
|
|
|
for (a=0; a < argscount; a++) PUSHs(args[a]); |
160
|
|
|
|
|
|
|
|
161
|
194
|
|
|
|
|
|
PUTBACK; |
162
|
194
|
|
|
|
|
|
} |
163
|
|
|
|
|
|
|
|
164
|
137
|
|
|
|
|
|
static inline void _authorize(pTHX_ int OPID, SV* path_sv, SV* callback_sv) { |
165
|
137
|
|
|
|
|
|
const char* opname = PL_op_desc[OPID]; |
166
|
|
|
|
|
|
|
|
167
|
137
|
|
|
|
|
|
dSP; |
168
|
|
|
|
|
|
|
|
169
|
137
|
|
|
|
|
|
SV* args[] = { |
170
|
137
|
|
|
|
|
|
newSVpvn_flags(opname, strlen(opname), SVs_TEMP), |
171
|
|
|
|
|
|
|
path_sv, |
172
|
|
|
|
|
|
|
}; |
173
|
|
|
|
|
|
|
|
174
|
137
|
|
|
|
|
|
_prep_stack(aTHX_ args, 2); |
175
|
|
|
|
|
|
|
|
176
|
137
|
|
|
|
|
|
I32 returns = call_sv( callback_sv, G_SCALAR ); |
177
|
|
|
|
|
|
|
|
178
|
137
|
|
|
|
|
|
SPAGAIN; |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
bool authorized; |
181
|
|
|
|
|
|
|
|
182
|
137
|
50
|
|
|
|
|
if (returns) { |
183
|
137
|
|
|
|
|
|
SV* got = POPs; |
184
|
137
|
50
|
|
|
|
|
authorized = SvTRUE(got); |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
185
|
|
|
|
|
|
|
} |
186
|
|
|
|
|
|
|
else { |
187
|
0
|
|
|
|
|
|
authorized = false; |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
137
|
|
|
|
|
|
PUTBACK; |
191
|
137
|
50
|
|
|
|
|
FREETMPS; |
192
|
137
|
|
|
|
|
|
LEAVE; |
193
|
|
|
|
|
|
|
|
194
|
137
|
100
|
|
|
|
|
if (!authorized) { |
195
|
57
|
|
|
|
|
|
_prep_stack(aTHX_ args, 2); |
196
|
|
|
|
|
|
|
|
197
|
57
|
|
|
|
|
|
call_pv( MYPKG "::_CROAK", G_VOID | G_DISCARD ); |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
// We should never get here: |
200
|
|
|
|
|
|
|
assert(0); |
201
|
|
|
|
|
|
|
} |
202
|
80
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
// open() is such a funny beast that it gets its own wrapper. |
205
|
26
|
|
|
|
|
|
static OP* _wrapped_pp_OP_OPEN(pTHX) { |
206
|
26
|
|
|
|
|
|
SV* callback = _get_callback(aTHX); |
207
|
26
|
50
|
|
|
|
|
if (callback) { |
208
|
26
|
|
|
|
|
|
dSP; |
209
|
26
|
|
|
|
|
|
dMARK_TOPMARK; |
210
|
|
|
|
|
|
|
|
211
|
26
|
|
|
|
|
|
int numargs = SP - MARK; |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
SV* path; |
214
|
|
|
|
|
|
|
|
215
|
26
|
|
|
|
|
|
switch (numargs) { |
216
|
|
|
|
|
|
|
case 1: |
217
|
0
|
|
|
|
|
|
path = NULL; |
218
|
0
|
|
|
|
|
|
break; |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
case 2: |
221
|
13
|
|
|
|
|
|
path = _get_path_from_2arg_open(aTHX_ MARK[2]); |
222
|
13
|
|
|
|
|
|
break; |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
case 3: |
225
|
13
|
|
|
|
|
|
path = _get_path_from_3arg_open(aTHX_ MARK[2], MARK[3]); |
226
|
|
|
|
|
|
|
|
227
|
13
|
|
|
|
|
|
break; |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
default: |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
// Shouldn’t happen, but just in case … |
232
|
0
|
|
|
|
|
|
croak("Bad # of args: %d", numargs); |
233
|
|
|
|
|
|
|
} |
234
|
|
|
|
|
|
|
|
235
|
26
|
100
|
|
|
|
|
if (path) { |
236
|
21
|
|
|
|
|
|
_authorize(aTHX_ OP_OPEN, path, callback); |
237
|
|
|
|
|
|
|
} |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
|
240
|
17
|
|
|
|
|
|
return ORIG_PL_ppaddr[OP_OPEN](aTHX); |
241
|
|
|
|
|
|
|
} |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
# if 0 |
244
|
|
|
|
|
|
|
// require() also gets its own wrapper since it depends on @INC. |
245
|
|
|
|
|
|
|
static OP* _wrapped_pp_OP_REQUIRE(pTHX) { |
246
|
|
|
|
|
|
|
SV* callback = _get_callback(aTHX); |
247
|
|
|
|
|
|
|
if (callback) { |
248
|
|
|
|
|
|
|
dSP; |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
SV* required = *SP; |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
STRLEN reqlen; |
253
|
|
|
|
|
|
|
const char* required_str = SvPVbyte(required, reqlen); |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
if (reqlen && NULL != strchr("./", required_str[0])) { |
256
|
|
|
|
|
|
|
_authorize(aTHX_ OP_REQUIRE, required, callback); |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
} |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
return ORIG_PL_ppaddr[OP_REQUIRE](aTHX); |
261
|
|
|
|
|
|
|
} |
262
|
|
|
|
|
|
|
#endif |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
#define MAKE_LAST_ARG_WRAPPER(OPID, CHECK_FH) \ |
265
|
|
|
|
|
|
|
static OP* _wrapped_pp_##OPID(pTHX) { \ |
266
|
|
|
|
|
|
|
SV* callback = _get_callback(aTHX); \ |
267
|
|
|
|
|
|
|
if (callback) { \ |
268
|
|
|
|
|
|
|
dSP; \ |
269
|
|
|
|
|
|
|
if (!CHECK_FH || !_IS_FILEHANDLE(*SP)) { \ |
270
|
|
|
|
|
|
|
_authorize(aTHX_ OPID, *SP, callback); \ |
271
|
|
|
|
|
|
|
} \ |
272
|
|
|
|
|
|
|
} \ |
273
|
|
|
|
|
|
|
\ |
274
|
|
|
|
|
|
|
return ORIG_PL_ppaddr[OPID](aTHX); \ |
275
|
|
|
|
|
|
|
} |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
#define MAKE_LAST_ARG_WRAPPER_CHECK_FH(OPID) \ |
278
|
|
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER(OPID, 1) |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
#define MAKE_LAST_ARG_WRAPPER_NO_CHECK_FH(OPID) \ |
281
|
|
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER(OPID, 0) |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
#define MAKE_2ARG_WRAPPER(OPID) \ |
284
|
|
|
|
|
|
|
static OP* _wrapped_pp_##OPID(pTHX) { \ |
285
|
|
|
|
|
|
|
SV* callback = _get_callback(aTHX); \ |
286
|
|
|
|
|
|
|
if (callback) { \ |
287
|
|
|
|
|
|
|
dSP; \ |
288
|
|
|
|
|
|
|
_authorize(aTHX_ OPID, *SP, callback); \ |
289
|
|
|
|
|
|
|
_authorize(aTHX_ OPID, *(SP - 1), callback); \ |
290
|
|
|
|
|
|
|
} \ |
291
|
|
|
|
|
|
|
\ |
292
|
|
|
|
|
|
|
return ORIG_PL_ppaddr[OPID](aTHX); \ |
293
|
|
|
|
|
|
|
} |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
// ---------------------------------------------------------------------- |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
#define _MY_SET_SP_AND_MARK(OP_MAXARG) \ |
298
|
|
|
|
|
|
|
dSP; \ |
299
|
|
|
|
|
|
|
dMARK_TOPMARK; \ |
300
|
|
|
|
|
|
|
\ |
301
|
|
|
|
|
|
|
/* The compiler will optimize this away \ |
302
|
|
|
|
|
|
|
for MAKE_FIRST_ARG_OPEN_LIST_WRAPPER: \ |
303
|
|
|
|
|
|
|
*/ \ |
304
|
|
|
|
|
|
|
if (OP_MAXARG) \ |
305
|
|
|
|
|
|
|
if (SP < MARK || (SP - MARK) > OP_MAXARG) { \ |
306
|
|
|
|
|
|
|
unsigned numargs = MAXARG; \ |
307
|
|
|
|
|
|
|
MARK = SP; \ |
308
|
|
|
|
|
|
|
while (numargs--) MARK--; \ |
309
|
|
|
|
|
|
|
} |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
/* For ops that take an indefinite number of args. */ |
312
|
|
|
|
|
|
|
#define MAKE_FIRST_ARG_OPEN_LIST_WRAPPER(OPID) \ |
313
|
|
|
|
|
|
|
MAKE_SINGLE_ARG_LIST_WRAPPER(OPID, 0, 0) |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
/* For ops whose number of string args is a fixed range. |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
NB: In some perls, some list opts don’t set MARK. In those cases we |
318
|
|
|
|
|
|
|
fall back to MAXARG. As of now mkdir is the known “offender”, and |
319
|
|
|
|
|
|
|
only on Alpine Linux 3.11 & 3.12 (not 3.13). |
320
|
|
|
|
|
|
|
*/ |
321
|
|
|
|
|
|
|
#define MAKE_SINGLE_ARG_LIST_WRAPPER(OPID, ARG_INDEX, OP_MAXARG) \ |
322
|
|
|
|
|
|
|
static OP* _wrapped_pp_##OPID(pTHX) { \ |
323
|
|
|
|
|
|
|
SV* callback = _get_callback(aTHX); \ |
324
|
|
|
|
|
|
|
if (callback) { \ |
325
|
|
|
|
|
|
|
_MY_SET_SP_AND_MARK(OP_MAXARG) \ |
326
|
|
|
|
|
|
|
\ |
327
|
|
|
|
|
|
|
_authorize(aTHX_ OPID, MARK[1 + ARG_INDEX], callback); \ |
328
|
|
|
|
|
|
|
} \ |
329
|
|
|
|
|
|
|
\ |
330
|
|
|
|
|
|
|
return ORIG_PL_ppaddr[OPID](aTHX); \ |
331
|
|
|
|
|
|
|
} |
332
|
|
|
|
|
|
|
|
333
|
3
|
|
|
|
|
|
static OP* _wrapped_pp_OP_TRUNCATE(pTHX) { |
334
|
3
|
|
|
|
|
|
SV* callback = _get_callback(aTHX); |
335
|
3
|
50
|
|
|
|
|
if (callback) { |
336
|
3
|
|
|
|
|
|
dSP; |
337
|
3
|
|
|
|
|
|
SV* first_arg = *(SP - 1); |
338
|
|
|
|
|
|
|
|
339
|
3
|
50
|
|
|
|
|
if (!_IS_FILEHANDLE(first_arg)) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
340
|
2
|
|
|
|
|
|
_authorize(aTHX_ OP_TRUNCATE, first_arg, callback); |
341
|
|
|
|
|
|
|
} |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
|
344
|
2
|
|
|
|
|
|
return ORIG_PL_ppaddr[OP_TRUNCATE](aTHX); |
345
|
|
|
|
|
|
|
} |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
#define MAKE_ALL_ARGS_LIST_WRAPPER_CHECK_FH(OPID, ARG_INDEX) \ |
348
|
|
|
|
|
|
|
static OP* _wrapped_pp_##OPID(pTHX) { \ |
349
|
|
|
|
|
|
|
SV* callback = _get_callback(aTHX); \ |
350
|
|
|
|
|
|
|
if (callback) { \ |
351
|
|
|
|
|
|
|
_MY_SET_SP_AND_MARK(0) \ |
352
|
|
|
|
|
|
|
\ |
353
|
|
|
|
|
|
|
MARK += ARG_INDEX; \ |
354
|
|
|
|
|
|
|
while (++MARK <= SP) { \ |
355
|
|
|
|
|
|
|
if (!_IS_FILEHANDLE(*MARK)) { \ |
356
|
|
|
|
|
|
|
_authorize(aTHX_ OPID, *MARK, callback); \ |
357
|
|
|
|
|
|
|
} \ |
358
|
|
|
|
|
|
|
} \ |
359
|
|
|
|
|
|
|
} \ |
360
|
|
|
|
|
|
|
\ |
361
|
|
|
|
|
|
|
return ORIG_PL_ppaddr[OPID](aTHX); \ |
362
|
|
|
|
|
|
|
} |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
/* For ops where only the last arg is a string. */ |
365
|
|
|
|
|
|
|
#define MAKE_SOCKET_OP_WRAPPER(OPID) \ |
366
|
|
|
|
|
|
|
static OP* _wrapped_pp_##OPID(pTHX) { \ |
367
|
|
|
|
|
|
|
SV* callback = _get_callback(aTHX); \ |
368
|
|
|
|
|
|
|
if (callback) { \ |
369
|
|
|
|
|
|
|
dSP; \ |
370
|
|
|
|
|
|
|
STRLEN pathlen; \ |
371
|
|
|
|
|
|
|
const char* path = _get_local_socket_path(aTHX_ SP[0], &pathlen); \ |
372
|
|
|
|
|
|
|
if (path) { \ |
373
|
|
|
|
|
|
|
SV* path_sv = newSVpvn_flags(path, pathlen, SVs_TEMP); \ |
374
|
|
|
|
|
|
|
_authorize(aTHX_ OPID, path_sv, callback); \ |
375
|
|
|
|
|
|
|
} \ |
376
|
|
|
|
|
|
|
} \ |
377
|
|
|
|
|
|
|
\ |
378
|
|
|
|
|
|
|
return ORIG_PL_ppaddr[OPID](aTHX); \ |
379
|
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
|
381
|
5
|
|
|
|
|
|
const char* _get_local_socket_path(pTHX_ SV* sockname_sv, STRLEN *pathlen) { |
382
|
5
|
|
|
|
|
|
char* path = NULL; |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
#if HAS_UNIX_SOCKETS |
385
|
|
|
|
|
|
|
STRLEN sockname_len; |
386
|
5
|
50
|
|
|
|
|
const char* sockname_str = SvPVbyte(sockname_sv, sockname_len); |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
// Let Perl handle the failure state: |
389
|
5
|
50
|
|
|
|
|
if (sockname_len >= SA_FAMILY_END_OFFSET) { |
390
|
5
|
|
|
|
|
|
sa_family_t family = ( (struct sockaddr*) sockname_str )->sa_family; |
391
|
|
|
|
|
|
|
|
392
|
5
|
50
|
|
|
|
|
if (family == AF_UNIX) { |
393
|
5
|
|
|
|
|
|
path = ( (struct sockaddr_un*) sockname_str )->sun_path; |
394
|
5
|
|
|
|
|
|
*pathlen = sockname_len - STRUCT_OFFSET(struct sockaddr_un, sun_path); |
395
|
|
|
|
|
|
|
} |
396
|
|
|
|
|
|
|
} |
397
|
|
|
|
|
|
|
#endif |
398
|
|
|
|
|
|
|
|
399
|
5
|
|
|
|
|
|
return path; |
400
|
|
|
|
|
|
|
} |
401
|
|
|
|
|
|
|
|
402
|
5
|
50
|
|
|
|
|
MAKE_SOCKET_OP_WRAPPER(OP_BIND); |
|
|
50
|
|
|
|
|
|
403
|
3
|
50
|
|
|
|
|
MAKE_SOCKET_OP_WRAPPER(OP_CONNECT); |
|
|
50
|
|
|
|
|
|
404
|
|
|
|
|
|
|
|
405
|
6
|
50
|
|
|
|
|
MAKE_SINGLE_ARG_LIST_WRAPPER(OP_SYSOPEN, 1, 4); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
406
|
|
|
|
|
|
|
|
407
|
0
|
0
|
|
|
|
|
MAKE_FIRST_ARG_OPEN_LIST_WRAPPER(OP_EXEC); |
408
|
6
|
50
|
|
|
|
|
MAKE_FIRST_ARG_OPEN_LIST_WRAPPER(OP_SYSTEM); |
409
|
|
|
|
|
|
|
|
410
|
0
|
0
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_LSTAT); |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
411
|
2
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_STAT); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
412
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTRREAD); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
413
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTRWRITE); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
414
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTREXEC); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
415
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTEREAD); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
416
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTEWRITE); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
417
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTEEXEC); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
418
|
7
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTIS); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
419
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTSIZE); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
420
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTMTIME); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
421
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTATIME); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
422
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTCTIME); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
423
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTROWNED); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
424
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTEOWNED); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
425
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTZERO); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
426
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTSOCK); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
427
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTCHR); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
428
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTBLK); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
429
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTFILE); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
430
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTDIR); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
431
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTPIPE); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
432
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTSUID); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
433
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTSGID); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
434
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTSVTX); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
435
|
3
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTLINK); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
436
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTTEXT); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
437
|
5
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_FTBINARY); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
438
|
0
|
0
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_CHECK_FH(OP_CHDIR); |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
439
|
13
|
50
|
|
|
|
|
MAKE_ALL_ARGS_LIST_WRAPPER_CHECK_FH(OP_CHOWN, 2); |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
440
|
0
|
0
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_NO_CHECK_FH(OP_CHROOT); |
441
|
10
|
50
|
|
|
|
|
MAKE_ALL_ARGS_LIST_WRAPPER_CHECK_FH(OP_UNLINK, 0); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
442
|
16
|
50
|
|
|
|
|
MAKE_ALL_ARGS_LIST_WRAPPER_CHECK_FH(OP_CHMOD, 1); |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
443
|
13
|
50
|
|
|
|
|
MAKE_ALL_ARGS_LIST_WRAPPER_CHECK_FH(OP_UTIME, 2); |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
444
|
5
|
50
|
|
|
|
|
MAKE_2ARG_WRAPPER(OP_RENAME); |
445
|
5
|
50
|
|
|
|
|
MAKE_2ARG_WRAPPER(OP_LINK); |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
// symlink() is special: its “target” (the first arg) and doesn’t |
448
|
|
|
|
|
|
|
// need to refer to a valid filesystem node. |
449
|
0
|
0
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_NO_CHECK_FH(OP_SYMLINK); |
450
|
|
|
|
|
|
|
|
451
|
3
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_NO_CHECK_FH(OP_READLINK); |
452
|
16
|
100
|
|
|
|
|
MAKE_SINGLE_ARG_LIST_WRAPPER(OP_MKDIR, 0, 2); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
453
|
3
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_NO_CHECK_FH(OP_RMDIR); |
454
|
3
|
50
|
|
|
|
|
MAKE_LAST_ARG_WRAPPER_NO_CHECK_FH(OP_OPEN_DIR); |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
// MAKE_LAST_ARG_WRAPPER_NO_CHECK_FH(OP_DOFILE); |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------- */ |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
#define MAKE_BOOT_WRAPPER(OPID) \ |
461
|
|
|
|
|
|
|
ORIG_PL_ppaddr[OPID] = PL_ppaddr[OPID]; \ |
462
|
|
|
|
|
|
|
PL_ppaddr[OPID] = _wrapped_pp_##OPID; |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
//---------------------------------------------------------------------- |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
bool initialized = false; |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
MODULE = Filesys::Restrict PACKAGE = Filesys::Restrict |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
PROTOTYPES: DISABLE |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
BOOT: |
473
|
|
|
|
|
|
|
/* In theory this is for PL_check rather than PL_ppaddr, but per |
474
|
|
|
|
|
|
|
Paul Evans in practice this mutex gets used for other stuff, too. |
475
|
|
|
|
|
|
|
Paul says a race here should be exceptionally rare, so for pre-5.16 |
476
|
|
|
|
|
|
|
perls (which lack this mutex) let’s just skip it. |
477
|
|
|
|
|
|
|
*/ |
478
|
|
|
|
|
|
|
#ifdef OP_CHECK_MUTEX_LOCK |
479
|
|
|
|
|
|
|
OP_CHECK_MUTEX_LOCK; |
480
|
|
|
|
|
|
|
#endif |
481
|
6
|
50
|
|
|
|
|
if (!initialized) { |
482
|
6
|
|
|
|
|
|
initialized = true; |
483
|
|
|
|
|
|
|
|
484
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_OPEN); |
485
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_SYSOPEN); |
486
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_TRUNCATE); |
487
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_EXEC); |
488
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_SYSTEM); |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
if (HAS_UNIX_SOCKETS) { |
491
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_BIND); |
492
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_CONNECT); |
493
|
|
|
|
|
|
|
} |
494
|
|
|
|
|
|
|
|
495
|
6
|
|
|
|
|
|
HV *stash = gv_stashpv(MYPKG, FALSE); |
496
|
6
|
|
|
|
|
|
newCONSTSUB(stash, "_HAS_UNIX_SOCKETS", boolSV(HAS_UNIX_SOCKETS)); |
497
|
|
|
|
|
|
|
|
498
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_LSTAT); |
499
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_STAT); |
500
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTRREAD); |
501
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTRWRITE); |
502
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTREXEC); |
503
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTEREAD); |
504
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTEWRITE); |
505
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTEEXEC); |
506
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTIS); |
507
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTSIZE); |
508
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTMTIME); |
509
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTATIME); |
510
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTCTIME); |
511
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTROWNED); |
512
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTEOWNED); |
513
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTZERO); |
514
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTSOCK); |
515
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTCHR); |
516
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTBLK); |
517
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTFILE); |
518
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTDIR); |
519
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTPIPE); |
520
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTSUID); |
521
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTSGID); |
522
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTSVTX); |
523
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTLINK); |
524
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTTEXT); |
525
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_FTBINARY); |
526
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_CHDIR); |
527
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_CHOWN); |
528
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_CHROOT); |
529
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_UNLINK); |
530
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_CHMOD); |
531
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_UTIME); |
532
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_RENAME); |
533
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_LINK); |
534
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_SYMLINK); |
535
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_READLINK); |
536
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_MKDIR); |
537
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_RMDIR); |
538
|
6
|
|
|
|
|
|
MAKE_BOOT_WRAPPER(OP_OPEN_DIR); |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
// MAKE_BOOT_WRAPPER(OP_REQUIRE); |
541
|
|
|
|
|
|
|
// MAKE_BOOT_WRAPPER(OP_DOFILE); |
542
|
|
|
|
|
|
|
} |
543
|
|
|
|
|
|
|
#ifdef OP_CHECK_MUTEX_UNLOCK |
544
|
|
|
|
|
|
|
OP_CHECK_MUTEX_UNLOCK; |
545
|
|
|
|
|
|
|
#endif |