5 print "Generating FCGI.xs for Perl version $]\n";
6 #unless (exists $Config{apiversion} && $Config{apiversion} >= 5.005)
8 for (qw(sv_undef diehook warnhook in_eval)) {
9 print OUT "#define PL_$_ $_\n"
12 print OUT while <DATA>;
15 /* $Id: FCGI.PL,v 1.9 1999/07/31 21:54:46 skimo Exp $ */
39 sffcgiread(f, buf, n, disc)
40 Sfio_t* f; /* stream involved */
41 Void_t* buf; /* buffer to read into */
42 size_t n; /* number of bytes to read */
43 Sfdisc_t* disc; /* discipline */
45 return FCGX_GetStr(buf, n, ((FCGI_Disc *)disc)->stream);
49 sffcgiwrite(f, buf, n, disc)
50 Sfio_t* f; /* stream involved */
51 const Void_t* buf; /* buffer to read into */
52 size_t n; /* number of bytes to read */
53 Sfdisc_t* disc; /* discipline */
55 n = FCGX_PutStr(buf, n, ((FCGI_Disc *)disc)->stream);
56 FCGX_FFlush(((FCGI_Disc *)disc)->stream);
66 New(1000,disc,1,FCGI_Disc);
67 if (!disc) return (Sfdisc_t *)disc;
69 disc->disc.exceptf = (Sfexcept_f)NULL;
70 disc->disc.seekf = (Sfseek_f)NULL;
71 disc->disc.readf = sffcgiread;
72 disc->disc.writef = sffcgiwrite;
73 disc->stream = stream;
74 return (Sfdisc_t *)disc;
86 static int isCGI = -1; /* -1: not checked; 0: FCGI; 1: FCGI */
88 typedef struct FCGP_Request {
98 FCGX_Request* requestPtr;
105 FCGI_Flush(FCGP_Request* request)
107 if(!request->acceptCalled || isCGI) {
111 sfsync(IoOFP(GvIOp(request->gv[1])));
112 sfsync(IoOFP(GvIOp(request->gv[2])));
114 FCGX_FFlush((FCGX_Stream *) SvIV((SV*) SvRV(request->svout)));
115 FCGX_FFlush((FCGX_Stream *) SvIV((SV*) SvRV(request->sverr)));
120 FCGI_UndoBinding(FCGP_Request* request)
128 sfdcdelfcgi(sfdisc(IoIFP(io[0] = GvIOp(request->gv[0])), SF_POPDISC));
129 sfdcdelfcgi(sfdisc(IoOFP(io[1] = GvIOp(request->gv[1])), SF_POPDISC));
130 sfdcdelfcgi(sfdisc(IoOFP(io[2] = GvIOp(request->gv[2])), SF_POPDISC));
131 for (i = 0; i < 3; ++i) {
132 if (request->sfcreated[i]) {
133 sfclose(IoIFP(io[i]));
134 IoIFP(io[i]) = IoOFP(io[i]) = Nullfp;
135 request->sfcreated[i] = FALSE;
140 sv_unmagic((SV *)request->gv[0], 'q');
141 sv_unmagic((SV *)request->gv[1], 'q');
142 sv_unmagic((SV *)request->gv[2], 'q');
147 FCGI_Accept(FCGP_Request* request)
151 * First call to FCGI_Accept. Is application running
152 * as FastCGI or as CGI?
154 isCGI = FCGX_IsCGI();
157 * Not first call to FCGI_Accept and running as CGI means
158 * application is done.
162 if(request->acceptCalled && !request->finishCalled) {
163 FCGI_UndoBinding(request);
170 FCGX_Stream *out, *error;
171 FCGX_ParamArray envp;
172 int acceptResult = FCGX_Accept_r(&request->in, &out, &error,
173 &envp, request->requestPtr);
174 if(acceptResult < 0) {
178 populate_env(envp, request->hvEnv);
181 for (i = 0; i < 3; ++i) {
182 io[i] = GvIOn(request->gv[i] = request->gvNew[i]);
183 if (!(i == 0 ? IoIFP(io[i]) : IoOFP(io[i]))) {
184 IoIFP(io[i]) = sftmp(0);
185 /*IoIFP(io[i]) = sfnew(NULL, NULL, SF_UNBOUND, 0,
186 SF_STRING | (i ? SF_WRITE : SF_READ));*/
187 if (i != 0) IoOFP(io[i]) = IoIFP(io[i]);
188 request->sfcreated[i] = TRUE;
191 sfdisc(IoIFP(io[0]), sfdcnewfcgi(request->in));
192 sfdisc(IoOFP(io[1]), sfdcnewfcgi(out));
193 sfdisc(IoOFP(io[2]), sfdcnewfcgi(error));
195 if (!request->svout) {
196 newSVrv(request->svout = newSV(0), "FCGI::Stream");
197 newSVrv(request->sverr = newSV(0), "FCGI::Stream");
198 newSVrv(request->svin = newSV(0), "FCGI::Stream");
200 sv_magic((SV *)request->gv[1] = request->gvNew[1],
201 request->svout, 'q', Nullch, 0);
202 sv_magic((SV *)request->gv[2] = request->gvNew[2],
203 request->sverr, 'q', Nullch, 0);
204 sv_magic((SV *)request->gv[0] = request->gvNew[0],
205 request->svin, 'q', Nullch, 0);
206 sv_setiv(SvRV(request->svout), (IV) out);
207 sv_setiv(SvRV(request->sverr), (IV) error);
208 sv_setiv(SvRV(request->svin), (IV) request->in);
210 request->finishCalled = FALSE;
212 request->acceptCalled = TRUE;
217 FCGI_Finish(FCGP_Request* request)
219 if(!request->acceptCalled || isCGI) {
222 FCGI_UndoBinding(request);
224 FCGX_Finish_r(request->requestPtr);
225 request->finishCalled = TRUE;
229 FCGI_StartFilterData(FCGP_Request* request)
231 return request->in ? FCGX_StartFilterData(request->in) : -1;
235 FCGI_SetExitStatus(FCGP_Request* request, int status)
237 if (request->in) FCGX_SetExitStatus(status, request->in);
240 static FCGP_Request *
243 FCGX_Request* fcgx_req;
246 Newz(551, fcgx_req, 1, FCGX_Request);
247 Newz(551, req, 1, FCGP_Request);
248 req->requestPtr = fcgx_req;
254 FCGI_Release_Request(FCGP_Request *req)
256 Safefree(req->requestPtr);
261 populate_env(envp, hv)
270 if((p = envp[i]) == NULL) {
275 sv = newSVpv(p1 + 1, 0);
276 /* call magic for this value ourselves */
277 hv_store(hv, p, p1 - p, sv, 0);
282 typedef FCGX_Stream * FCGI__Stream;
283 typedef FCGP_Request * FCGI;
287 MODULE = FCGI PACKAGE = FCGI
295 RETVAL = Perl_sv_setref_pv(Perl_newSV(0), "FCGI", FCGI_Request());
302 Accept(request, in, out, err, env)
313 request->gvNew[0] = in;
314 request->gvNew[1] = out;
315 request->gvNew[2] = err;
316 request->hvEnv = env;
318 RETVAL = FCGI_Accept(request);
334 * Finish the request.
336 FCGI_Finish(request);
352 StartFilterData(request)
359 RETVAL = FCGI_StartFilterData(request);
369 FCGI_Release_Request(request);
373 MODULE = FCGI PACKAGE = FCGI::Stream
385 for (n = 1; n < items; ++n) {
387 register char *tmps = (char *)SvPV(ST(n),len);
388 FCGX_PutStr(tmps, len, stream);
390 if (SvTRUEx(perl_get_sv("|", FALSE)))
394 WRITE(stream, bufsv, len, ...)
406 offset = (items == 4) ? (int)SvIV(ST(3)) : 0;
407 buf = SvPV(bufsv, blen);
408 if (offset < 0) offset += blen;
409 if (len > blen - offset)
411 if (offset < 0 || offset >= blen ||
412 (n = FCGX_PutStr(buf+offset, len, stream)) < 0)
413 ST(0) = &PL_sv_undef;
415 ST(0) = sv_newmortal();
416 sv_setpvf(ST(0), "%c", n);
420 READ(stream, bufsv, len, ...)
430 offset = (items == 4) ? (int)SvIV(ST(3)) : 0;
432 sv_setpvn(bufsv, "", 0);
433 buf = SvGROW(bufsv, len+offset+1);
434 len = FCGX_GetStr(buf+offset, len, stream);
435 SvCUR_set(bufsv, len+offset);
436 *SvEND(bufsv) = '\0';
437 (void)SvPOK_only(bufsv);
452 if ((retval = FCGX_GetChar(stream)) != -1) {
453 ST(0) = sv_newmortal();
454 sv_setpvf(ST(0), "%c", retval);
455 } else ST(0) = &PL_sv_undef;
465 RETVAL = FCGX_FClose(stream) != -1;