line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
/* |
2
|
|
|
|
|
|
|
* |
3
|
|
|
|
|
|
|
* Copyright (c) 2018, cPanel, LLC. |
4
|
|
|
|
|
|
|
* All rights reserved. |
5
|
|
|
|
|
|
|
* http://cpanel.net |
6
|
|
|
|
|
|
|
* |
7
|
|
|
|
|
|
|
* This is free software; you can redistribute it and/or modify it under the |
8
|
|
|
|
|
|
|
* same terms as Perl itself. |
9
|
|
|
|
|
|
|
* |
10
|
|
|
|
|
|
|
*/ |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
#include |
13
|
|
|
|
|
|
|
#include |
14
|
|
|
|
|
|
|
#include |
15
|
|
|
|
|
|
|
#include |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
#include "FileCheck.h" |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
/* |
20
|
|
|
|
|
|
|
* Macro to make the moking process easier |
21
|
|
|
|
|
|
|
* for now keep them there, so we can hack them in the same file |
22
|
|
|
|
|
|
|
*/ |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
/* generic macro with args */ |
25
|
|
|
|
|
|
|
#define _CALL_REAL_PP(zOP) (* ( gl_overload_ft->op[zOP].real_pp ) )(aTHX) |
26
|
|
|
|
|
|
|
#define _RETURN_CALL_REAL_PP_IF_UNMOCK(zOP) if (!gl_overload_ft->op[zOP].is_mocked) return _CALL_REAL_PP(zOP); |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
/* simplified versions for our custom usage */ |
29
|
|
|
|
|
|
|
#define CALL_REAL_OP() _CALL_REAL_PP(PL_op->op_type) |
30
|
|
|
|
|
|
|
#define RETURN_CALL_REAL_OP_IF_UNMOCK() _RETURN_CALL_REAL_PP_IF_UNMOCK(PL_op->op_type) |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
#define INIT_FILECHECK_MOCK(op_name, op_type, f) \ |
33
|
|
|
|
|
|
|
newCONSTSUB(stash, op_name, newSViv(op_type) ); \ |
34
|
|
|
|
|
|
|
gl_overload_ft->op[op_type].real_pp = PL_ppaddr[op_type]; \ |
35
|
|
|
|
|
|
|
PL_ppaddr[op_type] = f; |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
/* TODO: need to improve for Perl <= 5.014 */ |
38
|
|
|
|
|
|
|
#define RETURN_CALL_REAL_OP_IF_CALL_WITH_DEFGV() STMT_START { \ |
39
|
|
|
|
|
|
|
if (gl_overload_ft->op[OP_STAT].is_mocked) { \ |
40
|
|
|
|
|
|
|
SV *arg = *PL_stack_sp; GV *gv; \ |
41
|
|
|
|
|
|
|
if ( SvTYPE(arg) == SVt_PVAV ) arg = arg + AvMAX( arg ); \ |
42
|
|
|
|
|
|
|
/* GV *gv = MAYBE_DEREF_GV(arg); */ \ |
43
|
|
|
|
|
|
|
if ( PL_op->op_flags & OPf_REF ) \ |
44
|
|
|
|
|
|
|
gv = cGVOP_gv; \ |
45
|
|
|
|
|
|
|
else { \ |
46
|
|
|
|
|
|
|
gv = MAYBE_DEREF_GV(arg); \ |
47
|
|
|
|
|
|
|
} \ |
48
|
|
|
|
|
|
|
/* printf ("### XXX ---> arg %d %p vs GV %p vs defgv %p \n", SvFLAGS(arg), *PL_stack_sp, gv, PL_defgv ); */ \ |
49
|
|
|
|
|
|
|
/* get the GV from the arg if it s not a GV */ \ |
50
|
|
|
|
|
|
|
if ( SvTYPE(arg) == SVt_NULL || gv == PL_defgv ) { \ |
51
|
|
|
|
|
|
|
return CALL_REAL_OP(); \ |
52
|
|
|
|
|
|
|
} \ |
53
|
|
|
|
|
|
|
} \ |
54
|
|
|
|
|
|
|
} STMT_END |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
/* a Stat_t struct has 13 elements */ |
57
|
|
|
|
|
|
|
#define STAT_T_MAX 13 |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
/* ----------- start there --------------- */ |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
OverloadFTOps *gl_overload_ft = 0; |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
/* |
64
|
|
|
|
|
|
|
* common helper to callback the pure perl function Overload::FileCheck::_check |
65
|
|
|
|
|
|
|
* and get the mocked value for the -X check |
66
|
|
|
|
|
|
|
* |
67
|
|
|
|
|
|
|
* 1 check is true -> OP returns Yes |
68
|
|
|
|
|
|
|
* 0 check is false -> OP returns No |
69
|
|
|
|
|
|
|
* TODO: -> OP returns undef |
70
|
|
|
|
|
|
|
* -1 fallback to the original OP |
71
|
|
|
|
|
|
|
*/ |
72
|
771
|
|
|
|
|
|
int _overload_ft_ops() { |
73
|
771
|
|
|
|
|
|
SV *const arg = *PL_stack_sp; |
74
|
771
|
|
|
|
|
|
int optype = PL_op->op_type; /* this is the current op_type we are mocking */ |
75
|
771
|
|
|
|
|
|
int check_status = -1; /* 1 -> YES ; 0 -> FALSE ; -1 -> delegate */ |
76
|
|
|
|
|
|
|
int count; |
77
|
|
|
|
|
|
|
|
78
|
771
|
|
|
|
|
|
dSP; |
79
|
|
|
|
|
|
|
|
80
|
771
|
|
|
|
|
|
ENTER; |
81
|
771
|
|
|
|
|
|
SAVETMPS; |
82
|
|
|
|
|
|
|
|
83
|
771
|
50
|
|
|
|
|
PUSHMARK(SP); |
84
|
771
|
50
|
|
|
|
|
EXTEND(SP, 2); |
85
|
771
|
|
|
|
|
|
PUSHs(sv_2mortal(newSViv(optype))); |
86
|
771
|
|
|
|
|
|
PUSHs(arg); |
87
|
|
|
|
|
|
|
|
88
|
771
|
|
|
|
|
|
PUTBACK; |
89
|
|
|
|
|
|
|
|
90
|
771
|
|
|
|
|
|
count = call_pv("Overload::FileCheck::_check", G_SCALAR); |
91
|
|
|
|
|
|
|
|
92
|
771
|
|
|
|
|
|
SPAGAIN; |
93
|
|
|
|
|
|
|
|
94
|
771
|
50
|
|
|
|
|
if (count != 1) |
95
|
0
|
|
|
|
|
|
croak("No return value from Overload::FileCheck::_check for OP #%d\n", optype); |
96
|
|
|
|
|
|
|
|
97
|
771
|
100
|
|
|
|
|
check_status = POPi; /* TOOO pop on SV* for true / false & co */ |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
/* printf ("######## The result is %d /// OPTYPE is %d\n", check_status, optype); */ |
100
|
|
|
|
|
|
|
|
101
|
771
|
|
|
|
|
|
PUTBACK; |
102
|
771
|
50
|
|
|
|
|
FREETMPS; |
103
|
771
|
|
|
|
|
|
LEAVE; |
104
|
|
|
|
|
|
|
|
105
|
771
|
|
|
|
|
|
return check_status; |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
103
|
|
|
|
|
|
SV* _overload_ft_ops_sv() { |
109
|
103
|
|
|
|
|
|
SV *const arg = *PL_stack_sp; |
110
|
103
|
|
|
|
|
|
int optype = PL_op->op_type; /* this is the current op_type we are mocking */ |
111
|
|
|
|
|
|
|
SV *status; /* 1 -> YES ; 0 -> FALSE ; -1 -> delegate */ |
112
|
|
|
|
|
|
|
|
113
|
103
|
|
|
|
|
|
dSP; |
114
|
|
|
|
|
|
|
int count; |
115
|
|
|
|
|
|
|
|
116
|
103
|
|
|
|
|
|
ENTER; |
117
|
103
|
|
|
|
|
|
SAVETMPS; |
118
|
|
|
|
|
|
|
|
119
|
103
|
50
|
|
|
|
|
PUSHMARK(SP); |
120
|
103
|
50
|
|
|
|
|
EXTEND(SP, 2); |
121
|
103
|
|
|
|
|
|
PUSHs(sv_2mortal(newSViv(optype))); |
122
|
103
|
|
|
|
|
|
PUSHs(arg); |
123
|
|
|
|
|
|
|
|
124
|
103
|
|
|
|
|
|
PUTBACK; |
125
|
|
|
|
|
|
|
|
126
|
103
|
|
|
|
|
|
count = call_pv("Overload::FileCheck::_check", G_SCALAR); |
127
|
|
|
|
|
|
|
|
128
|
103
|
|
|
|
|
|
SPAGAIN; |
129
|
|
|
|
|
|
|
|
130
|
103
|
50
|
|
|
|
|
if (count != 1) |
131
|
0
|
|
|
|
|
|
croak("No return value from Overload::FileCheck::_check for OP #%d\n", optype); |
132
|
|
|
|
|
|
|
|
133
|
103
|
|
|
|
|
|
status = POPs; |
134
|
103
|
|
|
|
|
|
SvREFCNT_inc( status ); |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
/* printf ("######## The result is %d /// OPTYPE is %d\n", check_status, optype); */ |
137
|
|
|
|
|
|
|
|
138
|
103
|
|
|
|
|
|
PUTBACK; |
139
|
103
|
50
|
|
|
|
|
FREETMPS; |
140
|
103
|
|
|
|
|
|
LEAVE; |
141
|
|
|
|
|
|
|
|
142
|
103
|
|
|
|
|
|
return status; |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
/* |
146
|
|
|
|
|
|
|
* view perldoc to call SVs, method, ... |
147
|
|
|
|
|
|
|
* |
148
|
|
|
|
|
|
|
* https://perldoc.perl.org/perlcall.html |
149
|
|
|
|
|
|
|
* |
150
|
|
|
|
|
|
|
* but also https://perldoc.perl.org/perlguts.html |
151
|
|
|
|
|
|
|
*/ |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
#define set_stat_from_aryix(st, ix) \ |
154
|
|
|
|
|
|
|
rsv = ary[ix]; \ |
155
|
|
|
|
|
|
|
if (SvROK(rsv)) croak("Overload::FileCheck - Item %d should not be one RV\n", ix); \ |
156
|
|
|
|
|
|
|
if (SvIOK(rsv)) st = SvIV( rsv ); \ |
157
|
|
|
|
|
|
|
else if (SvUOK(rsv)) st = SvUV( rsv ); \ |
158
|
|
|
|
|
|
|
else if (SvNOK(rsv)) st = SvNV( rsv ); \ |
159
|
|
|
|
|
|
|
else croak("Overload::FileCheck - Item %d is not numeric...\n", ix); |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
/* |
163
|
|
|
|
|
|
|
* similar to _overload_ft_ops but expect more args from _check |
164
|
|
|
|
|
|
|
* which returns values for a fake stat |
165
|
|
|
|
|
|
|
* |
166
|
|
|
|
|
|
|
* Note: we could also call a dedicated function as _check_stat |
167
|
|
|
|
|
|
|
*/ |
168
|
385
|
|
|
|
|
|
int _overload_ft_stat(Stat_t *stat, int *size) { |
169
|
385
|
|
|
|
|
|
SV *const arg = *PL_stack_sp; |
170
|
385
|
|
|
|
|
|
int optype = PL_op->op_type; /* this is the current op_type we are mocking */ |
171
|
385
|
|
|
|
|
|
int check_status = -1; /* 1 -> YES ; 0 -> FALSE ; -1 -> delegate */ |
172
|
|
|
|
|
|
|
|
173
|
385
|
|
|
|
|
|
dSP; |
174
|
|
|
|
|
|
|
int count; |
175
|
|
|
|
|
|
|
SV *sv; |
176
|
|
|
|
|
|
|
|
177
|
385
|
|
|
|
|
|
ENTER; |
178
|
385
|
|
|
|
|
|
SAVETMPS; |
179
|
|
|
|
|
|
|
|
180
|
385
|
50
|
|
|
|
|
PUSHMARK(SP); |
181
|
385
|
50
|
|
|
|
|
EXTEND(SP, 2); |
182
|
385
|
|
|
|
|
|
PUSHs(sv_2mortal(newSViv(optype))); |
183
|
385
|
|
|
|
|
|
PUSHs(arg); |
184
|
385
|
|
|
|
|
|
PUTBACK; |
185
|
|
|
|
|
|
|
|
186
|
385
|
|
|
|
|
|
count = call_pv("Overload::FileCheck::_check", G_ARRAY); |
187
|
|
|
|
|
|
|
|
188
|
377
|
|
|
|
|
|
SPAGAIN; |
189
|
|
|
|
|
|
|
|
190
|
377
|
50
|
|
|
|
|
if (count < 1) |
191
|
0
|
|
|
|
|
|
croak("Overload::FileCheck::_check for stat OP #%d should return at least one SV.\n", optype); |
192
|
377
|
50
|
|
|
|
|
if (count > 2) |
193
|
0
|
|
|
|
|
|
croak("Overload::FileCheck::_check for stat OP #%d should return no more than two SVs.\n", optype); |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
/* popping the stack from last entry to first */ |
196
|
377
|
100
|
|
|
|
|
if (count == 2) sv = POPs; /* RvAV */ |
197
|
377
|
50
|
|
|
|
|
check_status = POPi; /* TOOO pop on SV* for true / false & co */ |
198
|
|
|
|
|
|
|
|
199
|
377
|
|
|
|
|
|
*size = 0; /* by default it fails */ |
200
|
|
|
|
|
|
|
|
201
|
377
|
100
|
|
|
|
|
if ( check_status == 1 ) { |
202
|
|
|
|
|
|
|
AV *stat_array; |
203
|
|
|
|
|
|
|
SV **ary; |
204
|
|
|
|
|
|
|
SV *rsv; |
205
|
|
|
|
|
|
|
int av_size; |
206
|
|
|
|
|
|
|
|
207
|
374
|
50
|
|
|
|
|
if (count != 2) |
208
|
0
|
|
|
|
|
|
croak("Overload::FileCheck::_check for stat OP #%d should return two SVs on success.\n", optype); |
209
|
|
|
|
|
|
|
|
210
|
374
|
50
|
|
|
|
|
if ( ! SvROK(sv) ) |
211
|
0
|
|
|
|
|
|
croak( "Overload::FileCheck::_check need to return an array ref" ); |
212
|
|
|
|
|
|
|
|
213
|
374
|
|
|
|
|
|
stat_array = MUTABLE_AV( SvRV( sv ) ); |
214
|
374
|
50
|
|
|
|
|
if ( SvTYPE(stat_array) != SVt_PVAV ) |
215
|
0
|
|
|
|
|
|
croak( "Overload::FileCheck::_check need to return an array ref" ); |
216
|
|
|
|
|
|
|
|
217
|
374
|
50
|
|
|
|
|
av_size = AvFILL(stat_array); |
218
|
374
|
100
|
|
|
|
|
if ( av_size > 0 && av_size != ( STAT_T_MAX - 1 ) ) |
|
|
50
|
|
|
|
|
|
219
|
0
|
|
|
|
|
|
croak( "Overload::FileCheck::_check: Array should contain 13 elements" ); |
220
|
|
|
|
|
|
|
|
221
|
374
|
100
|
|
|
|
|
if ( av_size > 0 ) { |
222
|
372
|
|
|
|
|
|
*size = av_size; /* store the av_size */ |
223
|
|
|
|
|
|
|
|
224
|
372
|
|
|
|
|
|
ary = AvARRAY(stat_array); |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
/* fill the stat struct */ |
227
|
372
|
50
|
|
|
|
|
set_stat_from_aryix( stat->st_dev, 0 ); /* IV */ |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
228
|
368
|
50
|
|
|
|
|
set_stat_from_aryix( stat->st_ino, 1 ); /* IV or UV : neg = PL_statcache.st_ino < 0 */ |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
229
|
368
|
50
|
|
|
|
|
set_stat_from_aryix( stat->st_mode, 2 ); /* UV */ |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
230
|
368
|
50
|
|
|
|
|
set_stat_from_aryix( stat->st_nlink, 3 ); /* UV */ |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
231
|
368
|
50
|
|
|
|
|
set_stat_from_aryix( stat->st_uid, 4 ); /* IV ? */ |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
232
|
368
|
50
|
|
|
|
|
set_stat_from_aryix( stat->st_gid, 5 ); /* IV ? */ |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
233
|
368
|
50
|
|
|
|
|
set_stat_from_aryix( stat->st_rdev, 6 ); /* IV or PV */ |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
234
|
368
|
50
|
|
|
|
|
set_stat_from_aryix( stat->st_size, 7 ); /* NV or IV */ |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
235
|
368
|
50
|
|
|
|
|
set_stat_from_aryix( stat->st_atime, 8 ); /* NV or IV */ |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
236
|
368
|
50
|
|
|
|
|
set_stat_from_aryix( stat->st_mtime, 9 ); /* NV or IV */ |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
237
|
368
|
50
|
|
|
|
|
set_stat_from_aryix( stat->st_ctime, 10 ); /* NV or IV */ |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
238
|
368
|
50
|
|
|
|
|
set_stat_from_aryix( stat->st_blksize, 11 ); /* UV or PV */ |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
239
|
368
|
50
|
|
|
|
|
set_stat_from_aryix( stat->st_blocks, 12 ); /* UV or PV */ |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
240
|
|
|
|
|
|
|
} |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
|
244
|
371
|
|
|
|
|
|
PUTBACK; |
245
|
371
|
50
|
|
|
|
|
FREETMPS; |
246
|
371
|
|
|
|
|
|
LEAVE; |
247
|
|
|
|
|
|
|
|
248
|
371
|
|
|
|
|
|
return check_status; |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
/* a generic OP to overload the FT OPs returning yes or no */ |
253
|
|
|
|
|
|
|
/* FIXME also need to handle undef */ |
254
|
1523
|
|
|
|
|
|
PP(pp_overload_ft_yes_no) { |
255
|
|
|
|
|
|
|
int check_status; |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
assert( gl_overload_ft ); |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
/* not currently mocked */ |
260
|
1523
|
100
|
|
|
|
|
RETURN_CALL_REAL_OP_IF_UNMOCK(); |
261
|
763
|
100
|
|
|
|
|
RETURN_CALL_REAL_OP_IF_CALL_WITH_DEFGV(); |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
262
|
|
|
|
|
|
|
|
263
|
733
|
|
|
|
|
|
check_status = _overload_ft_ops(); |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
{ |
266
|
|
|
|
|
|
|
FT_SETUP_dSP_IF_NEEDED; |
267
|
|
|
|
|
|
|
|
268
|
733
|
100
|
|
|
|
|
if ( check_status == 1 ) FT_RETURNYES; |
269
|
329
|
100
|
|
|
|
|
if ( check_status == 0 ) FT_RETURNUNDEF; |
270
|
|
|
|
|
|
|
/* if ( check_status == -1 ) FT_RETURNUNDEF; */ /* TODO */ |
271
|
|
|
|
|
|
|
} |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
/* fallback */ |
274
|
134
|
|
|
|
|
|
return CALL_REAL_OP(); |
275
|
|
|
|
|
|
|
} |
276
|
|
|
|
|
|
|
|
277
|
75
|
|
|
|
|
|
PP(pp_overload_ft_int) { |
278
|
|
|
|
|
|
|
int check_status; |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
assert( gl_overload_ft ); |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
/* not currently mocked */ |
283
|
75
|
100
|
|
|
|
|
RETURN_CALL_REAL_OP_IF_UNMOCK(); |
284
|
44
|
100
|
|
|
|
|
RETURN_CALL_REAL_OP_IF_CALL_WITH_DEFGV(); |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
285
|
|
|
|
|
|
|
|
286
|
38
|
|
|
|
|
|
check_status = _overload_ft_ops(); |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
/* SETERRNO(EEXIST,RMS_FEX); */ /* TODO */ |
289
|
38
|
100
|
|
|
|
|
if ( check_status == -1 ) |
290
|
8
|
|
|
|
|
|
return CALL_REAL_OP(); |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
{ |
293
|
30
|
|
|
|
|
|
dTARGET; |
294
|
|
|
|
|
|
|
FT_SETUP_dSP_IF_NEEDED; |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
/* TODO this is over simplistic some OPs can return one NV instead of IV */ |
297
|
30
|
|
|
|
|
|
sv_setiv(TARG, (IV) check_status); |
298
|
30
|
|
|
|
|
|
FT_RETURN_TARG; |
299
|
|
|
|
|
|
|
} |
300
|
|
|
|
|
|
|
} |
301
|
|
|
|
|
|
|
|
302
|
178
|
|
|
|
|
|
PP(pp_overload_ft_nv) { |
303
|
|
|
|
|
|
|
SV *status; |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
assert( gl_overload_ft ); |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
/* not currently mocked */ |
308
|
178
|
100
|
|
|
|
|
RETURN_CALL_REAL_OP_IF_UNMOCK(); |
309
|
103
|
100
|
|
|
|
|
RETURN_CALL_REAL_OP_IF_CALL_WITH_DEFGV(); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
310
|
|
|
|
|
|
|
|
311
|
103
|
|
|
|
|
|
status = _overload_ft_ops_sv(); |
312
|
|
|
|
|
|
|
|
313
|
103
|
100
|
|
|
|
|
if ( SvIOK(status) && SvIV(status) == -1 ) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
314
|
0
|
|
|
|
|
|
return CALL_REAL_OP(); |
315
|
|
|
|
|
|
|
|
316
|
103
|
100
|
|
|
|
|
if ( SvNOK(status) && SvNV(status) == -1 ) |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
317
|
16
|
|
|
|
|
|
return CALL_REAL_OP(); |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
{ |
320
|
87
|
|
|
|
|
|
dTARGET; |
321
|
|
|
|
|
|
|
FT_SETUP_dSP_IF_NEEDED; |
322
|
|
|
|
|
|
|
|
323
|
87
|
100
|
|
|
|
|
if ( SvNOK(status) ) |
324
|
75
|
50
|
|
|
|
|
sv_setnv(TARG, (NV) SvNV(status) ); |
325
|
12
|
50
|
|
|
|
|
else if ( SvIOK(status) ) |
326
|
12
|
50
|
|
|
|
|
sv_setiv(TARG, (IV) SvIV(status) ); |
327
|
|
|
|
|
|
|
|
328
|
87
|
|
|
|
|
|
FT_RETURN_TARG; |
329
|
|
|
|
|
|
|
} |
330
|
|
|
|
|
|
|
} |
331
|
|
|
|
|
|
|
|
332
|
478
|
|
|
|
|
|
PP(pp_overload_stat) { /* stat & lstat */ |
333
|
478
|
|
|
|
|
|
Stat_t mocked_stat = { 0 }; /* fake stats */ |
334
|
478
|
|
|
|
|
|
int check_status = 0; |
335
|
|
|
|
|
|
|
int size; |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
assert( gl_overload_ft ); |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
/* not currently mocked */ |
341
|
478
|
100
|
|
|
|
|
RETURN_CALL_REAL_OP_IF_UNMOCK(); |
342
|
391
|
50
|
|
|
|
|
RETURN_CALL_REAL_OP_IF_CALL_WITH_DEFGV(); |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
/* calling with our own tmp stat struct, instead of passing directly PL_statcache: more control */ |
345
|
385
|
|
|
|
|
|
check_status = _overload_ft_stat(&mocked_stat, &size); |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
/* explicit ask for fallback */ |
348
|
371
|
100
|
|
|
|
|
if ( check_status == -1 ) |
349
|
3
|
|
|
|
|
|
return CALL_REAL_OP(); |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
/* |
352
|
|
|
|
|
|
|
* The idea is too fool the stat function |
353
|
|
|
|
|
|
|
* like if it was called by passing _ or *_ |
354
|
|
|
|
|
|
|
* |
355
|
|
|
|
|
|
|
* We are setting these values as if stat was previously called |
356
|
|
|
|
|
|
|
* - PL_laststype |
357
|
|
|
|
|
|
|
* - PL_statcache |
358
|
|
|
|
|
|
|
* - PL_laststatval |
359
|
|
|
|
|
|
|
* - PL_statname |
360
|
|
|
|
|
|
|
* |
361
|
|
|
|
|
|
|
*/ |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
{ |
364
|
368
|
|
|
|
|
|
dSP; |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
/* drop & replace our stack first element with *_ */ |
367
|
|
|
|
|
|
|
/* Unexpected warning: Attempt to free unreferenced scalar: SV 0x119bd80. */ |
368
|
|
|
|
|
|
|
//SV *previous_stack = sv_2mortal(POPs); /* what do we want to do with this ? */ |
369
|
368
|
|
|
|
|
|
SV *previous_stack = POPs; |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
/* copy the content of mocked_stat to PL_statcache */ |
372
|
368
|
|
|
|
|
|
memcpy(&PL_statcache, &mocked_stat, sizeof(PL_statcache)); |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
/* Here, we cut early when stat() returned no values |
375
|
|
|
|
|
|
|
* In such a case, we set the statcache, but do not call |
376
|
|
|
|
|
|
|
* the real op (CALL_REAL_OP) |
377
|
|
|
|
|
|
|
*/ |
378
|
368
|
100
|
|
|
|
|
if ( !size ) |
379
|
2
|
|
|
|
|
|
RETURN; |
380
|
|
|
|
|
|
|
|
381
|
366
|
|
|
|
|
|
PUSHs( MUTABLE_SV( PL_defgv ) ); /* add *_ to the stack */ |
382
|
|
|
|
|
|
|
|
383
|
366
|
50
|
|
|
|
|
if ( size ) { /* yes it succeeds */ |
384
|
366
|
|
|
|
|
|
PL_laststatval = 0; |
385
|
|
|
|
|
|
|
} else { /* the stat call fails */ |
386
|
0
|
|
|
|
|
|
PL_laststatval = -1; |
387
|
|
|
|
|
|
|
} |
388
|
|
|
|
|
|
|
|
389
|
366
|
|
|
|
|
|
PL_laststype = PL_op->op_type; /* this was for our OP */ |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
/* probably not real necesseary, make warning messages nicer */ |
392
|
366
|
50
|
|
|
|
|
if ( previous_stack && SvPOK(previous_stack) ) |
|
|
100
|
|
|
|
|
|
393
|
363
|
100
|
|
|
|
|
sv_setpv(PL_statname, SvPV_nolen(previous_stack) ); |
394
|
|
|
|
|
|
|
|
395
|
464
|
|
|
|
|
|
return CALL_REAL_OP(); |
396
|
|
|
|
|
|
|
} |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
} |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
/* |
401
|
|
|
|
|
|
|
* extract from https://perldoc.perl.org/functions/-X.html |
402
|
|
|
|
|
|
|
* |
403
|
|
|
|
|
|
|
* -r File is readable by effective uid/gid. |
404
|
|
|
|
|
|
|
* -w File is writable by effective uid/gid. |
405
|
|
|
|
|
|
|
* -x File is executable by effective uid/gid. |
406
|
|
|
|
|
|
|
* -o File is owned by effective uid. |
407
|
|
|
|
|
|
|
* -R File is readable by real uid/gid. |
408
|
|
|
|
|
|
|
* -W File is writable by real uid/gid. |
409
|
|
|
|
|
|
|
* -X File is executable by real uid/gid. |
410
|
|
|
|
|
|
|
* -O File is owned by real uid. |
411
|
|
|
|
|
|
|
* -e File exists. |
412
|
|
|
|
|
|
|
* -z File has zero size (is empty). |
413
|
|
|
|
|
|
|
* -s File has nonzero size (returns size in bytes). |
414
|
|
|
|
|
|
|
* -f File is a plain file. |
415
|
|
|
|
|
|
|
* -d File is a directory. |
416
|
|
|
|
|
|
|
* -l File is a symbolic link (false if symlinks aren't |
417
|
|
|
|
|
|
|
* supported by the file system). |
418
|
|
|
|
|
|
|
* -p File is a named pipe (FIFO), or Filehandle is a pipe. |
419
|
|
|
|
|
|
|
* -S File is a socket. |
420
|
|
|
|
|
|
|
* -b File is a block special file. |
421
|
|
|
|
|
|
|
* -c File is a character special file. |
422
|
|
|
|
|
|
|
* -t Filehandle is opened to a tty. |
423
|
|
|
|
|
|
|
* -u File has setuid bit set. |
424
|
|
|
|
|
|
|
* -g File has setgid bit set. |
425
|
|
|
|
|
|
|
* -k File has sticky bit set. |
426
|
|
|
|
|
|
|
* -T File is an ASCII or UTF-8 text file (heuristic guess). |
427
|
|
|
|
|
|
|
* -B File is a "binary" file (opposite of -T). |
428
|
|
|
|
|
|
|
* -M Script start time minus file modification time, in days. |
429
|
|
|
|
|
|
|
* -A Same for access time. |
430
|
|
|
|
|
|
|
* -C Same for inode change time |
431
|
|
|
|
|
|
|
*/ |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
MODULE = Overload__FileCheck PACKAGE = Overload::FileCheck |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
SV* |
436
|
|
|
|
|
|
|
mock_op(optype) |
437
|
|
|
|
|
|
|
SV* optype; |
438
|
|
|
|
|
|
|
ALIAS: |
439
|
|
|
|
|
|
|
Overload::FileCheck::_xs_mock_op = 1 |
440
|
|
|
|
|
|
|
Overload::FileCheck::_xs_unmock_op = 2 |
441
|
|
|
|
|
|
|
CODE: |
442
|
|
|
|
|
|
|
{ |
443
|
|
|
|
|
|
|
/* mylogger = INT2PTR(MyLogger*, SvIV(SvRV(self))); */ |
444
|
884
|
|
|
|
|
|
int opid = 0; |
445
|
|
|
|
|
|
|
|
446
|
884
|
50
|
|
|
|
|
if ( ! SvIOK(optype) ) |
447
|
0
|
|
|
|
|
|
croak("first argument to _xs_mock_op / _xs_unmock_op must be one integer"); |
448
|
|
|
|
|
|
|
|
449
|
884
|
50
|
|
|
|
|
opid = SvIV( optype ); |
450
|
884
|
50
|
|
|
|
|
if ( !opid || opid < 0 || opid >= OP_MAX ) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
451
|
0
|
|
|
|
|
|
croak( "Invalid opid value %d", opid ); |
452
|
|
|
|
|
|
|
|
453
|
884
|
|
|
|
|
|
switch (ix) { |
454
|
|
|
|
|
|
|
case 1: /* _xs_mock_op */ |
455
|
613
|
|
|
|
|
|
gl_overload_ft->op[opid].is_mocked = 1; |
456
|
613
|
|
|
|
|
|
break; |
457
|
|
|
|
|
|
|
case 2: /* _xs_unmock_op */ |
458
|
271
|
|
|
|
|
|
gl_overload_ft->op[opid].is_mocked = 0; |
459
|
271
|
|
|
|
|
|
break; |
460
|
|
|
|
|
|
|
default: |
461
|
0
|
|
|
|
|
|
croak("Unsupported function at index %d", ix); |
462
|
|
|
|
|
|
|
XSRETURN_EMPTY; |
463
|
|
|
|
|
|
|
} |
464
|
|
|
|
|
|
|
|
465
|
884
|
|
|
|
|
|
XSRETURN_EMPTY; |
466
|
|
|
|
|
|
|
} |
467
|
|
|
|
|
|
|
OUTPUT: |
468
|
|
|
|
|
|
|
RETVAL |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
SV* |
472
|
|
|
|
|
|
|
get_basetime() |
473
|
|
|
|
|
|
|
CODE: |
474
|
57
|
|
|
|
|
|
RETVAL = newSViv(PL_basetime); |
475
|
|
|
|
|
|
|
OUTPUT: |
476
|
|
|
|
|
|
|
RETVAL |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
BOOT: |
480
|
47
|
50
|
|
|
|
|
if (!gl_overload_ft) { |
481
|
|
|
|
|
|
|
HV *stash; |
482
|
|
|
|
|
|
|
SV *sv; |
483
|
47
|
|
|
|
|
|
int ix = 0; |
484
|
|
|
|
|
|
|
|
485
|
47
|
|
|
|
|
|
Newxz( gl_overload_ft, 1, OverloadFTOps); |
486
|
|
|
|
|
|
|
|
487
|
47
|
|
|
|
|
|
stash = gv_stashpvn("Overload::FileCheck", 19, TRUE); |
488
|
|
|
|
|
|
|
|
489
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "_loaded", newSViv(1) ); |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
/* provide constants to standardize return values from mocked functions */ |
492
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "CHECK_IS_TRUE", &PL_sv_yes ); /* could use newSViv(1) or &PL_sv_yes */ |
493
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "CHECK_IS_FALSE", &PL_sv_no ); /* could use newSViv(0) or &PL_sv_no */ |
494
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "CHECK_IS_NULL", &PL_sv_undef ); /* FIXME: need to handle this as a valid answer */ |
495
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "FALLBACK_TO_REAL_OP", newSVnv(-1) ); |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
/* provide constants to add entry in a fake stat array */ |
498
|
|
|
|
|
|
|
|
499
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "ST_DEV", newSViv(ix++) ); |
500
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "ST_INO", newSViv(ix++) ); |
501
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "ST_MODE", newSViv(ix++) ); |
502
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "ST_NLINK", newSViv(ix++) ); |
503
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "ST_UID", newSViv(ix++) ); |
504
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "ST_GID", newSViv(ix++) ); |
505
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "ST_RDEV", newSViv(ix++) ); |
506
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "ST_SIZE", newSViv(ix++) ); |
507
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "ST_ATIME", newSViv(ix++) ); |
508
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "ST_MTIME", newSViv(ix++) ); |
509
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "ST_CTIME", newSViv(ix++) ); |
510
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "ST_BLKSIZE", newSViv(ix++) ); |
511
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "ST_BLOCKS", newSViv(ix++) ); |
512
|
|
|
|
|
|
|
assert(STAT_T_MAX == ix); |
513
|
47
|
|
|
|
|
|
newCONSTSUB(stash, "STAT_T_MAX", newSViv(STAT_T_MAX) ); |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
/* copy the original OP then plug our own custom OP function */ |
516
|
|
|
|
|
|
|
/* view pp_sys.c for complete list */ |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
/* PP(pp_ftrread) - yes/no/undef */ |
519
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTRREAD", OP_FTRREAD, &Perl_pp_overload_ft_yes_no); /* -R */ |
520
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTRWRITE", OP_FTRWRITE, &Perl_pp_overload_ft_yes_no); /* -W */ |
521
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTREXEC", OP_FTREXEC, &Perl_pp_overload_ft_yes_no); /* -X */ |
522
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTEREAD", OP_FTEREAD, &Perl_pp_overload_ft_yes_no); /* -r */ |
523
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTEWRITE", OP_FTEWRITE, &Perl_pp_overload_ft_yes_no); /* -w */ |
524
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTEEXEC", OP_FTEEXEC, &Perl_pp_overload_ft_yes_no); /* -x */ |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
/* PP(pp_ftis) - yes/undef/true/false */ |
527
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTIS", OP_FTIS, &Perl_pp_overload_ft_yes_no); /* -e */ |
528
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTSIZE", OP_FTSIZE, &Perl_pp_overload_ft_int); /* -s */ |
529
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTMTIME", OP_FTMTIME, &Perl_pp_overload_ft_nv); /* -M */ |
530
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTCTIME", OP_FTCTIME, &Perl_pp_overload_ft_nv); /* -C */ |
531
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTATIME", OP_FTATIME, &Perl_pp_overload_ft_nv); /* -A */ |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
/* PP(pp_ftrowned) yes/no/undef */ |
534
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTROWNED", OP_FTROWNED, &Perl_pp_overload_ft_yes_no); /* -O */ |
535
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTEOWNED", OP_FTEOWNED, &Perl_pp_overload_ft_yes_no); /* -o */ |
536
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTZERO", OP_FTZERO, &Perl_pp_overload_ft_yes_no); /* -z */ |
537
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTSOCK", OP_FTSOCK, &Perl_pp_overload_ft_yes_no); /* -S */ |
538
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTCHR", OP_FTCHR, &Perl_pp_overload_ft_yes_no); /* -c */ |
539
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTBLK", OP_FTBLK, &Perl_pp_overload_ft_yes_no); /* -b */ |
540
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTFILE", OP_FTFILE, &Perl_pp_overload_ft_yes_no); /* -f */ |
541
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTDIR", OP_FTDIR, &Perl_pp_overload_ft_yes_no); /* -d */ |
542
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTPIPE", OP_FTPIPE, &Perl_pp_overload_ft_yes_no); /* -p */ |
543
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTSUID", OP_FTSUID, &Perl_pp_overload_ft_yes_no); /* -u */ |
544
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTSGID", OP_FTSGID, &Perl_pp_overload_ft_yes_no); /* -g */ |
545
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTSVTX", OP_FTSVTX, &Perl_pp_overload_ft_yes_no); /* -k */ |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
/* PP(pp_ftlink) - yes/no/undef */ |
548
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTLINK", OP_FTLINK, &Perl_pp_overload_ft_yes_no); /* -l */ |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
/* PP(pp_fttty) - yes/no/undef */ |
551
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTTTY", OP_FTTTY, &Perl_pp_overload_ft_yes_no); /* -t */ |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
/* PP(pp_fttext) - yes/no/undef */ |
554
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTTEXT", OP_FTTEXT, &Perl_pp_overload_ft_yes_no); /* -T */ |
555
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_FTBINARY", OP_FTBINARY, &Perl_pp_overload_ft_yes_no); /* -B */ |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
/* PP(pp_stat) also used for: pp_lstat() */ |
558
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_STAT", OP_STAT, &Perl_pp_overload_stat); /* stat */ |
559
|
47
|
|
|
|
|
|
INIT_FILECHECK_MOCK( "OP_LSTAT", OP_LSTAT, &Perl_pp_overload_stat); /* lstat */ |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
} |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
|