line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
/* $Id: FCGI.XL,v 1.10 2003/06/22 00:24:11 robs Exp $ */ |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
#include "EXTERN.h" |
4
|
|
|
|
|
|
|
#include "perl.h" |
5
|
|
|
|
|
|
|
#include "XSUB.h" |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
#include "fcgi_config.h" |
8
|
|
|
|
|
|
|
#include "fcgiapp.h" |
9
|
|
|
|
|
|
|
#include "fastcgi.h" |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
#ifndef FALSE |
12
|
|
|
|
|
|
|
#define FALSE (0) |
13
|
|
|
|
|
|
|
#endif |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
#ifndef TRUE |
16
|
|
|
|
|
|
|
#define TRUE (1) |
17
|
|
|
|
|
|
|
#endif |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
#ifndef dTHX |
20
|
|
|
|
|
|
|
#define dTHX |
21
|
|
|
|
|
|
|
#endif |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
#ifndef INT2PTR |
24
|
|
|
|
|
|
|
#define INT2PTR(a,b) ((a) (b)) |
25
|
|
|
|
|
|
|
#endif |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
/* Deprecation added 2010-10-05. The deprecated functionality should not be |
28
|
|
|
|
|
|
|
* removed for at least a year after that. */ |
29
|
|
|
|
|
|
|
#define WIDE_CHAR_DEPRECATION_MSG "Use of wide characters in %s is deprecated" \ |
30
|
|
|
|
|
|
|
" and will stop working in a future version of FCGI" |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
#if defined(USE_ITHREADS) |
33
|
|
|
|
|
|
|
static perl_mutex accept_mutex; |
34
|
|
|
|
|
|
|
#endif |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
typedef struct FCGP_Request { |
37
|
|
|
|
|
|
|
int accepted; |
38
|
|
|
|
|
|
|
int bound; |
39
|
|
|
|
|
|
|
SV* svin; |
40
|
|
|
|
|
|
|
SV* svout; |
41
|
|
|
|
|
|
|
SV* sverr; |
42
|
|
|
|
|
|
|
GV* gv[3]; |
43
|
|
|
|
|
|
|
HV* hvEnv; |
44
|
|
|
|
|
|
|
FCGX_Request* requestPtr; |
45
|
|
|
|
|
|
|
} FCGP_Request; |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
static void FCGI_Finish(FCGP_Request* request); |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
static void |
50
|
0
|
|
|
|
|
|
FCGI_Flush(FCGP_Request* request) { |
51
|
|
|
|
|
|
|
dTHX; |
52
|
0
|
0
|
|
|
|
|
if(!request->bound) |
53
|
0
|
|
|
|
|
|
return; |
54
|
0
|
0
|
|
|
|
|
FCGX_FFlush(INT2PTR(FCGX_Stream *, SvIV((SV*) SvRV(request->svout)))); |
55
|
0
|
0
|
|
|
|
|
FCGX_FFlush(INT2PTR(FCGX_Stream *, SvIV((SV*) SvRV(request->sverr)))); |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
static void |
59
|
2
|
|
|
|
|
|
FCGI_UndoBinding(FCGP_Request* request) { |
60
|
|
|
|
|
|
|
dTHX; |
61
|
|
|
|
|
|
|
#ifdef USE_PERLIO |
62
|
2
|
|
|
|
|
|
sv_unmagic((SV *)GvIOp(request->gv[0]), 'q'); |
63
|
2
|
|
|
|
|
|
sv_unmagic((SV *)GvIOp(request->gv[1]), 'q'); |
64
|
2
|
|
|
|
|
|
sv_unmagic((SV *)GvIOp(request->gv[2]), 'q'); |
65
|
|
|
|
|
|
|
#else |
66
|
|
|
|
|
|
|
sv_unmagic((SV *)request->gv[0], 'q'); |
67
|
|
|
|
|
|
|
sv_unmagic((SV *)request->gv[1], 'q'); |
68
|
|
|
|
|
|
|
sv_unmagic((SV *)request->gv[2], 'q'); |
69
|
|
|
|
|
|
|
#endif |
70
|
2
|
|
|
|
|
|
request->bound = FALSE; |
71
|
2
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
static void |
74
|
2
|
|
|
|
|
|
FCGI_Bind(FCGP_Request* request) { |
75
|
|
|
|
|
|
|
dTHX; |
76
|
|
|
|
|
|
|
#ifdef USE_PERLIO |
77
|
|
|
|
|
|
|
/* For tied filehandles, we apply tiedscalar magic to the IO |
78
|
|
|
|
|
|
|
slot of the GP rather than the GV itself. */ |
79
|
|
|
|
|
|
|
|
80
|
2
|
50
|
|
|
|
|
if (!GvIOp(request->gv[1])) |
81
|
0
|
|
|
|
|
|
GvIOp(request->gv[1]) = newIO(); |
82
|
2
|
50
|
|
|
|
|
if (!GvIOp(request->gv[2])) |
83
|
0
|
|
|
|
|
|
GvIOp(request->gv[2]) = newIO(); |
84
|
2
|
50
|
|
|
|
|
if (!GvIOp(request->gv[0])) |
85
|
0
|
|
|
|
|
|
GvIOp(request->gv[0]) = newIO(); |
86
|
|
|
|
|
|
|
|
87
|
2
|
|
|
|
|
|
sv_magic((SV *)GvIOp(request->gv[1]), request->svout, 'q', Nullch, 0); |
88
|
2
|
|
|
|
|
|
sv_magic((SV *)GvIOp(request->gv[2]), request->sverr, 'q', Nullch, 0); |
89
|
2
|
|
|
|
|
|
sv_magic((SV *)GvIOp(request->gv[0]), request->svin, 'q', Nullch, 0); |
90
|
|
|
|
|
|
|
#else |
91
|
|
|
|
|
|
|
sv_magic((SV *)request->gv[1], request->svout, 'q', Nullch, 0); |
92
|
|
|
|
|
|
|
sv_magic((SV *)request->gv[2], request->sverr, 'q', Nullch, 0); |
93
|
|
|
|
|
|
|
sv_magic((SV *)request->gv[0], request->svin, 'q', Nullch, 0); |
94
|
|
|
|
|
|
|
#endif |
95
|
2
|
|
|
|
|
|
request->bound = TRUE; |
96
|
2
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
static void |
99
|
2
|
|
|
|
|
|
populate_env(char **envp, HV *hv) { |
100
|
|
|
|
|
|
|
int i; |
101
|
|
|
|
|
|
|
char *p, *p1; |
102
|
|
|
|
|
|
|
SV *sv; |
103
|
|
|
|
|
|
|
dTHX; |
104
|
|
|
|
|
|
|
|
105
|
2
|
|
|
|
|
|
hv_clear(hv); |
106
|
2
|
|
|
|
|
|
for(i = 0; ; i++) { |
107
|
6
|
100
|
|
|
|
|
if((p = envp[i]) == NULL) |
108
|
2
|
|
|
|
|
|
break; |
109
|
4
|
|
|
|
|
|
p1 = strchr(p, '='); |
110
|
|
|
|
|
|
|
assert(p1 != NULL); |
111
|
4
|
|
|
|
|
|
sv = newSVpv(p1 + 1, 0); |
112
|
|
|
|
|
|
|
/* call magic for this value ourselves */ |
113
|
4
|
|
|
|
|
|
hv_store(hv, p, p1 - p, sv, 0); |
114
|
4
|
50
|
|
|
|
|
SvSETMAGIC(sv); |
115
|
4
|
|
|
|
|
|
} |
116
|
2
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
static int |
119
|
2
|
|
|
|
|
|
FCGI_IsFastCGI(FCGP_Request* request) { |
120
|
|
|
|
|
|
|
static int isCGI = -1; /* -1: not checked; 0: FCGI; 1: CGI */ |
121
|
|
|
|
|
|
|
|
122
|
2
|
50
|
|
|
|
|
if (request->requestPtr->listen_sock == FCGI_LISTENSOCK_FILENO) { |
123
|
0
|
0
|
|
|
|
|
if (isCGI == -1) |
124
|
0
|
|
|
|
|
|
isCGI = FCGX_IsCGI(); |
125
|
0
|
|
|
|
|
|
return !isCGI; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
/* A explicit socket is being used -> assume FastCGI */ |
129
|
2
|
|
|
|
|
|
return 1; |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
static int |
133
|
2
|
|
|
|
|
|
FCGI_Accept(FCGP_Request* request) { |
134
|
|
|
|
|
|
|
dTHX; |
135
|
|
|
|
|
|
|
|
136
|
2
|
50
|
|
|
|
|
if (!FCGI_IsFastCGI(request)) { |
137
|
|
|
|
|
|
|
static int been_here = 0; |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
/* |
140
|
|
|
|
|
|
|
* Not first call to FCGI_Accept and running as CGI means |
141
|
|
|
|
|
|
|
* application is done. |
142
|
|
|
|
|
|
|
*/ |
143
|
0
|
0
|
|
|
|
|
if (been_here) |
144
|
0
|
|
|
|
|
|
return EOF; |
145
|
0
|
|
|
|
|
|
been_here = 1; |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
else { |
148
|
2
|
|
|
|
|
|
FCGX_Request *fcgx_req = request->requestPtr; |
149
|
|
|
|
|
|
|
int acceptResult; |
150
|
|
|
|
|
|
|
|
151
|
2
|
|
|
|
|
|
FCGI_Finish(request); |
152
|
|
|
|
|
|
|
#if defined(USE_ITHREADS) |
153
|
|
|
|
|
|
|
MUTEX_LOCK(&accept_mutex); |
154
|
|
|
|
|
|
|
#endif |
155
|
2
|
|
|
|
|
|
acceptResult = FCGX_Accept_r(fcgx_req); |
156
|
|
|
|
|
|
|
#if defined(USE_ITHREADS) |
157
|
|
|
|
|
|
|
MUTEX_UNLOCK(&accept_mutex); |
158
|
|
|
|
|
|
|
#endif |
159
|
2
|
50
|
|
|
|
|
if(acceptResult < 0) { |
160
|
0
|
|
|
|
|
|
return acceptResult; |
161
|
|
|
|
|
|
|
} |
162
|
|
|
|
|
|
|
|
163
|
2
|
|
|
|
|
|
populate_env(fcgx_req->envp, request->hvEnv); |
164
|
|
|
|
|
|
|
|
165
|
2
|
100
|
|
|
|
|
if (!request->svout) { |
166
|
1
|
|
|
|
|
|
newSVrv(request->svout = newSV(0), "FCGI::Stream"); |
167
|
1
|
|
|
|
|
|
newSVrv(request->sverr = newSV(0), "FCGI::Stream"); |
168
|
1
|
|
|
|
|
|
newSVrv(request->svin = newSV(0), "FCGI::Stream"); |
169
|
|
|
|
|
|
|
} |
170
|
2
|
|
|
|
|
|
sv_setiv(SvRV(request->svout), INT2PTR(IV, fcgx_req->out)); |
171
|
2
|
|
|
|
|
|
sv_setiv(SvRV(request->sverr), INT2PTR(IV, fcgx_req->err)); |
172
|
2
|
|
|
|
|
|
sv_setiv(SvRV(request->svin), INT2PTR(IV, fcgx_req->in)); |
173
|
2
|
|
|
|
|
|
FCGI_Bind(request); |
174
|
2
|
|
|
|
|
|
request->accepted = TRUE; |
175
|
|
|
|
|
|
|
} |
176
|
2
|
|
|
|
|
|
return 0; |
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
static void |
180
|
3
|
|
|
|
|
|
FCGI_Finish(FCGP_Request* request) { |
181
|
|
|
|
|
|
|
int was_bound; |
182
|
|
|
|
|
|
|
dTHX; |
183
|
|
|
|
|
|
|
|
184
|
3
|
100
|
|
|
|
|
if(!request->accepted) |
185
|
1
|
|
|
|
|
|
return; |
186
|
|
|
|
|
|
|
|
187
|
2
|
50
|
|
|
|
|
if (was_bound = request->bound) |
188
|
2
|
|
|
|
|
|
FCGI_UndoBinding(request); |
189
|
2
|
50
|
|
|
|
|
if (was_bound) |
190
|
2
|
|
|
|
|
|
FCGX_Finish_r(request->requestPtr); |
191
|
|
|
|
|
|
|
else |
192
|
0
|
|
|
|
|
|
FCGX_Free(request->requestPtr, 1); |
193
|
2
|
|
|
|
|
|
request->accepted = FALSE; |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
static int |
197
|
0
|
|
|
|
|
|
FCGI_StartFilterData(FCGP_Request* request) { |
198
|
0
|
|
|
|
|
|
return request->requestPtr->in ? |
199
|
0
|
0
|
|
|
|
|
FCGX_StartFilterData(request->requestPtr->in) : -1; |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
static FCGP_Request * |
203
|
1
|
|
|
|
|
|
FCGI_Request(GV *in, GV *out, GV *err, HV *env, int socket, int flags) { |
204
|
|
|
|
|
|
|
FCGX_Request* fcgx_req; |
205
|
|
|
|
|
|
|
FCGP_Request* req; |
206
|
|
|
|
|
|
|
|
207
|
1
|
|
|
|
|
|
Newz(551, fcgx_req, 1, FCGX_Request); |
208
|
1
|
|
|
|
|
|
FCGX_InitRequest(fcgx_req, socket, flags); |
209
|
1
|
|
|
|
|
|
Newz(551, req, 1, FCGP_Request); |
210
|
1
|
|
|
|
|
|
req->requestPtr = fcgx_req; |
211
|
1
|
|
|
|
|
|
SvREFCNT_inc(in); |
212
|
1
|
|
|
|
|
|
req->gv[0] = in; |
213
|
1
|
|
|
|
|
|
SvREFCNT_inc(out); |
214
|
1
|
|
|
|
|
|
req->gv[1] = out; |
215
|
1
|
|
|
|
|
|
SvREFCNT_inc(err); |
216
|
1
|
|
|
|
|
|
req->gv[2] = err; |
217
|
1
|
|
|
|
|
|
SvREFCNT_inc(env); |
218
|
1
|
|
|
|
|
|
req->hvEnv = env; |
219
|
|
|
|
|
|
|
|
220
|
1
|
|
|
|
|
|
return req; |
221
|
|
|
|
|
|
|
} |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
static void |
224
|
1
|
|
|
|
|
|
FCGI_Release_Request(FCGP_Request *req) { |
225
|
1
|
|
|
|
|
|
SvREFCNT_dec(req->gv[0]); |
226
|
1
|
|
|
|
|
|
SvREFCNT_dec(req->gv[1]); |
227
|
1
|
|
|
|
|
|
SvREFCNT_dec(req->gv[2]); |
228
|
1
|
|
|
|
|
|
SvREFCNT_dec(req->hvEnv); |
229
|
1
|
|
|
|
|
|
FCGI_Finish(req); |
230
|
1
|
|
|
|
|
|
Safefree(req->requestPtr); |
231
|
1
|
|
|
|
|
|
Safefree(req); |
232
|
1
|
|
|
|
|
|
} |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
static void |
235
|
3
|
|
|
|
|
|
FCGI_Init() { |
236
|
|
|
|
|
|
|
#if defined(USE_ITHREADS) |
237
|
|
|
|
|
|
|
dTHX; |
238
|
|
|
|
|
|
|
MUTEX_INIT(&accept_mutex); |
239
|
|
|
|
|
|
|
#endif |
240
|
3
|
|
|
|
|
|
FCGX_Init(); |
241
|
3
|
|
|
|
|
|
} |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
typedef FCGX_Stream* FCGI__Stream; |
244
|
|
|
|
|
|
|
typedef FCGP_Request* FCGI; |
245
|
|
|
|
|
|
|
typedef GV* GLOBREF; |
246
|
|
|
|
|
|
|
typedef HV* HASHREF; |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
MODULE = FCGI PACKAGE = FCGI PREFIX = FCGI_ |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
BOOT: |
251
|
3
|
|
|
|
|
|
FCGI_Init(); |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
SV * |
254
|
|
|
|
|
|
|
RequestX(in, out, err, env, socket, flags) |
255
|
|
|
|
|
|
|
GLOBREF in; |
256
|
|
|
|
|
|
|
GLOBREF out; |
257
|
|
|
|
|
|
|
GLOBREF err; |
258
|
|
|
|
|
|
|
HASHREF env; |
259
|
|
|
|
|
|
|
int socket; |
260
|
|
|
|
|
|
|
int flags; |
261
|
|
|
|
|
|
|
PROTOTYPE: ***$$$ |
262
|
|
|
|
|
|
|
CODE: |
263
|
1
|
|
|
|
|
|
RETVAL = sv_setref_pv(newSV(0), "FCGI", |
264
|
|
|
|
|
|
|
FCGI_Request(in, out, err, env, socket, flags)); |
265
|
|
|
|
|
|
|
OUTPUT: |
266
|
|
|
|
|
|
|
RETVAL |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
int |
269
|
|
|
|
|
|
|
OpenSocket(path, backlog) |
270
|
|
|
|
|
|
|
char* path; |
271
|
|
|
|
|
|
|
int backlog; |
272
|
|
|
|
|
|
|
PROTOTYPE: $$ |
273
|
|
|
|
|
|
|
CODE: |
274
|
2
|
|
|
|
|
|
RETVAL = FCGX_OpenSocket(path, backlog); |
275
|
|
|
|
|
|
|
OUTPUT: |
276
|
|
|
|
|
|
|
RETVAL |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
void |
279
|
|
|
|
|
|
|
CloseSocket(socket) |
280
|
|
|
|
|
|
|
int socket; |
281
|
|
|
|
|
|
|
PROTOTYPE: $ |
282
|
|
|
|
|
|
|
CODE: |
283
|
1
|
|
|
|
|
|
close(socket); |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
int |
286
|
|
|
|
|
|
|
FCGI_Accept(request) |
287
|
|
|
|
|
|
|
FCGI request; |
288
|
|
|
|
|
|
|
PROTOTYPE: $ |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
void |
291
|
|
|
|
|
|
|
FCGI_Finish(request) |
292
|
|
|
|
|
|
|
FCGI request; |
293
|
|
|
|
|
|
|
PROTOTYPE: $ |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
void |
296
|
|
|
|
|
|
|
FCGI_Flush(request) |
297
|
|
|
|
|
|
|
FCGI request; |
298
|
|
|
|
|
|
|
PROTOTYPE: $ |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
HV * |
301
|
|
|
|
|
|
|
GetEnvironment(request) |
302
|
|
|
|
|
|
|
FCGI request; |
303
|
|
|
|
|
|
|
PROTOTYPE: $ |
304
|
|
|
|
|
|
|
CODE: |
305
|
0
|
|
|
|
|
|
RETVAL = request->hvEnv; |
306
|
|
|
|
|
|
|
OUTPUT: |
307
|
|
|
|
|
|
|
RETVAL |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
void |
310
|
|
|
|
|
|
|
GetHandles(request) |
311
|
|
|
|
|
|
|
FCGI request; |
312
|
|
|
|
|
|
|
PROTOTYPE: $ |
313
|
|
|
|
|
|
|
PREINIT: |
314
|
|
|
|
|
|
|
int i; |
315
|
|
|
|
|
|
|
PPCODE: |
316
|
0
|
0
|
|
|
|
|
EXTEND(sp,3); |
317
|
0
|
0
|
|
|
|
|
for (i = 0; i < 3; ++i) |
318
|
0
|
|
|
|
|
|
PUSHs(sv_2mortal(newRV((SV *) request->gv[i]))); |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
int |
321
|
|
|
|
|
|
|
FCGI_IsFastCGI(request) |
322
|
|
|
|
|
|
|
FCGI request; |
323
|
|
|
|
|
|
|
PROTOTYPE: $ |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
void |
326
|
|
|
|
|
|
|
Detach(request) |
327
|
|
|
|
|
|
|
FCGI request; |
328
|
|
|
|
|
|
|
PROTOTYPE: $ |
329
|
|
|
|
|
|
|
CODE: |
330
|
0
|
0
|
|
|
|
|
if (request->accepted && request->bound) { |
|
|
0
|
|
|
|
|
|
331
|
0
|
|
|
|
|
|
FCGI_UndoBinding(request); |
332
|
0
|
|
|
|
|
|
FCGX_Detach(request->requestPtr); |
333
|
|
|
|
|
|
|
} |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
void |
336
|
|
|
|
|
|
|
Attach(request) |
337
|
|
|
|
|
|
|
FCGI request; |
338
|
|
|
|
|
|
|
PROTOTYPE: $ |
339
|
|
|
|
|
|
|
CODE: |
340
|
0
|
0
|
|
|
|
|
if (request->accepted && !request->bound) { |
|
|
0
|
|
|
|
|
|
341
|
0
|
|
|
|
|
|
FCGI_Bind(request); |
342
|
0
|
|
|
|
|
|
FCGX_Attach(request->requestPtr); |
343
|
|
|
|
|
|
|
} |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
void |
346
|
|
|
|
|
|
|
LastCall(request) |
347
|
|
|
|
|
|
|
FCGI request; |
348
|
|
|
|
|
|
|
PROTOTYPE: $ |
349
|
|
|
|
|
|
|
CODE: |
350
|
0
|
|
|
|
|
|
FCGX_ShutdownPending(); |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
int |
353
|
|
|
|
|
|
|
FCGI_StartFilterData(request) |
354
|
|
|
|
|
|
|
FCGI request; |
355
|
|
|
|
|
|
|
PROTOTYPE: $ |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
void |
358
|
|
|
|
|
|
|
DESTROY(request) |
359
|
|
|
|
|
|
|
FCGI request; |
360
|
|
|
|
|
|
|
CODE: |
361
|
1
|
|
|
|
|
|
FCGI_Release_Request(request); |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
MODULE = FCGI PACKAGE = FCGI::Stream |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
SV * |
366
|
|
|
|
|
|
|
PRINT(stream, ...) |
367
|
|
|
|
|
|
|
FCGI::Stream stream; |
368
|
|
|
|
|
|
|
PREINIT: |
369
|
|
|
|
|
|
|
int n; |
370
|
|
|
|
|
|
|
STRLEN len; |
371
|
|
|
|
|
|
|
register char *str; |
372
|
4
|
|
|
|
|
|
bool ok = TRUE; |
373
|
|
|
|
|
|
|
CODE: |
374
|
8
|
50
|
|
|
|
|
for (n = 1; ok && n < items; ++n) { |
|
|
100
|
|
|
|
|
|
375
|
|
|
|
|
|
|
#ifdef DO_UTF8 |
376
|
4
|
50
|
|
|
|
|
if (DO_UTF8(ST(n)) && !sv_utf8_downgrade(ST(n), 1) && ckWARN_d(WARN_UTF8)) |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
377
|
0
|
|
|
|
|
|
Perl_warner(aTHX_ WARN_UTF8, WIDE_CHAR_DEPRECATION_MSG, |
378
|
|
|
|
|
|
|
"FCGI::Stream::PRINT"); |
379
|
|
|
|
|
|
|
#endif |
380
|
4
|
50
|
|
|
|
|
str = (char *)SvPV(ST(n),len); |
381
|
4
|
50
|
|
|
|
|
if (FCGX_PutStr(str, len, stream) < 0) |
382
|
0
|
|
|
|
|
|
ok = FALSE; |
383
|
|
|
|
|
|
|
} |
384
|
4
|
50
|
|
|
|
|
if (ok && SvTRUEx(perl_get_sv("|", FALSE)) && FCGX_FFlush(stream) < 0) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
385
|
0
|
|
|
|
|
|
ok = FALSE; |
386
|
4
|
50
|
|
|
|
|
RETVAL = ok ? &PL_sv_yes : &PL_sv_undef; |
387
|
|
|
|
|
|
|
OUTPUT: |
388
|
|
|
|
|
|
|
RETVAL |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
int |
391
|
|
|
|
|
|
|
WRITE(stream, bufsv, len, ...) |
392
|
|
|
|
|
|
|
FCGI::Stream stream; |
393
|
|
|
|
|
|
|
SV *bufsv; |
394
|
|
|
|
|
|
|
int len; |
395
|
|
|
|
|
|
|
PREINIT: |
396
|
|
|
|
|
|
|
int offset; |
397
|
|
|
|
|
|
|
char *buf; |
398
|
|
|
|
|
|
|
STRLEN blen; |
399
|
|
|
|
|
|
|
int n; |
400
|
|
|
|
|
|
|
CODE: |
401
|
0
|
0
|
|
|
|
|
offset = (items == 4) ? (int)SvIV(ST(3)) : 0; |
|
|
0
|
|
|
|
|
|
402
|
|
|
|
|
|
|
#ifdef DO_UTF8 |
403
|
0
|
0
|
|
|
|
|
if (DO_UTF8(bufsv) && !sv_utf8_downgrade(bufsv, 1) && ckWARN_d(WARN_UTF8)) |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
404
|
0
|
|
|
|
|
|
Perl_warner(aTHX_ WARN_UTF8, WIDE_CHAR_DEPRECATION_MSG, |
405
|
|
|
|
|
|
|
"FCGI::Stream::WRITE"); |
406
|
|
|
|
|
|
|
#endif |
407
|
0
|
0
|
|
|
|
|
buf = SvPV(bufsv, blen); |
408
|
0
|
0
|
|
|
|
|
if (offset < 0) offset += blen; |
409
|
0
|
0
|
|
|
|
|
if (len > blen - offset) |
410
|
0
|
|
|
|
|
|
len = blen - offset; |
411
|
0
|
0
|
|
|
|
|
if (offset < 0 || offset >= blen || |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
412
|
0
|
|
|
|
|
|
(n = FCGX_PutStr(buf+offset, len, stream)) < 0) |
413
|
0
|
|
|
|
|
|
ST(0) = &PL_sv_undef; |
414
|
|
|
|
|
|
|
else { |
415
|
0
|
|
|
|
|
|
ST(0) = sv_newmortal(); |
416
|
0
|
|
|
|
|
|
sv_setiv(ST(0), n); |
417
|
|
|
|
|
|
|
} |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
void |
420
|
|
|
|
|
|
|
READ(stream, bufsv, len, ...) |
421
|
|
|
|
|
|
|
FCGI::Stream stream; |
422
|
|
|
|
|
|
|
SV *bufsv; |
423
|
|
|
|
|
|
|
int len; |
424
|
|
|
|
|
|
|
PREINIT: |
425
|
0
|
|
|
|
|
|
int offset = 0; |
426
|
|
|
|
|
|
|
char *buf; |
427
|
|
|
|
|
|
|
STRLEN blen; |
428
|
|
|
|
|
|
|
CODE: |
429
|
0
|
0
|
|
|
|
|
if (items < 3 || items > 4) |
|
|
0
|
|
|
|
|
|
430
|
0
|
|
|
|
|
|
croak("Usage: FCGI::Stream::READ(STREAM, SCALAR, LENGTH [, OFFSET ])"); |
431
|
0
|
0
|
|
|
|
|
if (len < 0) |
432
|
0
|
|
|
|
|
|
croak("Negative length"); |
433
|
0
|
0
|
|
|
|
|
if (!SvOK(bufsv)) |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
434
|
0
|
|
|
|
|
|
sv_setpvn(bufsv, "", 0); |
435
|
|
|
|
|
|
|
#ifdef DO_UTF8 |
436
|
0
|
0
|
|
|
|
|
if (DO_UTF8(bufsv) && !sv_utf8_downgrade(bufsv, 1) && ckWARN_d(WARN_UTF8)) |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
437
|
0
|
|
|
|
|
|
Perl_warner(aTHX_ WARN_UTF8, WIDE_CHAR_DEPRECATION_MSG, |
438
|
|
|
|
|
|
|
"FCGI::Stream::READ"); |
439
|
|
|
|
|
|
|
#endif |
440
|
0
|
0
|
|
|
|
|
buf = SvPV_force(bufsv, blen); |
441
|
0
|
0
|
|
|
|
|
if (items == 4) { |
442
|
0
|
0
|
|
|
|
|
offset = SvIV(ST(3)); |
443
|
0
|
0
|
|
|
|
|
if (offset < 0) { |
444
|
0
|
0
|
|
|
|
|
if (-offset > (int)blen) |
445
|
0
|
|
|
|
|
|
croak("Offset outside string"); |
446
|
0
|
|
|
|
|
|
offset += blen; |
447
|
|
|
|
|
|
|
} |
448
|
|
|
|
|
|
|
} |
449
|
0
|
0
|
|
|
|
|
buf = SvGROW(bufsv, len + offset + 1); |
|
|
0
|
|
|
|
|
|
450
|
0
|
0
|
|
|
|
|
if (offset > blen) |
451
|
0
|
|
|
|
|
|
Zero(buf + blen, offset - blen, char); |
452
|
0
|
|
|
|
|
|
len = FCGX_GetStr(buf + offset, len, stream); |
453
|
0
|
|
|
|
|
|
SvCUR_set(bufsv, len + offset); |
454
|
0
|
|
|
|
|
|
*SvEND(bufsv) = '\0'; |
455
|
0
|
|
|
|
|
|
(void)SvPOK_only(bufsv); |
456
|
0
|
0
|
|
|
|
|
SvSETMAGIC(bufsv); |
457
|
0
|
|
|
|
|
|
XSRETURN_IV(len); |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
SV * |
460
|
|
|
|
|
|
|
GETC(stream) |
461
|
|
|
|
|
|
|
FCGI::Stream stream; |
462
|
|
|
|
|
|
|
PREINIT: |
463
|
|
|
|
|
|
|
int retval; |
464
|
|
|
|
|
|
|
CODE: |
465
|
0
|
0
|
|
|
|
|
if ((retval = FCGX_GetChar(stream)) != -1) { |
466
|
0
|
|
|
|
|
|
ST(0) = sv_newmortal(); |
467
|
0
|
|
|
|
|
|
sv_setpvf(ST(0), "%c", retval); |
468
|
|
|
|
|
|
|
} |
469
|
|
|
|
|
|
|
else |
470
|
0
|
|
|
|
|
|
ST(0) = &PL_sv_undef; |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
SV * |
473
|
|
|
|
|
|
|
EOF(stream, called=0) |
474
|
|
|
|
|
|
|
FCGI::Stream stream; |
475
|
|
|
|
|
|
|
IV called; |
476
|
|
|
|
|
|
|
CODE: |
477
|
0
|
0
|
|
|
|
|
RETVAL = boolSV(FCGX_HasSeenEOF(stream)); |
478
|
|
|
|
|
|
|
OUTPUT: |
479
|
|
|
|
|
|
|
RETVAL |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
void |
482
|
|
|
|
|
|
|
FILENO(stream) |
483
|
|
|
|
|
|
|
FCGI::Stream stream; |
484
|
|
|
|
|
|
|
CODE: |
485
|
0
|
0
|
|
|
|
|
if (FCGX_HasSeenEOF(stream) != 0) |
486
|
0
|
|
|
|
|
|
XSRETURN_UNDEF; |
487
|
|
|
|
|
|
|
else |
488
|
0
|
|
|
|
|
|
XSRETURN_IV(-1); |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
bool |
491
|
|
|
|
|
|
|
CLOSE(stream) |
492
|
|
|
|
|
|
|
FCGI::Stream stream; |
493
|
|
|
|
|
|
|
CODE: |
494
|
0
|
|
|
|
|
|
RETVAL = FCGX_FClose(stream) != -1; |
495
|
|
|
|
|
|
|
OUTPUT: |
496
|
|
|
|
|
|
|
RETVAL |