[comp.lang.perl] perl 4.009

marc@athena.mit.edu (Marc Horowitz) (06/09/91)

I just compiled perl 4.009 for the pmax, running ultrix 3.1 (don't ask
why I'm not running 4.x yet).  I failed the following tests:

io/dup.........FAILED on test 4
io/pipe........FAILED on test 6

I noticed that Yeap Yuen Pin also failed those tests on ultrix 4.1, so
it's not ancient ultrix brain-damage.  Unfortunately, it's not modern
ultrix brain-damage, either.  Notice the following code from
do_open(), on line doio.c:247:

#if defined(HAS_FCNTL) && defined(F_SETFD)
    fd = fileno(fp);
    fcntl(fd,F_SETFD,fd > maxsysfd);
#endif
    if (saveifp) {		/* must use old fp? */
	fd = fileno(saveifp);
	if (saveofp) {
	    fflush(saveofp);		/* emulate fclose() */
	    if (saveofp != saveifp) {	/* was a socket? */
		fclose(saveofp);
		Safefree(saveofp);
	    }
	}
	if (fd != fileno(fp)) {
	    dup2(fileno(fp), fd);
	    fclose(fp);
	}
	fp = saveifp;
    }

Now, consider the following line of perl, from t/io/dup.t, which will
run the above c:

open(STDOUT,">Io.dup") || die "Can't open stdout";

What this will do is set the fd (which is 5 in my case) as
close-on-exec.  Then, it checks to see if the fp was magic, and should
be preserved.  STDOUT is, so it dup2's the filehandle.  Now, fd 1 is
close-on-exec, so the system 'echo ok 4' later in t/io/dup.t fails.
The solution is to put the close-on-exec test after the dup2. My
(unofficial) patch follows:

*** pl9/doio.c	Sun Jun  9 05:16:34 1991
--- doio.c	Sun Jun  9 05:09:37 1991
***************
*** 244,253 ****
  	    stio->type = 's';	/* some OS's return 0 on fstat()ed socket */
  #endif
      }
- #if defined(HAS_FCNTL) && defined(F_SETFD)
-     fd = fileno(fp);
-     fcntl(fd,F_SETFD,fd > maxsysfd);
- #endif
      if (saveifp) {		/* must use old fp? */
  	fd = fileno(saveifp);
  	if (saveofp) {
--- 244,249 ----
***************
*** 263,268 ****
--- 259,268 ----
  	}
  	fp = saveifp;
      }
+ #if defined(HAS_FCNTL) && defined(F_SETFD)
+     fd = fileno(fp);
+     fcntl(fd,F_SETFD,fd > maxsysfd);
+ #endif
      stio->ifp = fp;
      if (writing) {
  	if (stio->type != 's')

		Marc