SV *PerlIONginxInput_newhandle(pTHX_ ngx_http_request_t *r) { ngx_log_t *log = r->connection->log; GV *gv = (GV*)SvREFCNT_inc(newGVgen("Nginx::PSGI::Input")); if (!gv) return &PL_sv_undef; (void) hv_delete(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv), G_DISCARD); /* Body in memory */ if (r->request_body == NULL || r->request_body->temp_file == NULL) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "Open filehandle with 'ngx_input' layer to read from buffers"); PerlIO *f = PerlIO_allocate(aTHX); if (!(f = PerlIO_push(aTHX_ f, PERLIO_FUNCS_CAST(&PerlIO_nginx_input), "<", NULL)) ) { ngx_log_error(NGX_LOG_ERR, log, 0, "Error pushing layer to FH" ); return &PL_sv_undef; } if (!do_open(gv, "+<&", 3, FALSE, O_RDONLY, 0, f)) { ngx_log_error(NGX_LOG_ERR, log, 0, "Error opening GV" ); // FIXME PerlIO_close return &PL_sv_undef; } PerlIONginxInput *st = PerlIOSelf(f, PerlIONginxInput); st->r = r; } else { /* Body in temp file */ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "Open PSGI request body temp file '%s'", r->request_body->temp_file->file.name.data ); bool result = do_open(gv,(char*)r->request_body->temp_file->file.name.data, r->request_body->temp_file->file.name.len,FALSE,O_RDONLY,0,NULL); if (!result) { ngx_log_error(NGX_LOG_ERR, log, 0, "Error opening file" ); // FIXME PerlIO_close return NULL; } } return (SV*)newRV_noinc((SV *)gv); }
SV *PerlIONginxError_newhandle(pTHX_ ngx_http_request_t *r) { GV *gv = (GV*)SvREFCNT_inc(newGVgen("Nginx::PSGI::Error")); if (!gv) return &PL_sv_undef; (void) hv_delete(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv), G_DISCARD); PerlIO *f = PerlIO_allocate(aTHX); if (!(f = PerlIO_push(aTHX_ f, PERLIO_FUNCS_CAST(&PerlIO_nginx_error), ">", NULL)) ) { return &PL_sv_undef; } if (!do_open(gv, "+>&", 3, FALSE, O_WRONLY, 0, f)) { return &PL_sv_undef; } PerlIONginxError *st = PerlIOSelf(f, PerlIONginxError); st->log = r->connection->log; return newRV_noinc((SV*)gv); }
PerlIO * PerlIOWin32_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers, IV n, const char *mode, int fd, int imode, int perm, PerlIO *f, int narg, SV **args) { const char *tmode = mode; HANDLE h = INVALID_HANDLE_VALUE; if (f) { /* Close if already open */ if (PerlIOBase(f)->flags & PERLIO_F_OPEN) (*PerlIOBase(f)->tab->Close)(aTHX_ f); } if (narg > 0) { char *path = SvPV_nolen(*args); DWORD access = 0; /* CRT uses _SH_DENYNO for open(), this the Win32 equivelent */ DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE; DWORD create = -1; DWORD attr = FILE_ATTRIBUTE_NORMAL; if (stricmp(path, "/dev/null")==0) path = "NUL"; if (*mode == '#') { /* sysopen - imode is UNIX-like O_RDONLY etc. - do_open has converted that back to string form in mode as well - perm is UNIX like permissions */ mode++; } else { /* Normal open - decode mode string */ } switch(*mode) { case 'r': access = GENERIC_READ; create = OPEN_EXISTING; if (*++mode == '+') { access |= GENERIC_WRITE; create = OPEN_ALWAYS; mode++; } break; case 'w': access = GENERIC_WRITE; create = TRUNCATE_EXISTING; if (*++mode == '+') { access |= GENERIC_READ; mode++; } break; case 'a': access = GENERIC_WRITE; create = OPEN_ALWAYS; if (*++mode == '+') { access |= GENERIC_READ; mode++; } break; } if (*mode == 'b') { mode++; } else if (*mode == 't') { mode++; } if (*mode || create == -1) { SETERRNO(EINVAL,LIB$_INVARG); return NULL; } h = CreateFile(path,access,share,NULL,create,attr,NULL); if (h == INVALID_HANDLE_VALUE) { if (create == TRUNCATE_EXISTING) h = CreateFile(path,access,share,NULL,(create = OPEN_ALWAYS),attr,NULL); } } else { /* fd open */ h = INVALID_HANDLE_VALUE; if (fd >= 0 && fd <= max_open_fd) { PerlIOWin32 *s = fdtable[fd]; if (s) { s->refcnt++; if (!f) f = PerlIO_allocate(aTHX); *f = &s->base; return f; } } if (*mode == 'I') { mode++; switch(fd) { case 0: h = GetStdHandle(STD_INPUT_HANDLE); break; case 1: h = GetStdHandle(STD_OUTPUT_HANDLE); break; case 2: h = GetStdHandle(STD_ERROR_HANDLE); break; } } } if (h != INVALID_HANDLE_VALUE) fd = win32_open_osfhandle((intptr_t) h, PerlIOUnix_oflags(tmode)); if (fd >= 0) { PerlIOWin32 *s; if (!f) f = PerlIO_allocate(aTHX); s = PerlIOSelf(PerlIO_push(aTHX_ f,self,tmode,PerlIOArg),PerlIOWin32); s->h = h; s->fd = fd; s->refcnt = 1; if (fd >= 0) { fdtable[fd] = s; if (fd > max_open_fd) max_open_fd = fd; } return f; } if (f) { /* FIXME: pop layers ??? */ } return NULL; }