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