PerlIO_pop
PerlIO_sv_dup
PerlIO_perlio
+ PerlIO_syslayer
Perl_PerlIO_clearerr
Perl_PerlIO_close
#include <sys/mman.h>
#endif
-/*
- * Why is this here - not in perlio.h? RMB
- */
-void PerlIO_debug(const char *fmt, ...)
-#ifdef CHECK_FORMAT
- __attribute__ ((__format__(__printf__, 1, 2)))
-#endif
-;
void
PerlIO_debug(const char *fmt, ...)
return def;
}
+PerlIO *
+PerlIO_syslayer(pTHX_ PerlIO *f)
+{
+ if (PerlIOValid(f)) {
+ PerlIOl *l;
+ while (*PerlIONext(f)) {
+ f = PerlIONext(f);
+ }
+ l = *f;
+#if 0
+ Perl_warn(aTHX_ "syslayer %s",l->tab->name);
+#endif
+ return f;
+ }
+ else {
+ SETERRNO(EBADF, SS_IVCHAN);
+ return NULL;
+ }
+}
+
+
IV
PerlIOPop_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
{
f, PerlIOBase(f)->tab->name, (omode) ? omode : "(Null)",
l->flags, PerlIO_modestr(f, temp));
#endif
+ if (l->next) {
+ l->flags |= l->next->flags &
+ (PERLIO_F_TTY | PERLIO_F_NOTREG | PERLIO_F_SOCKET);
+ }
return 0;
}
PerlIOUnix_setfd(pTHX_ PerlIO *f, int fd, int imode)
{
PerlIOUnix *s = PerlIOSelf(f, PerlIOUnix);
-#if defined(WIN32)
+
+#if 1 || defined(WIN32) || defined(HAS_SOCKET) && \
+ (defined(PERL_SOCK_SYSREAD_IS_RECV) || \
+ defined(PERL_SOCK_SYSWRITE_IS_SEND))
Stat_t st;
if (PerlLIO_fstat(fd, &st) == 0) {
+#if defined(WIN32)
+ /* WIN32 needs to know about non-regular files
+ as only regular files can be lseek()ed
+ */
if (!S_ISREG(st.st_mode)) {
PerlIO_debug("%d is not regular file\n",fd);
PerlIOBase(f)->flags |= PERLIO_F_NOTREG;
else {
PerlIO_debug("%d _is_ a regular file\n",fd);
}
- }
#endif
+ /* If read/write are to be mapped to recv/send we need
+ to know this is a socket.
+ Lifted from code in doio.c that handles socket detection on dup
+ */
+#ifndef PERL_MICRO
+ if (S_ISSOCK(st.st_mode))
+ PerlIOBase(f)->flags |= PERLIO_F_SOCKET;
+ else if (
+#ifdef S_IFMT
+ !(st.st_mode & S_IFMT)
+#else
+ !st.st_mode
+#endif
+ ) {
+ char tmpbuf[256];
+ Sock_size_t buflen = sizeof tmpbuf;
+ if (PerlSock_getsockname(fd, (struct sockaddr *)tmpbuf, &buflen) >= 0
+ || errno != ENOTSOCK)
+ PerlIOBase(f)->flags |= PERLIO_F_SOCKET; /* some OS's return 0 on fstat()ed socket */
+ /* but some return 0 for streams too, sigh */
+ }
+#endif /* !PERL_MICRO */
+ }
+#endif /* HAS_SOCKET ... */
+
s->fd = fd;
s->oflags = imode;
PerlIOUnix_refcnt_inc(fd);
return 0;
}
while (1) {
- SSize_t len = PerlLIO_read(fd, vbuf, count);
+ SSize_t len;
+#ifdef PERL_SOCK_SYSREAD_IS_RECV
+ if (PerlIOBase(f)->flags & PERLIO_F_SOCKET) {
+ len = PerlSock_recv(fd, vbuf, count, 0);
+ }
+ else
+#endif
+ {
+ len = PerlLIO_read(fd, vbuf, count);
+ }
if (len >= 0 || errno != EINTR) {
if (len < 0) {
if (errno != EAGAIN) {
#ifdef PERLIO_LAYERS
extern void PerlIO_cleanup(pTHX);
-extern void PerlIO_debug(const char *fmt, ...);
+extern void PerlIO_debug(const char *fmt, ...)
+#ifdef CHECK_FORMAT
+ __attribute__ ((__format__(__printf__, 1, 2)))
+#endif
+;
+
typedef struct PerlIO_list_s PerlIO_list_t;
+extern PerlIO *PerlIO_syslayer(pTHX_ PerlIO *);
#endif
#define PERLIO_F_OPEN 0x00200000
#define PERLIO_F_FASTGETS 0x00400000
#define PERLIO_F_TTY 0x00800000
-#define PERLIO_F_NOTREG 0x01000000
+#define PERLIO_F_NOTREG 0x01000000
+#define PERLIO_F_SOCKET 0x02000000
#define PerlIOBase(f) (*(f))
#define PerlIOSelf(f,type) ((type *)PerlIOBase(f))
bool charstart = FALSE;
STRLEN charskip = 0;
STRLEN skip = 0;
+ PerlIO *pio;
gv = (GV*)*++MARK;
if ((PL_op->op_type == OP_READ || PL_op->op_type == OP_SYSREAD)
SETERRNO(EBADF,RMS_IFI);
goto say_undef;
}
- if ((fp_utf8 = PerlIO_isutf8(IoIFP(io))) && !IN_BYTES) {
+ pio = IoIFP(io);
+#ifdef PERLIO_LAYERS
+ if (PL_op->op_type == OP_SYSREAD) {
+ /* sysread happens further down the stack
+ and we need isutf8 of that layer
+ */
+ pio = PerlIO_syslayer(aTHX_ pio);
+ if (!pio) {
+ goto say_undef;
+ }
+ }
+#endif
+ if ((fp_utf8 = PerlIO_isutf8(pio)) && !IN_BYTES) {
buffer = SvPVutf8_force(bufsv, blen);
/* UTF8 may not have been set if they are all low bytes */
SvUTF8_on(bufsv);
#endif
buffer = SvGROW(bufsv, (STRLEN)(length+1));
/* 'offset' means 'flags' here */
- count = PerlSock_recvfrom(PerlIO_fileno(IoIFP(io)), buffer, length, offset,
+ count = PerlSock_recvfrom(PerlIO_fileno(pio), buffer, length, offset,
(struct sockaddr *)namebuf, &bufsize);
if (count < 0)
RETPUSHUNDEF;
}
buffer = buffer + offset;
+#ifndef PERLIO_LAYERS
if (PL_op->op_type == OP_SYSREAD) {
#ifdef PERL_SOCK_SYSREAD_IS_RECV
if (IoTYPE(io) == IoTYPE_SOCKET) {
- count = PerlSock_recv(PerlIO_fileno(IoIFP(io)),
+ count = PerlSock_recv(PerlIO_fileno(pio),
buffer, length, 0);
}
else
#endif
{
- count = PerlLIO_read(PerlIO_fileno(IoIFP(io)),
+ count = PerlLIO_read(PerlIO_fileno(pio),
buffer, length);
}
}
else
+#endif
#ifdef HAS_SOCKET__bad_code_maybe
if (IoTYPE(io) == IoTYPE_SOCKET) {
char namebuf[MAXPATHLEN];
#else
bufsize = sizeof namebuf;
#endif
- count = PerlSock_recvfrom(PerlIO_fileno(IoIFP(io)), buffer, length, 0,
+ count = PerlSock_recvfrom(PerlIO_fileno(pio), buffer, length, 0,
(struct sockaddr *)namebuf, &bufsize);
}
else
#endif
{
- count = PerlIO_read(IoIFP(io), buffer, length);
+ count = PerlIO_read(pio, buffer, length);
/* PerlIO_read() - like fread() returns 0 on both error and EOF */
- if (count == 0 && PerlIO_error(IoIFP(io)))
+ if (count == 0 && PerlIO_error(pio))
count = -1;
}
if (count < 0) {