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.1 1999/02/13 05:26:42 roberts Exp $ */
31 extern char **environ;
32 static char **requestEnviron = NULL;
42 sffcgiread(f, buf, n, disc)
43 Sfio_t* f; /* stream involved */
44 Void_t* buf; /* buffer to read into */
45 size_t n; /* number of bytes to read */
46 Sfdisc_t* disc; /* discipline */
48 return FCGX_GetStr(buf, n, ((FCGI_Disc *)disc)->stream);
52 sffcgiwrite(f, buf, n, disc)
53 Sfio_t* f; /* stream involved */
54 const Void_t* buf; /* buffer to read into */
55 size_t n; /* number of bytes to read */
56 Sfdisc_t* disc; /* discipline */
58 n = FCGX_PutStr(buf, n, ((FCGI_Disc *)disc)->stream);
59 FCGX_FFlush(((FCGI_Disc *)disc)->stream);
69 New(1000,disc,1,FCGI_Disc);
70 if (!disc) return (Sfdisc_t *)disc;
72 disc->disc.exceptf = (Sfexcept_f)NULL;
73 disc->disc.seekf = (Sfseek_f)NULL;
74 disc->disc.readf = sffcgiread;
75 disc->disc.writef = sffcgiwrite;
76 disc->stream = stream;
77 return (Sfdisc_t *)disc;
89 static int acceptCalled = FALSE;
90 static int finishCalled = FALSE;
91 static int isCGI = FALSE;
92 static FCGX_Stream *in = NULL;
93 static SV *svout = NULL, *svin, *sverr;
98 if(!acceptCalled || isCGI) {
102 sfsync(PerlIO_stdout());
103 sfsync(PerlIO_stderr());
105 FCGX_FFlush((FCGX_Stream *) SvIV((SV*) SvRV(svout)));
106 FCGX_FFlush((FCGX_Stream *) SvIV((SV*) SvRV(sverr)));
115 * First call to FCGI_Accept. Is application running
116 * as FastCGI or as CGI?
118 isCGI = FCGX_IsCGI();
121 * Not first call to FCGI_Accept and running as CGI means
122 * application is done.
128 sfdcdelfcgi(sfdisc(PerlIO_stdin(), SF_POPDISC));
129 sfdcdelfcgi(sfdisc(PerlIO_stdout(), SF_POPDISC));
130 sfdcdelfcgi(sfdisc(PerlIO_stderr(), SF_POPDISC));
137 FCGX_ParamArray envp;
138 FCGX_Stream *out, *error;
139 int acceptResult = FCGX_Accept(&in, &out, &error, &envp);
140 if(acceptResult < 0) {
144 sfdisc(PerlIO_stdin(), sfdcnewfcgi(in));
145 sfdisc(PerlIO_stdout(), sfdcnewfcgi(out));
146 sfdisc(PerlIO_stderr(), sfdcnewfcgi(error));
149 newSVrv(svout = newSV(0), "FCGI");
150 sv_magic((SV *)gv_fetchpv("STDOUT",TRUE, SVt_PVIO),
151 svout, 'q', Nullch, 0);
152 newSVrv(sverr = newSV(0), "FCGI");
153 sv_magic((SV *)gv_fetchpv("STDERR",TRUE, SVt_PVIO),
154 sverr, 'q', Nullch, 0);
155 newSVrv(svin = newSV(0), "FCGI");
156 sv_magic((SV *)gv_fetchpv("STDIN",TRUE, SVt_PVIO),
157 svin, 'q', Nullch, 0);
159 sv_setiv(SvRV(svout), (IV) out);
160 sv_setiv(SvRV(sverr), (IV) error);
161 sv_setiv(SvRV(svin), (IV) in);
162 if (PL_warnhook) SvREFCNT_dec(PL_warnhook);
163 PL_warnhook = SvREFCNT_inc(GvCV(gv_fetchmethod(Nullhv, "FCGI::WARN")));
164 if (PL_diehook) SvREFCNT_dec(PL_diehook);
165 PL_diehook = SvREFCNT_inc(GvCV(gv_fetchmethod(Nullhv, "FCGI::DIE")));
167 finishCalled = FALSE;
177 if(!acceptCalled || isCGI) {
181 sfdcdelfcgi(sfdisc(PerlIO_stdin(), SF_POPDISC));
182 sfdcdelfcgi(sfdisc(PerlIO_stdout(), SF_POPDISC));
183 sfdcdelfcgi(sfdisc(PerlIO_stderr(), SF_POPDISC));
195 SvREFCNT_dec(PL_warnhook);
196 PL_warnhook = Nullsv;
199 SvREFCNT_dec(PL_diehook);
206 FCGI_StartFilterData(void)
208 return in ? FCGX_StartFilterData(in) : -1;
212 FCGI_SetExitStatus(int status)
214 if (in) FCGX_SetExitStatus(status, in);
218 * For each variable in the array envp, either set or unset it
219 * in the global hash %ENV.
230 hv = perl_get_hv("ENV", TRUE);
233 perl_eval_pv("%ENV = %FCGI::ENV", 0);
235 perl_eval_pv("%FCGI::ENV = %ENV", 0);
237 if((p = envp[i]) == NULL) {
243 sv = newSVpv(p1 + 1, 0);
244 /* call magic for this value ourselves */
245 hv_store(hv, p, p1 - p, sv, 0);
253 typedef FCGX_Stream * FCGI;
255 MODULE = FCGI PACKAGE = FCGI
264 FCGX_PutS(msg, (FCGX_Stream *) SvIV((SV*) SvRV(sverr)));
271 FCGX_PutS(msg, (FCGX_Stream *) SvIV((SV*) SvRV(sverr)));
281 for (n = 1; n < items; ++n) {
283 register char *tmps = (char *)SvPV(ST(n),len);
284 FCGX_PutStr(tmps, len, stream);
286 if (SvTRUEx(perl_get_sv("|", FALSE)))
290 WRITE(stream, bufsv, len, ...)
302 offset = (items == 4) ? (int)SvIV(ST(3)) : 0;
303 buf = SvPV(bufsv, blen);
304 if (offset < 0) offset += blen;
305 if (len > blen - offset)
307 if (offset < 0 || offset >= blen ||
308 (n = FCGX_PutStr(buf+offset, len, stream)) < 0)
309 ST(0) = &PL_sv_undef;
311 ST(0) = sv_newmortal();
312 sv_setpvf(ST(0), "%c", n);
316 READ(stream, bufsv, len, ...)
326 offset = (items == 4) ? (int)SvIV(ST(3)) : 0;
328 sv_setpvn(bufsv, "", 0);
329 buf = SvGROW(bufsv, len+offset+1);
330 len = FCGX_GetStr(buf+offset, len, stream);
331 SvCUR_set(bufsv, len+offset);
332 *SvEND(bufsv) = '\0';
333 (void)SvPOK_only(bufsv);
348 if ((retval = FCGX_GetChar(stream)) != -1) {
349 ST(0) = sv_newmortal();
350 sv_setpvf(ST(0), "%c", retval);
351 } else ST(0) = &PL_sv_undef;
361 RETVAL = FCGX_FClose(stream) != -1;
377 * Unmake Perl variable settings for the request just completed.
379 if(requestEnviron != NULL) {
380 DoPerlEnv(requestEnviron, FALSE);
381 requestEnviron = NULL;
384 * Call FCGI_Accept but preserve environ.
386 savedEnviron = environ;
387 acceptStatus = FCGI_Accept();
388 requestEnviron = environ;
389 environ = savedEnviron;
391 * Make Perl variable settings for the new request.
393 if(acceptStatus >= 0 && !FCGX_IsCGI()) {
394 DoPerlEnv(requestEnviron, TRUE);
396 requestEnviron = NULL;
398 RETVAL = acceptStatus;
411 * Unmake Perl variable settings for the completed request.
413 if(requestEnviron != NULL) {
414 DoPerlEnv(requestEnviron, FALSE);
415 requestEnviron = NULL;
418 * Finish the request.
432 set_exit_status(status)
438 FCGI_SetExitStatus(status);
445 RETVAL = FCGI_StartFilterData();