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.2 1999/02/28 17:46:31 skimo 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 (!SvTRUEx(perl_get_sv("FCGI::no_warn_redirection", FALSE)))
164 if (PL_warnhook) SvREFCNT_dec(PL_warnhook);
165 PL_warnhook = SvREFCNT_inc(GvCV(gv_fetchmethod(Nullhv, "FCGI::WARN")));
167 if (!SvTRUEx(perl_get_sv("FCGI::no_die_redirection", FALSE)))
169 if (PL_diehook) SvREFCNT_dec(PL_diehook);
170 PL_diehook = SvREFCNT_inc(GvCV(gv_fetchmethod(Nullhv, "FCGI::DIE")));
173 finishCalled = FALSE;
183 if(!acceptCalled || isCGI) {
187 sfdcdelfcgi(sfdisc(PerlIO_stdin(), SF_POPDISC));
188 sfdcdelfcgi(sfdisc(PerlIO_stdout(), SF_POPDISC));
189 sfdcdelfcgi(sfdisc(PerlIO_stderr(), SF_POPDISC));
200 if (!SvTRUEx(perl_get_sv("FCGI::no_warn_redirection", FALSE)) &&
201 PL_warnhook == (SV*)GvCV(gv_fetchmethod(Nullhv, "FCGI::WARN"))) {
202 SvREFCNT_dec(PL_warnhook);
203 PL_warnhook = Nullsv;
205 if (!SvTRUEx(perl_get_sv("FCGI::no_die_redirection", FALSE)) &&
206 PL_diehook == (SV*)GvCV(gv_fetchmethod(Nullhv, "FCGI::DIE"))) {
207 SvREFCNT_dec(PL_diehook);
214 FCGI_StartFilterData(void)
216 return in ? FCGX_StartFilterData(in) : -1;
220 FCGI_SetExitStatus(int status)
222 if (in) FCGX_SetExitStatus(status, in);
226 * For each variable in the array envp, either set or unset it
227 * in the global hash %ENV.
238 hv = perl_get_hv("ENV", TRUE);
241 perl_eval_pv("%ENV = %FCGI::ENV", 0);
243 perl_eval_pv("%FCGI::ENV = %ENV", 0);
245 if((p = envp[i]) == NULL) {
251 sv = newSVpv(p1 + 1, 0);
252 /* call magic for this value ourselves */
253 hv_store(hv, p, p1 - p, sv, 0);
261 typedef FCGX_Stream * FCGI;
263 MODULE = FCGI PACKAGE = FCGI
272 FCGX_PutS(msg, (FCGX_Stream *) SvIV((SV*) SvRV(sverr)));
279 FCGX_PutS(msg, (FCGX_Stream *) SvIV((SV*) SvRV(sverr)));
289 for (n = 1; n < items; ++n) {
291 register char *tmps = (char *)SvPV(ST(n),len);
292 FCGX_PutStr(tmps, len, stream);
294 if (SvTRUEx(perl_get_sv("|", FALSE)))
298 WRITE(stream, bufsv, len, ...)
310 offset = (items == 4) ? (int)SvIV(ST(3)) : 0;
311 buf = SvPV(bufsv, blen);
312 if (offset < 0) offset += blen;
313 if (len > blen - offset)
315 if (offset < 0 || offset >= blen ||
316 (n = FCGX_PutStr(buf+offset, len, stream)) < 0)
317 ST(0) = &PL_sv_undef;
319 ST(0) = sv_newmortal();
320 sv_setpvf(ST(0), "%c", n);
324 READ(stream, bufsv, len, ...)
334 offset = (items == 4) ? (int)SvIV(ST(3)) : 0;
336 sv_setpvn(bufsv, "", 0);
337 buf = SvGROW(bufsv, len+offset+1);
338 len = FCGX_GetStr(buf+offset, len, stream);
339 SvCUR_set(bufsv, len+offset);
340 *SvEND(bufsv) = '\0';
341 (void)SvPOK_only(bufsv);
356 if ((retval = FCGX_GetChar(stream)) != -1) {
357 ST(0) = sv_newmortal();
358 sv_setpvf(ST(0), "%c", retval);
359 } else ST(0) = &PL_sv_undef;
369 RETVAL = FCGX_FClose(stream) != -1;
385 * Unmake Perl variable settings for the request just completed.
387 if(requestEnviron != NULL) {
388 DoPerlEnv(requestEnviron, FALSE);
389 requestEnviron = NULL;
392 * Call FCGI_Accept but preserve environ.
394 savedEnviron = environ;
395 acceptStatus = FCGI_Accept();
396 requestEnviron = environ;
397 environ = savedEnviron;
399 * Make Perl variable settings for the new request.
401 if(acceptStatus >= 0 && !FCGX_IsCGI()) {
402 DoPerlEnv(requestEnviron, TRUE);
404 requestEnviron = NULL;
406 RETVAL = acceptStatus;
419 * Unmake Perl variable settings for the completed request.
421 if(requestEnviron != NULL) {
422 DoPerlEnv(requestEnviron, FALSE);
423 requestEnviron = NULL;
426 * Finish the request.
440 set_exit_status(status)
446 FCGI_SetExitStatus(status);
453 RETVAL = FCGI_StartFilterData();