#unless (exists $Config{apiversion} && $Config{apiversion} >= 5.005)
unless ($] >= 5.005) {
for (qw(sv_undef diehook warnhook in_eval)) {
- print OUT "#define PL_$_ $_\n"
+ print OUT "#define PL_$_ $_\n"
}
}
print OUT while <DATA>;
#define INT2PTR(a,b) ((a) (b))
#endif
-#ifdef USE_SFIO
-typedef struct
-{
- Sfdisc_t disc;
- FCGX_Stream *stream;
-} FCGI_Disc;
-
-static ssize_t
-sffcgiread(f, buf, n, disc)
-Sfio_t* f; /* stream involved */
-Void_t* buf; /* buffer to read into */
-size_t n; /* number of bytes to read */
-Sfdisc_t* disc; /* discipline */
-{
- return FCGX_GetStr(buf, n, ((FCGI_Disc *)disc)->stream);
-}
-
-static ssize_t
-sffcgiwrite(f, buf, n, disc)
-Sfio_t* f; /* stream involved */
-const Void_t* buf; /* buffer to read into */
-size_t n; /* number of bytes to read */
-Sfdisc_t* disc; /* discipline */
-{
- n = FCGX_PutStr(buf, n, ((FCGI_Disc *)disc)->stream);
- FCGX_FFlush(((FCGI_Disc *)disc)->stream);
- return n;
-}
-
-Sfdisc_t *
-sfdcnewfcgi(stream)
- FCGX_Stream *stream;
-{
- FCGI_Disc* disc;
-
- New(1000,disc,1,FCGI_Disc);
- if (!disc) return (Sfdisc_t *)disc;
-
- disc->disc.exceptf = (Sfexcept_f)NULL;
- disc->disc.seekf = (Sfseek_f)NULL;
- disc->disc.readf = sffcgiread;
- disc->disc.writef = sffcgiwrite;
- disc->stream = stream;
- return (Sfdisc_t *)disc;
-}
-
-Sfdisc_t *
-sfdcdelfcgi(disc)
- Sfdisc_t* disc;
-{
- Safefree(disc);
- return 0;
-}
-#endif
+/* Deprecation added 2010-10-05. The deprecated functionality should not be
+ * removed for at least a year after that. */
+#define WIDE_CHAR_DEPRECATION_MSG "Use of wide characters in %s is deprecated" \
+ " and will stop wprking in a future version of FCGI"
#if defined(USE_LOCKING) && defined(USE_THREADS)
-static perl_mutex accept_mutex;
+static perl_mutex accept_mutex;
#endif
typedef struct FCGP_Request {
- int accepted;
- int bound;
- SV* svin;
- SV* svout;
- SV* sverr;
- GV* gv[3];
- HV* hvEnv;
+ int accepted;
+ int bound;
+ SV* svin;
+ SV* svout;
+ SV* sverr;
+ GV* gv[3];
+ HV* hvEnv;
FCGX_Request* requestPtr;
-#ifdef USE_SFIO
- int sfcreated[3];
- IO* io[3];
-#endif
} FCGP_Request;
static void FCGI_Finish(FCGP_Request* request);
static void
-FCGI_Flush(FCGP_Request* request)
-{
+FCGI_Flush(FCGP_Request* request) {
dTHX;
-
- if(!request->bound) {
- return;
- }
-#ifdef USE_SFIO
- sfsync(IoOFP(GvIOp(request->gv[1])));
- sfsync(IoOFP(GvIOp(request->gv[2])));
-#else
+ if(!request->bound)
+ return;
FCGX_FFlush(INT2PTR(FCGX_Stream *, SvIV((SV*) SvRV(request->svout))));
FCGX_FFlush(INT2PTR(FCGX_Stream *, SvIV((SV*) SvRV(request->sverr))));
-#endif
}
static void
-FCGI_UndoBinding(FCGP_Request* request)
-{
+FCGI_UndoBinding(FCGP_Request* request) {
dTHX;
-
-#ifdef USE_SFIO
- sfdcdelfcgi(sfdisc(IoIFP(request->io[0]), SF_POPDISC));
- sfdcdelfcgi(sfdisc(IoOFP(request->io[1]), SF_POPDISC));
- sfdcdelfcgi(sfdisc(IoOFP(request->io[2]), SF_POPDISC));
-#else
-# ifdef USE_PERLIO
+#ifdef USE_PERLIO
sv_unmagic((SV *)GvIOp(request->gv[0]), 'q');
sv_unmagic((SV *)GvIOp(request->gv[1]), 'q');
sv_unmagic((SV *)GvIOp(request->gv[2]), 'q');
-# else
+#else
sv_unmagic((SV *)request->gv[0], 'q');
sv_unmagic((SV *)request->gv[1], 'q');
sv_unmagic((SV *)request->gv[2], 'q');
-# endif
#endif
request->bound = FALSE;
}
static void
-FCGI_Bind(FCGP_Request* request)
-{
+FCGI_Bind(FCGP_Request* request) {
dTHX;
-
-#ifdef USE_SFIO
- sfdisc(IoIFP(request->io[0]), sfdcnewfcgi(request->requestPtr->in));
- sfdisc(IoOFP(request->io[1]), sfdcnewfcgi(request->requestPtr->out));
- sfdisc(IoOFP(request->io[2]), sfdcnewfcgi(request->requestPtr->err));
-#else
-# ifdef USE_PERLIO
+#ifdef USE_PERLIO
/* For tied filehandles, we apply tiedscalar magic to the IO
slot of the GP rather than the GV itself. */
if (!GvIOp(request->gv[1]))
- GvIOp(request->gv[1]) = newIO();
+ GvIOp(request->gv[1]) = newIO();
if (!GvIOp(request->gv[2]))
- GvIOp(request->gv[2]) = newIO();
+ GvIOp(request->gv[2]) = newIO();
if (!GvIOp(request->gv[0]))
- GvIOp(request->gv[0]) = newIO();
+ GvIOp(request->gv[0]) = newIO();
sv_magic((SV *)GvIOp(request->gv[1]), request->svout, 'q', Nullch, 0);
sv_magic((SV *)GvIOp(request->gv[2]), request->sverr, 'q', Nullch, 0);
sv_magic((SV *)GvIOp(request->gv[0]), request->svin, 'q', Nullch, 0);
-# else
+#else
sv_magic((SV *)request->gv[1], request->svout, 'q', Nullch, 0);
sv_magic((SV *)request->gv[2], request->sverr, 'q', Nullch, 0);
sv_magic((SV *)request->gv[0], request->svin, 'q', Nullch, 0);
-# endif
#endif
request->bound = TRUE;
}
static void
-populate_env(envp, hv)
-char **envp;
-HV *hv;
-{
+populate_env(char **envp, HV *hv) {
int i;
char *p, *p1;
- SV *sv;
+ SV *sv;
dTHX;
hv_clear(hv);
for(i = 0; ; i++) {
- if((p = envp[i]) == NULL) {
- break;
- }
- p1 = strchr(p, '=');
- assert(p1 != NULL);
- sv = newSVpv(p1 + 1, 0);
- /* call magic for this value ourselves */
- hv_store(hv, p, p1 - p, sv, 0);
- SvSETMAGIC(sv);
+ if((p = envp[i]) == NULL)
+ break;
+ p1 = strchr(p, '=');
+ assert(p1 != NULL);
+ sv = newSVpv(p1 + 1, 0);
+ /* call magic for this value ourselves */
+ hv_store(hv, p, p1 - p, sv, 0);
+ SvSETMAGIC(sv);
}
}
static int
-FCGI_IsFastCGI(FCGP_Request* request)
-{
+FCGI_IsFastCGI(FCGP_Request* request) {
static int isCGI = -1; /* -1: not checked; 0: FCGI; 1: CGI */
if (request->requestPtr->listen_sock == FCGI_LISTENSOCK_FILENO) {
- if (isCGI == -1)
- isCGI = FCGX_IsCGI();
- return !isCGI;
+ if (isCGI == -1)
+ isCGI = FCGX_IsCGI();
+ return !isCGI;
}
/* A explicit socket is being used -> assume FastCGI */
}
static int
-FCGI_Accept(FCGP_Request* request)
-{
+FCGI_Accept(FCGP_Request* request) {
dTHX;
if (!FCGI_IsFastCGI(request)) {
- static int been_here = 0;
+ static int been_here = 0;
/*
- * Not first call to FCGI_Accept and running as CGI means
- * application is done.
- */
- if (been_here)
- return EOF;
-
- been_here = 1;
- } else {
-#ifdef USE_SFIO
- int i;
-#endif
- FCGX_Request *fcgx_req = request->requestPtr;
+ * Not first call to FCGI_Accept and running as CGI means
+ * application is done.
+ */
+ if (been_here)
+ return EOF;
+ been_here = 1;
+ }
+ else {
+ FCGX_Request *fcgx_req = request->requestPtr;
int acceptResult;
- FCGI_Finish(request);
+ FCGI_Finish(request);
#if defined(USE_LOCKING) && defined(USE_THREADS)
- MUTEX_LOCK(&accept_mutex);
+ MUTEX_LOCK(&accept_mutex);
#endif
- acceptResult = FCGX_Accept_r(fcgx_req);
+ acceptResult = FCGX_Accept_r(fcgx_req);
#if defined(USE_LOCKING) && defined(USE_THREADS)
- MUTEX_UNLOCK(&accept_mutex);
+ MUTEX_UNLOCK(&accept_mutex);
#endif
if(acceptResult < 0) {
return acceptResult;
}
- populate_env(fcgx_req->envp, request->hvEnv);
-
-#ifdef USE_SFIO
- for (i = 0; i < 3; ++i) {
- request->io[i] = GvIOn(request->gv[i]);
- if (!(i == 0 ? IoIFP(request->io[i])
- : IoOFP(request->io[i]))) {
- IoIFP(request->io[i]) = sftmp(0);
- /*IoIFP(request->io[i]) = sfnew(NULL, NULL, SF_UNBOUND, 0,
- SF_STRING | (i ? SF_WRITE : SF_READ));*/
- if (i != 0)
- IoOFP(request->io[i]) = IoIFP(request->io[i]);
- request->sfcreated[i] = TRUE;
- }
- }
-#else
- if (!request->svout) {
- newSVrv(request->svout = newSV(0), "FCGI::Stream");
- newSVrv(request->sverr = newSV(0), "FCGI::Stream");
- newSVrv(request->svin = newSV(0), "FCGI::Stream");
- }
- sv_setiv(SvRV(request->svout), INT2PTR(IV, fcgx_req->out));
- sv_setiv(SvRV(request->sverr), INT2PTR(IV, fcgx_req->err));
- sv_setiv(SvRV(request->svin), INT2PTR(IV, fcgx_req->in));
-#endif
- FCGI_Bind(request);
- request->accepted = TRUE;
+ populate_env(fcgx_req->envp, request->hvEnv);
+
+ if (!request->svout) {
+ newSVrv(request->svout = newSV(0), "FCGI::Stream");
+ newSVrv(request->sverr = newSV(0), "FCGI::Stream");
+ newSVrv(request->svin = newSV(0), "FCGI::Stream");
+ }
+ sv_setiv(SvRV(request->svout), INT2PTR(IV, fcgx_req->out));
+ sv_setiv(SvRV(request->sverr), INT2PTR(IV, fcgx_req->err));
+ sv_setiv(SvRV(request->svin), INT2PTR(IV, fcgx_req->in));
+ FCGI_Bind(request);
+ request->accepted = TRUE;
}
return 0;
}
static void
-FCGI_Finish(FCGP_Request* request)
-{
-#ifdef USE_SFIO
- int i;
-#endif
+FCGI_Finish(FCGP_Request* request) {
int was_bound;
dTHX;
- if(!request->accepted) {
- return;
- }
+ if(!request->accepted)
+ return;
- if (was_bound = request->bound) {
- FCGI_UndoBinding(request);
- }
-#ifdef USE_SFIO
- for (i = 0; i < 3; ++i) {
- if (request->sfcreated[i]) {
- sfclose(IoIFP(request->io[i]));
- IoIFP(request->io[i]) = IoOFP(request->io[i]) = Nullfp;
- request->sfcreated[i] = FALSE;
- }
- }
-#endif
+ if (was_bound = request->bound)
+ FCGI_UndoBinding(request);
if (was_bound)
- FCGX_Finish_r(request->requestPtr);
+ FCGX_Finish_r(request->requestPtr);
else
- FCGX_Free(request->requestPtr, 1);
+ FCGX_Free(request->requestPtr, 1);
request->accepted = FALSE;
}
static int
-FCGI_StartFilterData(FCGP_Request* request)
-{
+FCGI_StartFilterData(FCGP_Request* request) {
return request->requestPtr->in ?
- FCGX_StartFilterData(request->requestPtr->in) : -1;
+ FCGX_StartFilterData(request->requestPtr->in) : -1;
}
static FCGP_Request *
-FCGI_Request(in, out, err, env, socket, flags)
- GV* in;
- GV* out;
- GV* err;
- HV* env;
- int socket;
- int flags;
-{
+FCGI_Request(GV *in, GV *out, GV *err, HV *env, int socket, int flags) {
FCGX_Request* fcgx_req;
FCGP_Request* req;
}
static void
-FCGI_Release_Request(FCGP_Request *req)
-{
+FCGI_Release_Request(FCGP_Request *req) {
SvREFCNT_dec(req->gv[0]);
SvREFCNT_dec(req->gv[1]);
SvREFCNT_dec(req->gv[2]);
}
static void
-FCGI_Init()
-{
+FCGI_Init() {
#if defined(USE_LOCKING) && defined(USE_THREADS)
dTHX;
-
MUTEX_INIT(&accept_mutex);
#endif
-
FCGX_Init();
}
-typedef FCGX_Stream * FCGI__Stream;
-typedef FCGP_Request * FCGI;
-typedef GV* GLOBREF;
-typedef HV* HASHREF;
+typedef FCGX_Stream* FCGI__Stream;
+typedef FCGP_Request* FCGI;
+typedef GV* GLOBREF;
+typedef HV* HASHREF;
-MODULE = FCGI PACKAGE = FCGI PREFIX = FCGI_
+MODULE = FCGI PACKAGE = FCGI PREFIX = FCGI_
BOOT:
FCGI_Init();
GLOBREF out;
GLOBREF err;
HASHREF env;
- int socket;
- int flags;
-
- PROTOTYPE: ***$$$
- CODE:
+ int socket;
+ int flags;
+ PROTOTYPE: ***$$$
+ CODE:
RETVAL = sv_setref_pv(newSV(0), "FCGI",
- FCGI_Request(in, out, err, env, socket, flags));
-
- OUTPUT:
+ FCGI_Request(in, out, err, env, socket, flags));
+ OUTPUT:
RETVAL
int
OpenSocket(path, backlog)
char* path;
int backlog;
-
- PROTOTYPE: $$
- CODE:
+ PROTOTYPE: $$
+ CODE:
RETVAL = FCGX_OpenSocket(path, backlog);
- OUTPUT:
+ OUTPUT:
RETVAL
void
CloseSocket(socket)
int socket;
-
- PROTOTYPE: $
- CODE:
+ PROTOTYPE: $
+ CODE:
close(socket);
int
FCGI_Accept(request)
-
FCGI request;
-
- PROTOTYPE: $
+ PROTOTYPE: $
void
FCGI_Finish(request)
- FCGI request;
-
- PROTOTYPE: $
+ FCGI request;
+ PROTOTYPE: $
void
FCGI_Flush(request)
- FCGI request;
-
- PROTOTYPE: $
+ FCGI request;
+ PROTOTYPE: $
HV *
GetEnvironment(request)
- FCGI request;
-
- PROTOTYPE: $
-
- CODE:
+ FCGI request;
+ PROTOTYPE: $
+ CODE:
RETVAL = request->hvEnv;
-
- OUTPUT:
+ OUTPUT:
RETVAL
void
GetHandles(request)
- FCGI request;
-
- PROTOTYPE: $
-
- PREINIT:
- int i;
-
- PPCODE:
+ FCGI request;
+ PROTOTYPE: $
+ PREINIT:
+ int i;
+ PPCODE:
EXTEND(sp,3);
for (i = 0; i < 3; ++i)
- PUSHs(sv_2mortal(newRV((SV *) request->gv[i])));
+ PUSHs(sv_2mortal(newRV((SV *) request->gv[i])));
int
FCGI_IsFastCGI(request)
- FCGI request;
-
- PROTOTYPE: $
+ FCGI request;
+ PROTOTYPE: $
void
Detach(request)
- FCGI request;
-
- PROTOTYPE: $
-
- CODE:
+ FCGI request;
+ PROTOTYPE: $
+ CODE:
if (request->accepted && request->bound) {
FCGI_UndoBinding(request);
FCGX_Detach(request->requestPtr);
void
Attach(request)
- FCGI request;
-
- PROTOTYPE: $
-
- CODE:
+ FCGI request;
+ PROTOTYPE: $
+ CODE:
if (request->accepted && !request->bound) {
FCGI_Bind(request);
FCGX_Attach(request->requestPtr);
void
LastCall(request)
- FCGI request;
-
- PROTOTYPE: $
-
- CODE:
+ FCGI request;
+ PROTOTYPE: $
+ CODE:
FCGX_ShutdownPending();
int
FCGI_StartFilterData(request)
-
- FCGI request;
-
- PROTOTYPE: $
+ FCGI request;
+ PROTOTYPE: $
void
DESTROY(request)
- FCGI request;
-
- CODE:
+ FCGI request;
+ CODE:
FCGI_Release_Request(request);
-
-
-MODULE = FCGI PACKAGE = FCGI::Stream
-
-#ifndef USE_SFIO
+MODULE = FCGI PACKAGE = FCGI::Stream
SV *
PRINT(stream, ...)
- FCGI::Stream stream;
-
- PREINIT:
+ FCGI::Stream stream;
+ PREINIT:
int n;
STRLEN len;
register char *str;
bool ok = TRUE;
-
- CODE:
+ CODE:
for (n = 1; ok && n < items; ++n) {
#ifdef DO_UTF8
- if (DO_UTF8(ST(n)) && !sv_utf8_downgrade(ST(n), 1))
- croak("Wide character in FCGI::Stream::PRINT");
+ if (DO_UTF8(ST(n)) && !sv_utf8_downgrade(ST(n), 1) && ckWARN_d(WARN_UTF8))
+ Perl_warner(aTHX_ WARN_UTF8, WIDE_CHAR_DEPRECATION_MSG,
+ "FCGI::Stream::PRINT");
#endif
str = (char *)SvPV(ST(n),len);
if (FCGX_PutStr(str, len, stream) < 0)
ok = FALSE;
}
-
- if (ok && SvTRUEx(perl_get_sv("|", FALSE)) && FCGX_FFlush(stream) < 0)
- ok = FALSE;
-
+ if (ok && SvTRUEx(perl_get_sv("|", FALSE)) && FCGX_FFlush(stream) < 0)
+ ok = FALSE;
RETVAL = ok ? &PL_sv_yes : &PL_sv_undef;
+ OUTPUT:
+ RETVAL
int
WRITE(stream, bufsv, len, ...)
- FCGI::Stream stream;
- SV * bufsv;
- int len;
-
- PREINIT:
- int offset;
- char * buf;
- STRLEN blen;
- int n;
-
- CODE:
- offset = (items == 4) ? (int)SvIV(ST(3)) : 0;
+ FCGI::Stream stream;
+ SV *bufsv;
+ int len;
+ PREINIT:
+ int offset;
+ char *buf;
+ STRLEN blen;
+ int n;
+ CODE:
+ offset = (items == 4) ? (int)SvIV(ST(3)) : 0;
#ifdef DO_UTF8
- if (DO_UTF8(bufsv) && !sv_utf8_downgrade(bufsv, 1))
- croak("Wide character in FCGI::Stream::WRITE");
+ if (DO_UTF8(bufsv) && !sv_utf8_downgrade(bufsv, 1) && ckWARN_d(WARN_UTF8))
+ Perl_warner(aTHX_ WARN_UTF8, WIDE_CHAR_DEPRECATION_MSG,
+ "FCGI::Stream::WRITE");
#endif
- buf = SvPV(bufsv, blen);
- if (offset < 0) offset += blen;
- if (len > blen - offset)
- len = blen - offset;
- if (offset < 0 || offset >= blen ||
- (n = FCGX_PutStr(buf+offset, len, stream)) < 0)
- ST(0) = &PL_sv_undef;
- else {
- ST(0) = sv_newmortal();
- sv_setiv(ST(0), n);
- }
+ buf = SvPV(bufsv, blen);
+ if (offset < 0) offset += blen;
+ if (len > blen - offset)
+ len = blen - offset;
+ if (offset < 0 || offset >= blen ||
+ (n = FCGX_PutStr(buf+offset, len, stream)) < 0)
+ ST(0) = &PL_sv_undef;
+ else {
+ ST(0) = sv_newmortal();
+ sv_setiv(ST(0), n);
+ }
-int
+void
READ(stream, bufsv, len, ...)
- FCGI::Stream stream;
- SV * bufsv;
- int len;
-
- PREINIT:
- int offset;
- char * buf;
-
- CODE:
- offset = (items == 4) ? (int)SvIV(ST(3)) : 0;
+ FCGI::Stream stream;
+ SV *bufsv;
+ int len;
+ PREINIT:
+ int offset = 0;
+ char *buf;
+ STRLEN blen;
+ CODE:
+ if (items < 3 || items > 4)
+ croak("Usage: FCGI::Stream::READ(STREAM, SCALAR, LENGTH [, OFFSET ])");
+ if (len < 0)
+ croak("Negative length");
+ if (!SvOK(bufsv))
+ sv_setpvn(bufsv, "", 0);
#ifdef DO_UTF8
- if (DO_UTF8(bufsv) && !sv_utf8_downgrade(bufsv, 1))
- croak("Wide character in FCGI::Stream::READ");
+ if (DO_UTF8(bufsv) && !sv_utf8_downgrade(bufsv, 1) && ckWARN_d(WARN_UTF8))
+ Perl_warner(aTHX_ WARN_UTF8, WIDE_CHAR_DEPRECATION_MSG,
+ "FCGI::Stream::READ");
#endif
- if (! SvOK(bufsv))
- sv_setpvn(bufsv, "", 0);
- buf = SvGROW(bufsv, len+offset+1);
- len = FCGX_GetStr(buf+offset, len, stream);
- SvCUR_set(bufsv, len+offset);
- *SvEND(bufsv) = '\0';
- (void)SvPOK_only(bufsv);
- SvSETMAGIC(bufsv);
- RETVAL = len;
-
- OUTPUT:
- RETVAL
+ buf = SvPV_force(bufsv, blen);
+ if (items == 4) {
+ offset = SvIV(ST(3));
+ if (offset < 0) {
+ if (-offset > (int)blen)
+ croak("Offset outside string");
+ offset += blen;
+ }
+ }
+ buf = SvGROW(bufsv, len + offset + 1);
+ if (offset > blen)
+ Zero(buf + blen, offset - blen, char);
+ len = FCGX_GetStr(buf + offset, len, stream);
+ SvCUR_set(bufsv, len + offset);
+ *SvEND(bufsv) = '\0';
+ (void)SvPOK_only(bufsv);
+ SvSETMAGIC(bufsv);
+ XSRETURN_IV(len);
SV *
GETC(stream)
- FCGI::Stream stream;
-
- PREINIT:
- int retval;
-
- CODE:
- if ((retval = FCGX_GetChar(stream)) != -1) {
- ST(0) = sv_newmortal();
- sv_setpvf(ST(0), "%c", retval);
- } else ST(0) = &PL_sv_undef;
+ FCGI::Stream stream;
+ PREINIT:
+ int retval;
+ CODE:
+ if ((retval = FCGX_GetChar(stream)) != -1) {
+ ST(0) = sv_newmortal();
+ sv_setpvf(ST(0), "%c", retval);
+ }
+ else
+ ST(0) = &PL_sv_undef;
bool
CLOSE(stream)
- FCGI::Stream stream;
-
-# ALIAS:
-# DESTROY = 1
-
- CODE:
- RETVAL = FCGX_FClose(stream) != -1;
-
- OUTPUT:
- RETVAL
-
-#endif
+ FCGI::Stream stream;
+ CODE:
+ RETVAL = FCGX_FClose(stream) != -1;
+ OUTPUT:
+ RETVAL