$ref1 == $ref2 without NV_PRESERVES_UV
[p5sagit/p5-mst-13.2.git] / pp_sys.c
index ab43036..d6266dc 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -98,6 +98,12 @@ extern int h_errno;
 #  endif
 #endif
 
+#ifdef I_SYS_UN
+#  ifdef  __linux__
+#    include <sys/un.h>
+#  endif
+#endif
+
 /* Put this after #includes because fork and vfork prototypes may conflict. */
 #ifndef HAS_VFORK
 #   define vfork fork
@@ -1571,6 +1577,13 @@ PP(pp_sysread)
        if (!(IoFLAGS(io) & IOf_UNTAINT))
            SvTAINTED_on(bufsv);
        SP = ORIGMARK;
+#if defined(I_SYS_UN) && defined(__linux__)
+       /* Linux returns the sum of actual pathname string length and the
+          size of the other members of sockaddr_un members. It should
+          return sizeof(struct sockaddr_un). */
+       if (((struct sockaddr *)namebuf)->sa_family == AF_UNIX)
+           bufsize = sizeof(struct sockaddr_un);
+#endif
        sv_setpvn(TARG, namebuf, bufsize);
        PUSHs(TARG);
        RETURN;
@@ -1634,8 +1647,7 @@ PP(pp_sysread)
            count = -1;
     }
     if (count < 0) {
-       if ((IoTYPE(io) == IoTYPE_WRONLY || IoIFP(io) == PerlIO_stdout()
-           || IoIFP(io) == PerlIO_stderr()) && ckWARN(WARN_IO))
+       if ((IoTYPE(io) == IoTYPE_WRONLY) && ckWARN(WARN_IO))
        {
            /* integrate with report_evil_fh()? */
            char *name = NULL;
@@ -2193,6 +2205,9 @@ PP(pp_socket)
        RETPUSHUNDEF;
     }
 
+    if (IoIFP(io))
+       do_close(gv, FALSE);
+
     TAINT_PROPER("socket");
     fd = PerlSock_socket(domain, type, protocol);
     if (fd < 0)
@@ -2251,6 +2266,9 @@ PP(pp_sockpair)
        RETPUSHUNDEF;
     }
 
+    if (IoIFP(io))
+       do_close(gv, FALSE);
+
     TAINT_PROPER("socketpair");
     if (PerlSock_socketpair(domain, type, protocol, fd) < 0)
        RETPUSHUNDEF;
@@ -2444,6 +2462,12 @@ PP(pp_accept)
     setbuf( IoIFP(nstio), NULL); /* EPOC gets confused about sockets */
 #endif
 
+#if defined(I_SYS_UN) && defined(__linux__)
+    /* see the comment in pp_sysread */
+    if (saddr.sa_family == AF_UNIX)
+       len = sizeof(struct sockaddr_un);
+#endif
+
     PUSHp((char *)&saddr, len);
     RETURN;
 
@@ -2621,6 +2645,11 @@ PP(pp_getpeername)
     if (len == BOGUS_GETNAME_RETURN)
        len = sizeof(struct sockaddr);
 #endif
+#if defined(I_SYS_UN) && defined(__linux__)
+    /* see the comment in pp_sysread */
+    if (((struct sockaddr *)SvPVX(sv))->sa_family == AF_UNIX)
+       len = sizeof(struct sockaddr_un);
+#endif
     SvCUR_set(sv, len);
     *SvEND(sv) ='\0';
     PUSHs(sv);