Perl: creating input and error streams if closed.
Application handler can do anything with a stream object (including close it). Once the stream is closed, Unit creates a new stream. This closes #616 issue on GitHub.
This commit is contained in:
@@ -28,19 +28,15 @@ typedef struct {
|
||||
} nxt_perl_psgi_ctx_t;
|
||||
|
||||
|
||||
static long nxt_perl_psgi_io_input_read(PerlInterpreter *my_perl,
|
||||
static SSize_t nxt_perl_psgi_io_input_read(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length);
|
||||
static long nxt_perl_psgi_io_input_write(PerlInterpreter *my_perl,
|
||||
static SSize_t nxt_perl_psgi_io_input_write(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length);
|
||||
static long nxt_perl_psgi_io_input_flush(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg);
|
||||
|
||||
static long nxt_perl_psgi_io_error_read(PerlInterpreter *my_perl,
|
||||
static SSize_t nxt_perl_psgi_io_error_read(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length);
|
||||
static long nxt_perl_psgi_io_error_write(PerlInterpreter *my_perl,
|
||||
static SSize_t nxt_perl_psgi_io_error_write(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length);
|
||||
static long nxt_perl_psgi_io_error_flush(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg);
|
||||
|
||||
/*
|
||||
static void nxt_perl_psgi_xs_core_global_changes(PerlInterpreter *my_perl,
|
||||
@@ -57,10 +53,8 @@ static SV *nxt_perl_psgi_call_method(PerlInterpreter *my_perl, SV *obj,
|
||||
/* For currect load XS modules */
|
||||
EXTERN_C void boot_DynaLoader(pTHX_ CV *cv);
|
||||
|
||||
static nxt_int_t nxt_perl_psgi_io_input_init(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg);
|
||||
static nxt_int_t nxt_perl_psgi_io_error_init(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg);
|
||||
static int nxt_perl_psgi_io_init(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg, const char *mode, void *req);
|
||||
|
||||
static int nxt_perl_psgi_ctx_init(const char *script,
|
||||
nxt_perl_psgi_ctx_t *pctx);
|
||||
@@ -125,20 +119,26 @@ NXT_EXPORT nxt_app_module_t nxt_app_module = {
|
||||
nxt_perl_psgi_start,
|
||||
};
|
||||
|
||||
const nxt_perl_psgi_io_tab_t nxt_perl_psgi_io_tab_input = {
|
||||
.read = nxt_perl_psgi_io_input_read,
|
||||
.write = nxt_perl_psgi_io_input_write,
|
||||
};
|
||||
|
||||
static long
|
||||
const nxt_perl_psgi_io_tab_t nxt_perl_psgi_io_tab_error = {
|
||||
.read = nxt_perl_psgi_io_error_read,
|
||||
.write = nxt_perl_psgi_io_error_write,
|
||||
};
|
||||
|
||||
|
||||
static SSize_t
|
||||
nxt_perl_psgi_io_input_read(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length)
|
||||
{
|
||||
nxt_perl_psgi_ctx_t *pctx;
|
||||
|
||||
pctx = arg->pctx;
|
||||
|
||||
return nxt_unit_request_read(pctx->req, vbuf, length);
|
||||
return nxt_unit_request_read(arg->req, vbuf, length);
|
||||
}
|
||||
|
||||
|
||||
static long
|
||||
static SSize_t
|
||||
nxt_perl_psgi_io_input_write(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length)
|
||||
{
|
||||
@@ -146,15 +146,7 @@ nxt_perl_psgi_io_input_write(PerlInterpreter *my_perl,
|
||||
}
|
||||
|
||||
|
||||
static long
|
||||
nxt_perl_psgi_io_input_flush(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static long
|
||||
static SSize_t
|
||||
nxt_perl_psgi_io_error_read(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length)
|
||||
{
|
||||
@@ -162,25 +154,13 @@ nxt_perl_psgi_io_error_read(PerlInterpreter *my_perl,
|
||||
}
|
||||
|
||||
|
||||
static long
|
||||
static SSize_t
|
||||
nxt_perl_psgi_io_error_write(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length)
|
||||
{
|
||||
nxt_perl_psgi_ctx_t *pctx;
|
||||
nxt_unit_req_error(arg->req, "Perl: %s", (const char*) vbuf);
|
||||
|
||||
pctx = arg->pctx;
|
||||
|
||||
nxt_unit_req_error(pctx->req, "Perl: %s", (const char*) vbuf);
|
||||
|
||||
return (long) length;
|
||||
}
|
||||
|
||||
|
||||
static long
|
||||
nxt_perl_psgi_io_error_flush(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg)
|
||||
{
|
||||
return 0;
|
||||
return (SSize_t) length;
|
||||
}
|
||||
|
||||
|
||||
@@ -461,70 +441,49 @@ nxt_perl_psgi_module_create(const char *script)
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_perl_psgi_io_input_init(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg)
|
||||
static int
|
||||
nxt_perl_psgi_io_init(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg, const char *mode, void *req)
|
||||
{
|
||||
SV *io;
|
||||
PerlIO *fp;
|
||||
|
||||
fp = nxt_perl_psgi_layer_stream_fp_create(aTHX_ arg, "r");
|
||||
if (arg->io == NULL) {
|
||||
fp = nxt_perl_psgi_layer_stream_fp_create(aTHX_ arg->rv, mode);
|
||||
if (nxt_slow_path(fp == NULL)) {
|
||||
return NXT_UNIT_ERROR;
|
||||
}
|
||||
|
||||
if (nxt_slow_path(fp == NULL)) {
|
||||
return NXT_ERROR;
|
||||
io = nxt_perl_psgi_layer_stream_io_create(aTHX_ fp);
|
||||
if (nxt_slow_path(io == NULL)) {
|
||||
nxt_perl_psgi_layer_stream_fp_destroy(aTHX_ fp);
|
||||
return NXT_UNIT_ERROR;
|
||||
}
|
||||
|
||||
arg->io = io;
|
||||
arg->fp = fp;
|
||||
}
|
||||
|
||||
io = nxt_perl_psgi_layer_stream_io_create(aTHX_ fp);
|
||||
arg->req = req;
|
||||
|
||||
if (nxt_slow_path(io == NULL)) {
|
||||
nxt_perl_psgi_layer_stream_fp_destroy(aTHX_ fp);
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
arg->io = io;
|
||||
arg->fp = fp;
|
||||
arg->flush = nxt_perl_psgi_io_input_flush;
|
||||
arg->read = nxt_perl_psgi_io_input_read;
|
||||
arg->write = nxt_perl_psgi_io_input_write;
|
||||
|
||||
return NXT_OK;
|
||||
return NXT_UNIT_OK;
|
||||
}
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_perl_psgi_io_error_init(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg)
|
||||
static void
|
||||
nxt_perl_psgi_io_release(PerlInterpreter *my_perl, nxt_perl_psgi_io_arg_t *arg)
|
||||
{
|
||||
SV *io;
|
||||
PerlIO *fp;
|
||||
|
||||
fp = nxt_perl_psgi_layer_stream_fp_create(aTHX_ arg, "w");
|
||||
|
||||
if (nxt_slow_path(fp == NULL)) {
|
||||
return NXT_ERROR;
|
||||
if (arg->io != NULL) {
|
||||
SvREFCNT_dec(arg->io);
|
||||
arg->io = NULL;
|
||||
}
|
||||
|
||||
io = nxt_perl_psgi_layer_stream_io_create(aTHX_ fp);
|
||||
|
||||
if (nxt_slow_path(io == NULL)) {
|
||||
nxt_perl_psgi_layer_stream_fp_destroy(aTHX_ fp);
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
arg->io = io;
|
||||
arg->fp = fp;
|
||||
arg->flush = nxt_perl_psgi_io_error_flush;
|
||||
arg->read = nxt_perl_psgi_io_error_read;
|
||||
arg->write = nxt_perl_psgi_io_error_write;
|
||||
|
||||
return NXT_OK;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
nxt_perl_psgi_ctx_init(const char *script, nxt_perl_psgi_ctx_t *pctx)
|
||||
{
|
||||
int status;
|
||||
int status, res;
|
||||
char *run_module;
|
||||
PerlInterpreter *my_perl;
|
||||
|
||||
@@ -577,19 +536,27 @@ nxt_perl_psgi_ctx_init(const char *script, nxt_perl_psgi_ctx_t *pctx)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pctx->arg_input.pctx = pctx;
|
||||
pctx->arg_input.rv = newSV_type(SVt_RV);
|
||||
sv_setptrref(pctx->arg_input.rv, &pctx->arg_input);
|
||||
SvSETMAGIC(pctx->arg_input.rv);
|
||||
|
||||
status = nxt_perl_psgi_io_input_init(my_perl, &pctx->arg_input);
|
||||
if (nxt_slow_path(status != NXT_OK)) {
|
||||
pctx->arg_input.io_tab = &nxt_perl_psgi_io_tab_input;
|
||||
|
||||
res = nxt_perl_psgi_io_init(my_perl, &pctx->arg_input, "r", NULL);
|
||||
if (nxt_slow_path(res != NXT_UNIT_OK)) {
|
||||
nxt_unit_alert(NULL, "PSGI: Failed to init io.psgi.input");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pctx->arg_error.pctx = pctx;
|
||||
pctx->arg_error.rv = newSV_type(SVt_RV);
|
||||
sv_setptrref(pctx->arg_error.rv, &pctx->arg_error);
|
||||
SvSETMAGIC(pctx->arg_error.rv);
|
||||
|
||||
status = nxt_perl_psgi_io_error_init(my_perl, &pctx->arg_error);
|
||||
if (nxt_slow_path(status != NXT_OK)) {
|
||||
nxt_unit_alert(NULL, "PSGI: Failed to init io.psgi.errors");
|
||||
pctx->arg_error.io_tab = &nxt_perl_psgi_io_tab_error;
|
||||
|
||||
res = nxt_perl_psgi_io_init(my_perl, &pctx->arg_error, "w", NULL);
|
||||
if (nxt_slow_path(res != NXT_UNIT_OK)) {
|
||||
nxt_unit_alert(NULL, "PSGI: Failed to init io.psgi.error");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -607,6 +574,9 @@ nxt_perl_psgi_ctx_init(const char *script, nxt_perl_psgi_ctx_t *pctx)
|
||||
|
||||
fail:
|
||||
|
||||
nxt_perl_psgi_io_release(my_perl, &pctx->arg_input);
|
||||
nxt_perl_psgi_io_release(my_perl, &pctx->arg_error);
|
||||
|
||||
if (run_module != NULL) {
|
||||
nxt_unit_free(NULL, run_module);
|
||||
}
|
||||
@@ -614,6 +584,8 @@ fail:
|
||||
perl_destruct(my_perl);
|
||||
perl_free(my_perl);
|
||||
|
||||
pctx->my_perl = NULL;
|
||||
|
||||
return NXT_UNIT_ERROR;
|
||||
}
|
||||
|
||||
@@ -672,21 +644,25 @@ nxt_perl_psgi_env_create(PerlInterpreter *my_perl,
|
||||
r->tls ? newSVpv("https", 5)
|
||||
: newSVpv("http", 4)));
|
||||
|
||||
RC(nxt_perl_psgi_io_init(my_perl, &pctx->arg_input, "r", req));
|
||||
RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.input"),
|
||||
SvREFCNT_inc(pctx->arg_input.io)));
|
||||
SvREFCNT_inc(pctx->arg_input.io)));
|
||||
|
||||
RC(nxt_perl_psgi_io_init(my_perl, &pctx->arg_error, "w", req));
|
||||
RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.errors"),
|
||||
SvREFCNT_inc(pctx->arg_error.io)));
|
||||
SvREFCNT_inc(pctx->arg_error.io)));
|
||||
|
||||
RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.multithread"),
|
||||
nxt_perl_psgi_ctxs != NULL
|
||||
? &PL_sv_yes : &PL_sv_no));
|
||||
nxt_perl_psgi_ctxs != NULL
|
||||
? &PL_sv_yes : &PL_sv_no));
|
||||
RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.multiprocess"),
|
||||
&PL_sv_yes));
|
||||
&PL_sv_yes));
|
||||
RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.run_once"),
|
||||
&PL_sv_no));
|
||||
&PL_sv_no));
|
||||
RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.nonblocking"),
|
||||
&PL_sv_no));
|
||||
&PL_sv_no));
|
||||
RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.streaming"),
|
||||
&PL_sv_yes));
|
||||
&PL_sv_yes));
|
||||
|
||||
RC(nxt_perl_psgi_add_sptr(my_perl, hash_env, NL("QUERY_STRING"),
|
||||
&r->query, r->query_length));
|
||||
@@ -1447,11 +1423,11 @@ nxt_perl_psgi_ctx_free(nxt_perl_psgi_ctx_t *pctx)
|
||||
|
||||
PERL_SET_CONTEXT(my_perl);
|
||||
|
||||
nxt_perl_psgi_layer_stream_io_destroy(aTHX_ pctx->arg_input.io);
|
||||
nxt_perl_psgi_layer_stream_fp_destroy(aTHX_ pctx->arg_input.fp);
|
||||
SvREFCNT_dec(pctx->arg_input.rv);
|
||||
SvREFCNT_dec(pctx->arg_error.rv);
|
||||
|
||||
nxt_perl_psgi_layer_stream_io_destroy(aTHX_ pctx->arg_error.io);
|
||||
nxt_perl_psgi_layer_stream_fp_destroy(aTHX_ pctx->arg_error.fp);
|
||||
nxt_perl_psgi_io_release(my_perl, &pctx->arg_input);
|
||||
nxt_perl_psgi_io_release(my_perl, &pctx->arg_error);
|
||||
|
||||
perl_destruct(my_perl);
|
||||
perl_free(my_perl);
|
||||
|
||||
@@ -93,11 +93,9 @@ nxt_perl_psgi_layer_stream_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg,
|
||||
unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t);
|
||||
|
||||
if (arg != NULL && SvOK(arg)) {
|
||||
unit_stream->var = arg;
|
||||
unit_stream->var = SvREFCNT_inc(arg);
|
||||
}
|
||||
|
||||
SvSETMAGIC(unit_stream->var);
|
||||
|
||||
return PerlIOBase_pushed(aTHX_ f, mode, Nullsv, tab);
|
||||
}
|
||||
|
||||
@@ -105,11 +103,17 @@ nxt_perl_psgi_layer_stream_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg,
|
||||
static IV
|
||||
nxt_perl_psgi_layer_stream_popped(pTHX_ PerlIO *f)
|
||||
{
|
||||
nxt_perl_psgi_io_arg_t *arg;
|
||||
nxt_perl_psgi_layer_stream_t *unit_stream;
|
||||
|
||||
unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t);
|
||||
|
||||
if (unit_stream->var != NULL) {
|
||||
arg = (void *) (intptr_t) SvIV(SvRV(unit_stream->var));
|
||||
|
||||
arg->io = NULL;
|
||||
arg->fp = NULL;
|
||||
|
||||
SvREFCNT_dec(unit_stream->var);
|
||||
unit_stream->var = Nullsv;
|
||||
}
|
||||
@@ -181,9 +185,6 @@ nxt_perl_psgi_layer_stream_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
|
||||
return 0;
|
||||
}
|
||||
|
||||
unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t);
|
||||
arg = (nxt_perl_psgi_io_arg_t *) (intptr_t) SvIV(SvRV(unit_stream->var));
|
||||
|
||||
if ((PerlIOBase(f)->flags & PERLIO_F_CANREAD) == 0) {
|
||||
PerlIOBase(f)->flags |= PERLIO_F_ERROR;
|
||||
|
||||
@@ -192,7 +193,10 @@ nxt_perl_psgi_layer_stream_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (SSize_t) arg->read(PERL_GET_CONTEXT, arg, vbuf, count);
|
||||
unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t);
|
||||
arg = (void *) (intptr_t) SvIV(SvRV(unit_stream->var));
|
||||
|
||||
return arg->io_tab->read(PERL_GET_CONTEXT, arg, vbuf, count);
|
||||
}
|
||||
|
||||
|
||||
@@ -204,13 +208,10 @@ nxt_perl_psgi_layer_stream_write(pTHX_ PerlIO *f,
|
||||
nxt_perl_psgi_layer_stream_t *unit_stream;
|
||||
|
||||
if (PerlIOBase(f)->flags & PERLIO_F_CANWRITE) {
|
||||
|
||||
unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t);
|
||||
arg = (void *) (intptr_t) SvIV(SvRV(unit_stream->var));
|
||||
|
||||
arg = (nxt_perl_psgi_io_arg_t *)
|
||||
(intptr_t) SvIV(SvRV(unit_stream->var));
|
||||
|
||||
return (SSize_t) arg->write(PERL_GET_CONTEXT, arg, vbuf, count);
|
||||
return arg->io_tab->write(PERL_GET_CONTEXT, arg, vbuf, count);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -244,13 +245,7 @@ nxt_perl_psgi_layer_stream_fill(pTHX_ PerlIO *f)
|
||||
static IV
|
||||
nxt_perl_psgi_layer_stream_flush(pTHX_ PerlIO *f)
|
||||
{
|
||||
nxt_perl_psgi_io_arg_t *arg;
|
||||
nxt_perl_psgi_layer_stream_t *unit_stream;
|
||||
|
||||
unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t);
|
||||
arg = (nxt_perl_psgi_io_arg_t *) (intptr_t) SvIV(SvRV(unit_stream->var));
|
||||
|
||||
return (IV) arg->flush(PERL_GET_CONTEXT, arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -346,29 +341,11 @@ nxt_perl_psgi_layer_stream_init(pTHX)
|
||||
|
||||
|
||||
PerlIO *
|
||||
nxt_perl_psgi_layer_stream_fp_create(pTHX_ nxt_perl_psgi_io_arg_t *arg,
|
||||
nxt_perl_psgi_layer_stream_fp_create(pTHX_ SV *arg_rv,
|
||||
const char *mode)
|
||||
{
|
||||
SV *arg_rv;
|
||||
PerlIO *fp;
|
||||
|
||||
arg_rv = newSV_type(SVt_RV);
|
||||
|
||||
if (arg_rv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sv_setptrref(arg_rv, arg);
|
||||
|
||||
fp = PerlIO_openn(aTHX_ "NGINX_Unit_PSGI_Layer_Stream",
|
||||
mode, 0, 0, 0, NULL, 1, &arg_rv);
|
||||
|
||||
if (fp == NULL) {
|
||||
SvREFCNT_dec(arg_rv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fp;
|
||||
return PerlIO_openn(aTHX_ "NGINX_Unit_PSGI_Layer_Stream",
|
||||
mode, 0, 0, 0, NULL, 1, &arg_rv);
|
||||
}
|
||||
|
||||
|
||||
@@ -403,10 +380,3 @@ nxt_perl_psgi_layer_stream_io_create(pTHX_ PerlIO *fp)
|
||||
|
||||
return rvio;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nxt_perl_psgi_layer_stream_io_destroy(pTHX_ SV *rvio)
|
||||
{
|
||||
SvREFCNT_dec(rvio);
|
||||
}
|
||||
|
||||
@@ -14,35 +14,35 @@
|
||||
#include <perliol.h>
|
||||
|
||||
|
||||
typedef struct nxt_perl_psgi_io_tab_s nxt_perl_psgi_io_tab_t;
|
||||
typedef struct nxt_perl_psgi_io_arg_s nxt_perl_psgi_io_arg_t;
|
||||
|
||||
typedef long (*nxt_perl_psgi_io_read_f)(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length);
|
||||
typedef long (*nxt_perl_psgi_io_write_f)(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length);
|
||||
typedef long (*nxt_perl_psgi_io_arg_f)(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg);
|
||||
|
||||
struct nxt_perl_psgi_io_tab_s {
|
||||
SSize_t (*read)(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length);
|
||||
SSize_t (*write)(PerlInterpreter *my_perl,
|
||||
nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length);
|
||||
};
|
||||
|
||||
|
||||
struct nxt_perl_psgi_io_arg_s {
|
||||
SV *io;
|
||||
PerlIO *fp;
|
||||
SV *rv;
|
||||
SV *io;
|
||||
PerlIO *fp;
|
||||
|
||||
nxt_perl_psgi_io_arg_f flush;
|
||||
nxt_perl_psgi_io_read_f read;
|
||||
nxt_perl_psgi_io_write_f write;
|
||||
const nxt_perl_psgi_io_tab_t *io_tab;
|
||||
|
||||
void *pctx;
|
||||
void *req;
|
||||
};
|
||||
|
||||
|
||||
void nxt_perl_psgi_layer_stream_init(pTHX);
|
||||
|
||||
PerlIO *nxt_perl_psgi_layer_stream_fp_create(pTHX_ nxt_perl_psgi_io_arg_t *arg,
|
||||
PerlIO *nxt_perl_psgi_layer_stream_fp_create(pTHX_ SV *arg_rv,
|
||||
const char *mode);
|
||||
void nxt_perl_psgi_layer_stream_fp_destroy(pTHX_ PerlIO *io);
|
||||
|
||||
SV *nxt_perl_psgi_layer_stream_io_create(pTHX_ PerlIO *fp);
|
||||
void nxt_perl_psgi_layer_stream_io_destroy(pTHX_ SV *rvio);
|
||||
|
||||
#endif /* _NXT_PERL_PSGI_LAYER_H_INCLUDED_ */
|
||||
|
||||
Reference in New Issue
Block a user