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.3 1999/03/08 16:26:04 skimo Exp $ */
32 #define environ _environ
35 extern char **environ;
36 static char **requestEnviron = NULL;
46 sffcgiread(f, buf, n, disc)
47 Sfio_t* f; /* stream involved */
48 Void_t* buf; /* buffer to read into */
49 size_t n; /* number of bytes to read */
50 Sfdisc_t* disc; /* discipline */
52 return FCGX_GetStr(buf, n, ((FCGI_Disc *)disc)->stream);
56 sffcgiwrite(f, buf, n, disc)
57 Sfio_t* f; /* stream involved */
58 const Void_t* buf; /* buffer to read into */
59 size_t n; /* number of bytes to read */
60 Sfdisc_t* disc; /* discipline */
62 n = FCGX_PutStr(buf, n, ((FCGI_Disc *)disc)->stream);
63 FCGX_FFlush(((FCGI_Disc *)disc)->stream);
73 New(1000,disc,1,FCGI_Disc);
74 if (!disc) return (Sfdisc_t *)disc;
76 disc->disc.exceptf = (Sfexcept_f)NULL;
77 disc->disc.seekf = (Sfseek_f)NULL;
78 disc->disc.readf = sffcgiread;
79 disc->disc.writef = sffcgiwrite;
80 disc->stream = stream;
81 return (Sfdisc_t *)disc;
93 static int acceptCalled = FALSE;
94 static int finishCalled = FALSE;
95 static int isCGI = FALSE;
96 static FCGX_Stream *in = NULL;
97 static SV *svout = NULL, *svin, *sverr;
102 if(!acceptCalled || isCGI) {
106 sfsync(PerlIO_stdout());
107 sfsync(PerlIO_stderr());
109 FCGX_FFlush((FCGX_Stream *) SvIV((SV*) SvRV(svout)));
110 FCGX_FFlush((FCGX_Stream *) SvIV((SV*) SvRV(sverr)));
119 * First call to FCGI_Accept. Is application running
120 * as FastCGI or as CGI?
122 isCGI = FCGX_IsCGI();
125 * Not first call to FCGI_Accept and running as CGI means
126 * application is done.
132 sfdcdelfcgi(sfdisc(PerlIO_stdin(), SF_POPDISC));
133 sfdcdelfcgi(sfdisc(PerlIO_stdout(), SF_POPDISC));
134 sfdcdelfcgi(sfdisc(PerlIO_stderr(), SF_POPDISC));
141 FCGX_ParamArray envp;
142 FCGX_Stream *out, *error;
143 int acceptResult = FCGX_Accept(&in, &out, &error, &envp);
144 if(acceptResult < 0) {
148 sfdisc(PerlIO_stdin(), sfdcnewfcgi(in));
149 sfdisc(PerlIO_stdout(), sfdcnewfcgi(out));
150 sfdisc(PerlIO_stderr(), sfdcnewfcgi(error));
153 newSVrv(svout = newSV(0), "FCGI");
154 sv_magic((SV *)gv_fetchpv("STDOUT",TRUE, SVt_PVIO),
155 svout, 'q', Nullch, 0);
156 newSVrv(sverr = newSV(0), "FCGI");
157 sv_magic((SV *)gv_fetchpv("STDERR",TRUE, SVt_PVIO),
158 sverr, 'q', Nullch, 0);
159 newSVrv(svin = newSV(0), "FCGI");
160 sv_magic((SV *)gv_fetchpv("STDIN",TRUE, SVt_PVIO),
161 svin, 'q', Nullch, 0);
163 sv_setiv(SvRV(svout), (IV) out);
164 sv_setiv(SvRV(sverr), (IV) error);
165 sv_setiv(SvRV(svin), (IV) in);
166 if (!SvTRUEx(perl_get_sv("FCGI::no_warn_redirection", FALSE)))
168 if (PL_warnhook) SvREFCNT_dec(PL_warnhook);
169 PL_warnhook = SvREFCNT_inc(GvCV(gv_fetchmethod(Nullhv, "FCGI::WARN")));
171 if (!SvTRUEx(perl_get_sv("FCGI::no_die_redirection", FALSE)))
173 if (PL_diehook) SvREFCNT_dec(PL_diehook);
174 PL_diehook = SvREFCNT_inc(GvCV(gv_fetchmethod(Nullhv, "FCGI::DIE")));
177 finishCalled = FALSE;
187 if(!acceptCalled || isCGI) {
191 sfdcdelfcgi(sfdisc(PerlIO_stdin(), SF_POPDISC));
192 sfdcdelfcgi(sfdisc(PerlIO_stdout(), SF_POPDISC));
193 sfdcdelfcgi(sfdisc(PerlIO_stderr(), SF_POPDISC));
204 if (!SvTRUEx(perl_get_sv("FCGI::no_warn_redirection", FALSE)) &&
205 PL_warnhook == (SV*)GvCV(gv_fetchmethod(Nullhv, "FCGI::WARN"))) {
206 SvREFCNT_dec(PL_warnhook);
207 PL_warnhook = Nullsv;
209 if (!SvTRUEx(perl_get_sv("FCGI::no_die_redirection", FALSE)) &&
210 PL_diehook == (SV*)GvCV(gv_fetchmethod(Nullhv, "FCGI::DIE"))) {
211 SvREFCNT_dec(PL_diehook);
218 FCGI_StartFilterData(void)
220 return in ? FCGX_StartFilterData(in) : -1;
224 FCGI_SetExitStatus(int status)
226 if (in) FCGX_SetExitStatus(status, in);
230 * For each variable in the array envp, either set or unset it
231 * in the global hash %ENV.
242 hv = perl_get_hv("ENV", TRUE);
245 perl_eval_pv("%ENV = %FCGI::ENV", 0);
247 perl_eval_pv("%FCGI::ENV = %ENV", 0);
249 if((p = envp[i]) == NULL) {
255 sv = newSVpv(p1 + 1, 0);
256 /* call magic for this value ourselves */
257 hv_store(hv, p, p1 - p, sv, 0);
265 typedef FCGX_Stream * FCGI;
267 MODULE = FCGI PACKAGE = FCGI
276 FCGX_PutS(msg, (FCGX_Stream *) SvIV((SV*) SvRV(sverr)));
283 FCGX_PutS(msg, (FCGX_Stream *) SvIV((SV*) SvRV(sverr)));
293 for (n = 1; n < items; ++n) {
295 register char *tmps = (char *)SvPV(ST(n),len);
296 FCGX_PutStr(tmps, len, stream);
298 if (SvTRUEx(perl_get_sv("|", FALSE)))
302 WRITE(stream, bufsv, len, ...)
314 offset = (items == 4) ? (int)SvIV(ST(3)) : 0;
315 buf = SvPV(bufsv, blen);
316 if (offset < 0) offset += blen;
317 if (len > blen - offset)
319 if (offset < 0 || offset >= blen ||
320 (n = FCGX_PutStr(buf+offset, len, stream)) < 0)
321 ST(0) = &PL_sv_undef;
323 ST(0) = sv_newmortal();
324 sv_setpvf(ST(0), "%c", n);
328 READ(stream, bufsv, len, ...)
338 offset = (items == 4) ? (int)SvIV(ST(3)) : 0;
340 sv_setpvn(bufsv, "", 0);
341 buf = SvGROW(bufsv, len+offset+1);
342 len = FCGX_GetStr(buf+offset, len, stream);
343 SvCUR_set(bufsv, len+offset);
344 *SvEND(bufsv) = '\0';
345 (void)SvPOK_only(bufsv);
360 if ((retval = FCGX_GetChar(stream)) != -1) {
361 ST(0) = sv_newmortal();
362 sv_setpvf(ST(0), "%c", retval);
363 } else ST(0) = &PL_sv_undef;
373 RETVAL = FCGX_FClose(stream) != -1;
389 * Unmake Perl variable settings for the request just completed.
391 if(requestEnviron != NULL) {
392 DoPerlEnv(requestEnviron, FALSE);
393 requestEnviron = NULL;
396 * Call FCGI_Accept but preserve environ.
398 savedEnviron = environ;
399 acceptStatus = FCGI_Accept();
400 requestEnviron = environ;
401 environ = savedEnviron;
403 * Make Perl variable settings for the new request.
405 if(acceptStatus >= 0 && !FCGX_IsCGI()) {
406 DoPerlEnv(requestEnviron, TRUE);
408 requestEnviron = NULL;
410 RETVAL = acceptStatus;
423 * Unmake Perl variable settings for the completed request.
425 if(requestEnviron != NULL) {
426 DoPerlEnv(requestEnviron, FALSE);
427 requestEnviron = NULL;
430 * Finish the request.
444 set_exit_status(status)
450 FCGI_SetExitStatus(status);
457 RETVAL = FCGI_StartFilterData();