| 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 |