Switch PRINT back to void and use XSRETURN_UNDEF/XSRETURN_YES - chansen
[catagits/fcgi2.git] / perl / FCGI.XL
index 3c6067e..4e8e552 100644 (file)
@@ -12,7 +12,7 @@ unless ($] >= 5.005) {
 print OUT while <DATA>;
 close OUT;
 __END__
-/* $Id: FCGI.XL,v 1.3 2001/08/28 19:06:50 robs Exp $ */
+/* $Id: FCGI.XL,v 1.10 2003/06/22 00:24:11 robs Exp $ */
 
 #include "EXTERN.h"
 #include "perl.h"
@@ -34,6 +34,10 @@ __END__
 #define dTHX
 #endif
 
+#ifndef INT2PTR
+#define INT2PTR(a,b) ((a) (b))
+#endif
+
 #ifdef USE_SFIO
 typedef struct
 {
@@ -122,8 +126,8 @@ FCGI_Flush(FCGP_Request* request)
     sfsync(IoOFP(GvIOp(request->gv[1])));
     sfsync(IoOFP(GvIOp(request->gv[2])));
 #else
-    FCGX_FFlush((FCGX_Stream *) SvIV((SV*) SvRV(request->svout)));
-    FCGX_FFlush((FCGX_Stream *) SvIV((SV*) SvRV(request->sverr)));
+    FCGX_FFlush(INT2PTR(FCGX_Stream *, SvIV((SV*) SvRV(request->svout))));
+    FCGX_FFlush(INT2PTR(FCGX_Stream *, SvIV((SV*) SvRV(request->sverr))));
 #endif
 }
 
@@ -137,9 +141,15 @@ FCGI_UndoBinding(FCGP_Request* request)
     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;
 }
@@ -154,9 +164,25 @@ FCGI_Bind(FCGP_Request* request)
     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;
 }
@@ -256,9 +282,9 @@ FCGI_Accept(FCGP_Request* request)
            newSVrv(request->sverr = newSV(0), "FCGI::Stream");
            newSVrv(request->svin = newSV(0), "FCGI::Stream");
        }
-       sv_setiv(SvRV(request->svout), (IV) fcgx_req->out);
-       sv_setiv(SvRV(request->sverr), (IV) fcgx_req->err);
-       sv_setiv(SvRV(request->svin), (IV) fcgx_req->in);
+       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;
@@ -321,9 +347,13 @@ FCGI_Request(in, out, err, env, socket, flags)
     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;
@@ -332,6 +362,10 @@ FCGI_Request(in, out, err, env, socket, flags)
 static void
 FCGI_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);
@@ -448,26 +482,36 @@ FCGI_IsFastCGI(request)
 
 void
 Detach(request)
-
     FCGI    request;
 
     PROTOTYPE: $
 
     CODE:
-    if (request->accepted && request->bound)
-       FCGI_UndoBinding(request);
+    if (request->accepted && request->bound) {
+        FCGI_UndoBinding(request);
+        FCGX_Detach(request->requestPtr);
+    }
 
 void
 Attach(request)
-
     FCGI    request;
 
     PROTOTYPE: $
 
     CODE:
-    if (request->accepted && !request->bound)
-       FCGI_Bind(request);
+    if (request->accepted && !request->bound) {
+        FCGI_Bind(request);
+        FCGX_Attach(request->requestPtr);
+    }
+
+void
+LastCall(request)
+    FCGI    request;
+
+    PROTOTYPE: $
 
+    CODE:
+    FCGX_ShutdownPending();
 
 int
 FCGI_StartFilterData(request)
@@ -494,16 +538,30 @@ PRINT(stream, ...)
        FCGI::Stream    stream;
 
        PREINIT:
-       int     n;
+    int n, sum = 0, ret = 0;
+    STRLEN len;
+    register char *str;
 
        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))) 
+    for (n = 1; n < items; ++n) {
+#ifdef DO_UTF8
+            if (DO_UTF8(ST(n)) && !sv_utf8_downgrade(ST(n), 1))
+                croak("Wide character in FCGI::Stream::PRINT");
+#endif
+        str = (char *)SvPV(ST(n),len);
+        if ((ret = FCGX_PutStr(str, len, stream)) < 0)
+            break;
+
+        sum += ret;
+    }
+
+    if (sum == 0 && ret < 0)
+        XSRETURN_UNDEF;
+
+
+       if (SvTRUEx(perl_get_sv("|", FALSE)))
            FCGX_FFlush(stream);
+    XSRETURN_YES;
 
 int
 WRITE(stream, bufsv, len, ...)
@@ -519,6 +577,10 @@ WRITE(stream, bufsv, len, ...)
 
        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");
+#endif
        buf = SvPV(bufsv, blen);
        if (offset < 0) offset += blen;
        if (len > blen - offset)
@@ -528,7 +590,7 @@ WRITE(stream, bufsv, len, ...)
            ST(0) = &PL_sv_undef;
        else {
            ST(0) = sv_newmortal();
-           sv_setpvf(ST(0), "%c", n);
+           sv_setiv(ST(0), n);
        }
 
 int
@@ -543,6 +605,10 @@ READ(stream, bufsv, len, ...)
 
        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::READ");
+#endif
        if (! SvOK(bufsv))
            sv_setpvn(bufsv, "", 0);
        buf = SvGROW(bufsv, len+offset+1);