⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fcgi.xl

📁 FastCGI,语言无关的、可伸缩架构的CGI开放扩展
💻 XL
字号:
use Config;open OUT, ">FCGI.xs";print "Generating FCGI.xs for Perl version $]\n";#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 while <DATA>;close OUT;__END__/* $Id: FCGI.XL,v 1.9 2002/11/11 13:51:20 skimo Exp $ */#include "EXTERN.h"#include "perl.h"#include "XSUB.h"#include "fcgi_config.h"#include "fcgiapp.h"#include "fastcgi.h"#ifndef FALSE#define FALSE (0)#endif#ifndef TRUE#define TRUE  (1)#endif#ifndef dTHX#define dTHX#endif#ifndef INT2PTR#define INT2PTR(a,b) ((a) (b))#endif#ifdef USE_SFIOtypedef struct{    Sfdisc_t	disc;    FCGX_Stream	*stream;} FCGI_Disc;static ssize_tsffcgiread(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_tsffcgiwrite(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#if defined(USE_LOCKING) && defined(USE_THREADS)static perl_mutex   accept_mutex;#endiftypedef struct FCGP_Request {    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){    dTHX;    if(!request->bound) {	return;	}#ifdef USE_SFIO    sfsync(IoOFP(GvIOp(request->gv[1])));    sfsync(IoOFP(GvIOp(request->gv[2])));#else    FCGX_FFlush(INT2PTR(FCGX_Stream *, SvIV((SV*) SvRV(request->svout))));    FCGX_FFlush(INT2PTR(FCGX_Stream *, SvIV((SV*) SvRV(request->sverr))));#endif}static voidFCGI_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    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    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 voidFCGI_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    /* 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();    if (!GvIOp(request->gv[2]))	GvIOp(request->gv[2]) = newIO();    if (!GvIOp(request->gv[0]))	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    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 voidpopulate_env(envp, hv)char **envp;HV *hv;{    int i;    char *p, *p1;    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);    }}static intFCGI_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;    }    /* A explicit socket is being used -> assume FastCGI */    return 1;}static int FCGI_Accept(FCGP_Request* request){    dTHX;    if (!FCGI_IsFastCGI(request)) {	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;        int acceptResult;	FCGI_Finish(request);#if defined(USE_LOCKING) && defined(USE_THREADS)	MUTEX_LOCK(&accept_mutex);#endif	acceptResult = FCGX_Accept_r(fcgx_req);#if defined(USE_LOCKING) && defined(USE_THREADS)	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;    }    return 0;}static void FCGI_Finish(FCGP_Request* request){#ifdef USE_SFIO    int i;#endif    int was_bound;    dTHX;    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)	FCGX_Finish_r(request->requestPtr);    else	FCGX_Free(request->requestPtr, 1);    request->accepted = FALSE;}static int FCGI_StartFilterData(FCGP_Request* request){    return request->requestPtr->in ? 	    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;{    FCGX_Request* fcgx_req;    FCGP_Request* req;    Newz(551, fcgx_req, 1, FCGX_Request);    FCGX_InitRequest(fcgx_req, socket, flags);    Newz(551, req, 1, FCGP_Request);    req->requestPtr = fcgx_req;    SvREFCNT_inc(in);    req->gv[0] = in;    SvREFCNT_inc(out);    req->gv[1] = out;    SvREFCNT_inc(err);    req->gv[2] = err;    SvREFCNT_inc(env);    req->hvEnv = env;    return req;}static voidFCGI_Release_Request(FCGP_Request *req){    SvREFCNT_dec(req->gv[0]);    SvREFCNT_dec(req->gv[1]);    SvREFCNT_dec(req->gv[2]);    SvREFCNT_dec(req->hvEnv);    FCGI_Finish(req);    Safefree(req->requestPtr);    Safefree(req);}static voidFCGI_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;MODULE = FCGI		PACKAGE = FCGI	    PREFIX = FCGI_BOOT:    FCGI_Init();SV *RequestX(in, out, err, env, socket, flags)    GLOBREF in;    GLOBREF out;    GLOBREF err;    HASHREF env;    int	    socket;    int	    flags;    PROTOTYPE: ***$$$    CODE:    RETVAL = sv_setref_pv(newSV(0), "FCGI", 		FCGI_Request(in, out, err, env, socket, flags));    OUTPUT:    RETVALintOpenSocket(path, backlog)    char* path;    int backlog;    PROTOTYPE: $$    CODE:    RETVAL = FCGX_OpenSocket(path, backlog);    OUTPUT:    RETVALvoidCloseSocket(socket)    int socket;    PROTOTYPE: $    CODE:    close(socket);intFCGI_Accept(request)    FCGI    request;    PROTOTYPE: $voidFCGI_Finish(request)    FCGI    request;    PROTOTYPE: $voidFCGI_Flush(request)    FCGI    request;    PROTOTYPE: $HV *GetEnvironment(request)    FCGI    request;    PROTOTYPE: $    CODE:    RETVAL = request->hvEnv;    OUTPUT:     RETVALvoidGetHandles(request)    FCGI    request;    PROTOTYPE: $    PREINIT:    int	    i;    PPCODE:    EXTEND(sp,3);    for (i = 0; i < 3; ++i)	PUSHs(sv_2mortal(newRV((SV *) request->gv[i])));intFCGI_IsFastCGI(request)    FCGI    request;    PROTOTYPE: $voidDetach(request)    FCGI    request;    PROTOTYPE: $    CODE:    if (request->accepted && request->bound)	FCGI_UndoBinding(request);voidAttach(request)    FCGI    request;    PROTOTYPE: $    CODE:    if (request->accepted && !request->bound)	FCGI_Bind(request);voidLastCall(request)    FCGI    request;    PROTOTYPE: $    CODE:    FCGX_ShutdownPending();intFCGI_StartFilterData(request)    FCGI    request;    PROTOTYPE: $voidDESTROY(request)    FCGI    request;    CODE:    FCGI_Release_Request(request);MODULE = FCGI		PACKAGE = FCGI::Stream#ifndef USE_SFIOvoidPRINT(stream, ...)	FCGI::Stream	stream;	PREINIT:	int	n;	CODE:	for (n = 1; n < items; ++n) {            STRLEN len;            register char *tmps = (char *)SvPV(ST(n),len);            FCGX_PutStr(tmps, len, stream);	}	if (SvTRUEx(perl_get_sv("|", FALSE))) 	    FCGX_FFlush(stream);intWRITE(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;	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_setpvf(ST(0), "%c", n);	}intREAD(stream, bufsv, len, ...)	FCGI::Stream	stream;	SV *	bufsv;	int	len;	PREINIT:	int	offset;	char *	buf;	CODE:	offset = (items == 4) ? (int)SvIV(ST(3)) : 0;	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:	RETVALSV *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;boolCLOSE(stream)	FCGI::Stream	stream;#	ALIAS:#	DESTROY = 1	CODE:	RETVAL = FCGX_FClose(stream) != -1;	OUTPUT:	RETVAL#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -