This is a fix, somewhat ugly but working, to the problem mentioned
previously about doing "print"'s to a network socket.

The idea is that we flag file#'s as "sockets" in the few places where
socket filehandles are actually created, and then reset them when the
files are closed.

Then my_fwrite (in VMS.C) only has to check the file# and flag to see
if it should use "write" or "fputs" for output.

I used a fixed global array for this, for several reasons (a) speed
[it gets checked on each item of a print list] (b) simplicity (c)
thread-safety.

You run into problems if you have more than 256 i/o channels open; you'll
get a warning message for any sockets opened at beyond the 256 and you'll
get the "fputs" rather than "write".   The 256 is #defined in vms/vmsish.h
so you can change it if you want.

After modification, all tests in the test suite pass...not surprising, I
don't think any of them use socket i/o at all.  But the LIBWWW test for
local/http.t also passes all tests after doing the usual VMSish patchup
of file/directory names.

Patch follows:
--- doio.c-orig Thu Apr 27 09:16:26 2000
+++ doio.c      Thu Apr 27 13:12:49 2000
@@ -327,7 +327,18 @@
                            fd = -1;
                    }
                    if (dodup)
+#ifdef VMS_DO_SOCKETS
+                   {   
+                       char o = 0;
+                       if (fd >= 0 && fd <= MAX_FILEISSOCKET) 
+                           o = PL_VMS_file_is_socket[fd];
+#endif
                        fd = PerlLIO_dup(fd);
+#ifdef VMS_DO_SOCKETS
+                       if (fd >= 0 && fd <= MAX_FILEISSOCKET) 
+                       PL_VMS_file_is_socket[fd] = o;
+                   }
+#endif
                    else
                        was_fdopen = TRUE;
                    if (!(fp = PerlIO_fdopen(fd,mode))) {
@@ -830,6 +841,20 @@
 {
     bool retval = FALSE;
     int status;
+
+#ifdef VMS_DO_SOCKETS
+    int fd;
+    if (IoIFP(io)) {
+        fd = fileno(IoIFP(io));
+        if (fd >= 0 && fd <= MAX_FILEISSOCKET) 
+            PL_VMS_file_is_socket[fd] = 0 ;
+    }
+    if (IoOFP(io)) {
+        fd = fileno(IoOFP(io));
+        if (fd >= 0 && fd <= MAX_FILEISSOCKET) 
+            PL_VMS_file_is_socket[fd] = 0 ;
+    }
+#endif
 
     if (IoIFP(io)) {
        if (IoTYPE(io) == '|') {
--- pp_sys.c-orig       Thu Apr 27 08:55:28 2000
+++ pp_sys.c    Thu Apr 27 13:12:49 2000
@@ -2045,6 +2045,11 @@
     fd = PerlSock_socket(domain, type, protocol);
     if (fd < 0)
        RETPUSHUNDEF;
+#ifdef VMS_DO_SOCKETS
+    if (fd <= MAX_FILEISSOCKET) PL_VMS_file_is_socket[fd]=1;
+    else if (ckWARN(WARN_IO))  
+        Perl_warner(aTHX_ WARN_IO, "socket file# too large, may have i/o errors");
+#endif
     IoIFP(io) = PerlIO_fdopen(fd, "r");        /* stdio gets confused about sockets */
     IoOFP(io) = PerlIO_fdopen(fd, "w");
     IoTYPE(io) = 's';
@@ -2092,6 +2097,14 @@
     TAINT_PROPER("socketpair");
     if (PerlSock_socketpair(domain, type, protocol, fd) < 0)
        RETPUSHUNDEF;
+#ifdef VMS_DO_SOCKETS
+    if (fd[0] <= MAX_FILEISSOCKET) PL_VMS_file_is_socket[fd[0]]=1;
+    else if (ckWARN(WARN_IO))  
+        Perl_warner(aTHX_ WARN_IO, "socket file# too large, may have i/o errors");
+    if (fd[1] <= MAX_FILEISSOCKET) PL_VMS_file_is_socket[fd[1]]=1;
+    else if (ckWARN(WARN_IO))  
+        Perl_warner(aTHX_ WARN_IO, "socket file# too large, may have i/o errors");
+#endif
     IoIFP(io1) = PerlIO_fdopen(fd[0], "r");
     IoOFP(io1) = PerlIO_fdopen(fd[0], "w");
     IoTYPE(io1) = 's';
@@ -2264,6 +2277,11 @@
     fd = PerlSock_accept(PerlIO_fileno(IoIFP(gstio)), (struct sockaddr *)&saddr, 
&len);
     if (fd < 0)
        goto badexit;
+#ifdef VMS_DO_SOCKETS
+    if (fd <= MAX_FILEISSOCKET) PL_VMS_file_is_socket[fd]=1;
+    else if (ckWARN(WARN_IO))  
+        Perl_warner(aTHX_ WARN_IO, "socket file# too large, may have i/o errors");
+#endif
     IoIFP(nstio) = PerlIO_fdopen(fd, "r");
     IoOFP(nstio) = PerlIO_fdopen(fd, "w");
     IoTYPE(nstio) = 's';
--- vms/vms.c-pre_socket        Thu Apr 27 09:24:32 2000
+++ vms/vms.c   Thu Apr 27 09:47:41 2000
@@ -4639,6 +4639,10 @@
 }  /* end of do_spawn() */
 /*}}}*/
 
+#ifdef VMS_DO_SOCKETS
+char PL_VMS_file_is_socket[MAX_FILEISSOCKET+1];
+#endif
+
 /* 
  * A simple fwrite replacement which outputs itmsz*nitm chars without
  * introducing record boundaries every itmsz chars.
@@ -4648,7 +4652,13 @@
 my_fwrite(void *src, size_t itmsz, size_t nitm, FILE *dest)
 {
   register char *cp, *end;
-
+#ifdef VMS_DO_SOCKETS
+  int fd = fileno(dest);
+  if (fd >= 0 && fd <= MAX_FILEISSOCKET && PL_VMS_file_is_socket[fd]) {
+      if (write(fd,src,itmsz*nitm) == EOF) return EOF;
+      return 1;
+  }
+#endif
   end = (char *)src + itmsz * nitm;
 
   while ((char *)src <= end) {
@@ -6168,6 +6178,13 @@
 
   store_pipelocs();
 
+#ifdef VMS_DO_SOCKETS
+  {
+    int j;
+    for (j = 0; j <= MAX_FILEISSOCKET; j++)  
+        PL_VMS_file_is_socket[j] = 0;
+  }
+#endif
   return;
 }
   
--- vms/vmsish.h-orig   Fri Apr 21 07:37:23 2000
+++ vms/vmsish.h        Thu Apr 27 12:25:48 2000
@@ -721,5 +724,12 @@
 #if defined(fileno) && defined(__DECC_VER) && __DECC_VER < 50300000
 #  undef fileno 
 #endif 
+
+/* fixup i/o to sockets, flag which file#'s are sockets */
+#ifdef VMS_DO_SOCKETS
+#define MAX_FILEISSOCKET 256
+extern char PL_VMS_file_is_socket[MAX_FILEISSOCKET+1];
+#endif
+
 
 #endif  /* __vmsish_h_included */
--
 Drexel University       \V                     --Chuck Lane
----------------->--------*------------<[EMAIL PROTECTED]
     (215) 895-1545      / \  Particle Physics  [EMAIL PROTECTED]
FAX: (215) 895-5934        /~~~~~~~~~~~         [EMAIL PROTECTED]

Reply via email to