--- ./doio.c-pre	Sat Sep 13 10:26:32 2003
+++ ./doio.c	Mon Sep 22 20:19:30 2003
@@ -937,8 +937,8 @@ Perl_do_pipe(pTHX_ SV *sv, GV *rgv, GV *
 
     if (PerlProc_pipe(fd) < 0)
 	goto badexit;
-    IoIFP(rstio) = PerlIO_fdopen(fd[0], "r"PIPESOCK_MODE);
-    IoOFP(wstio) = PerlIO_fdopen(fd[1], "w"PIPESOCK_MODE);
+    IoIFP(rstio) = PerlIO_fdopen(fd[0], "r"PIPE_OPEN_MODE);
+    IoOFP(wstio) = PerlIO_fdopen(fd[1], "w"PIPE_OPEN_MODE);
     IoOFP(rstio) = IoIFP(rstio);
     IoIFP(wstio) = IoOFP(wstio);
     IoTYPE(rstio) = IoTYPE_RDONLY;
--- ./perl.h-pre	Mon Sep 22 20:18:52 2003
+++ ./perl.h	Mon Sep 22 20:18:58 2003
@@ -4353,6 +4353,14 @@ extern void moncontrol(int);
 #  define PIPESOCK_MODE
 #endif
 
+#ifndef SOCKET_OPEN_MODE
+#  define SOCKET_OPEN_MODE	PIPESOCK_MODE
+#endif
+
+#ifndef PIPE_OPEN_MODE
+#  define PIPE_OPEN_MODE	PIPESOCK_MODE
+#endif
+
 #define PERL_MAGIC_UTF8_CACHESIZE	2
 
 #define PERL_UNICODE_STDIN_FLAG			0x0001
--- ./perlio.c-pre	Sat Sep 13 10:26:32 2003
+++ ./perlio.c	Sat Sep 20 00:07:48 2003
@@ -4861,7 +4861,7 @@ PerlIO_tmpfile(void)
      if (fd >= 0)
 	  f = PerlIO_fdopen(fd, "w+b");
 #else /* WIN32 */
-#    ifdef HAS_MKSTEMP
+#    if defined(HAS_MKSTEMP) && !defined(OS2)
      SV *sv = newSVpv("/tmp/PerlIO_XXXXXX", 0);
 
      /*
--- ./pp_sys.c-pre	Fri Sep 12 12:19:56 2003
+++ ./pp_sys.c	Mon Sep 22 20:21:42 2003
@@ -609,8 +609,8 @@ PP(pp_pipe_op)
     if (PerlProc_pipe(fd) < 0)
 	goto badexit;
 
-    IoIFP(rstio) = PerlIO_fdopen(fd[0], "r"PIPESOCK_MODE);
-    IoOFP(wstio) = PerlIO_fdopen(fd[1], "w"PIPESOCK_MODE);
+    IoIFP(rstio) = PerlIO_fdopen(fd[0], "r"PIPE_OPEN_MODE);
+    IoOFP(wstio) = PerlIO_fdopen(fd[1], "w"PIPE_OPEN_MODE);
     IoOFP(rstio) = IoIFP(rstio);
     IoIFP(wstio) = IoOFP(wstio);
     IoTYPE(rstio) = IoTYPE_RDONLY;
@@ -2283,8 +2283,8 @@ PP(pp_socket)
     fd = PerlSock_socket(domain, type, protocol);
     if (fd < 0)
 	RETPUSHUNDEF;
-    IoIFP(io) = PerlIO_fdopen(fd, "r"PIPESOCK_MODE);	/* stdio gets confused about sockets */
-    IoOFP(io) = PerlIO_fdopen(fd, "w"PIPESOCK_MODE);
+    IoIFP(io) = PerlIO_fdopen(fd, "r"SOCKET_OPEN_MODE);	/* stdio gets confused about sockets */
+    IoOFP(io) = PerlIO_fdopen(fd, "w"SOCKET_OPEN_MODE);
     IoTYPE(io) = IoTYPE_SOCKET;
     if (!IoIFP(io) || !IoOFP(io)) {
 	if (IoIFP(io)) PerlIO_close(IoIFP(io));
@@ -2345,11 +2345,11 @@ PP(pp_sockpair)
     TAINT_PROPER("socketpair");
     if (PerlSock_socketpair(domain, type, protocol, fd) < 0)
 	RETPUSHUNDEF;
-    IoIFP(io1) = PerlIO_fdopen(fd[0], "r"PIPESOCK_MODE);
-    IoOFP(io1) = PerlIO_fdopen(fd[0], "w"PIPESOCK_MODE);
+    IoIFP(io1) = PerlIO_fdopen(fd[0], "r"SOCKET_OPEN_MODE);
+    IoOFP(io1) = PerlIO_fdopen(fd[0], "w"SOCKET_OPEN_MODE);
     IoTYPE(io1) = IoTYPE_SOCKET;
-    IoIFP(io2) = PerlIO_fdopen(fd[1], "r"PIPESOCK_MODE);
-    IoOFP(io2) = PerlIO_fdopen(fd[1], "w"PIPESOCK_MODE);
+    IoIFP(io2) = PerlIO_fdopen(fd[1], "r"SOCKET_OPEN_MODE);
+    IoOFP(io2) = PerlIO_fdopen(fd[1], "w"SOCKET_OPEN_MODE);
     IoTYPE(io2) = IoTYPE_SOCKET;
     if (!IoIFP(io1) || !IoOFP(io1) || !IoIFP(io2) || !IoOFP(io2)) {
 	if (IoIFP(io1)) PerlIO_close(IoIFP(io1));
@@ -2520,8 +2520,8 @@ PP(pp_accept)
 	goto badexit;
     if (IoIFP(nstio))
 	do_close(ngv, FALSE);
-    IoIFP(nstio) = PerlIO_fdopen(fd, "r"PIPESOCK_MODE);
-    IoOFP(nstio) = PerlIO_fdopen(fd, "w"PIPESOCK_MODE);
+    IoIFP(nstio) = PerlIO_fdopen(fd, "r"SOCKET_OPEN_MODE);
+    IoOFP(nstio) = PerlIO_fdopen(fd, "w"SOCKET_OPEN_MODE);
     IoTYPE(nstio) = IoTYPE_SOCKET;
     if (!IoIFP(nstio) || !IoOFP(nstio)) {
 	if (IoIFP(nstio)) PerlIO_close(IoIFP(nstio));
@@ -3084,7 +3084,7 @@ PP(pp_ftmtime)
     dSP; dTARGET;
     if (result < 0)
 	RETPUSHUNDEF;
-    PUSHn( (PL_basetime - PL_statcache.st_mtime) / 86400.0 );
+    PUSHn( (((NV)PL_basetime - PL_statcache.st_mtime)) / 86400.0 );
     RETURN;
 }
 
@@ -3094,7 +3094,7 @@ PP(pp_ftatime)
     dSP; dTARGET;
     if (result < 0)
 	RETPUSHUNDEF;
-    PUSHn( (PL_basetime - PL_statcache.st_atime) / 86400.0 );
+    PUSHn( (((NV)PL_basetime - PL_statcache.st_atime)) / 86400.0 );
     RETURN;
 }
 
@@ -3104,7 +3104,7 @@ PP(pp_ftctime)
     dSP; dTARGET;
     if (result < 0)
 	RETPUSHUNDEF;
-    PUSHn( (PL_basetime - PL_statcache.st_ctime) / 86400.0 );
+    PUSHn( (((NV)PL_basetime - PL_statcache.st_ctime)) / 86400.0 );
     RETURN;
 }
 
--- ./t/run/switches.t-pre	Sun Aug 31 09:58:48 2003
+++ ./t/run/switches.t	Sat Sep 13 13:47:48 2003
@@ -231,7 +231,7 @@ SWTESTPM
     local $TODO = '';   # these ones should work on VMS
 
     like( runperl( switches => ['-h'] ),
-	  qr/Usage: .+perl.+switches.+programfile.+arguments/,
+	  qr/Usage: .+(?i:perl(\.exe)?).+switches.+programfile.+arguments/,
           '-h looks okay' );
 
 }
--- ./t/op/magic.t-pre	Mon Aug 25 03:22:48 2003
+++ ./t/op/magic.t	Tue Sep 16 19:11:08 2003
@@ -125,7 +125,8 @@ END
 END
     close CMDPIPE;
     $? >>= 8 if $^O eq 'VMS'; # POSIX status hiding in 2nd byte
-    print $? & 0xFF ? "ok 6\n" : "not ok 6\n";
+    my $todo = ($^O eq 'os2' ? ' # TODO EMX v0.9d_fix4 bug: wrong nibble? ' : '');
+    print $? & 0xFF ? "ok 6$todo\n" : "not ok 6$todo\n";
 
     $test += 4;
 }
--- ./t/op/time.t-pre	Fri Aug  8 14:09:52 2003
+++ ./t/op/time.t	Thu Sep 18 10:58:18 2003
@@ -3,10 +3,10 @@
 # $RCSfile: time.t,v $$Revision: 4.1 $$Date: 92/08/07 18:28:32 $
 
 if ( $does_gmtime = gmtime(time) ) { 
-    print "1..7\n" 
+    print "1..12\n"
 }
 else { 
-    print "1..4\n" 
+    print "1..9\n" 
 }
 
 
@@ -53,6 +53,20 @@ ok(localtime() =~ /^(Sun|Mon|Tue|Wed|Thu
                   /x,
    'localtime(), scalar context'
   );
+
+sleep(3);
+my $f = 'tstamp.tmp';
+unlink $f;
+ok (open(S, "> $f"), 'can create tmp file');
+close S or die;
+my @a = stat $f;
+print "# time=$^T, stat=(@a)\n";
+my @b = (-M _, -A _, -C _);
+print "# -MAC=(@b)\n";
+ok( (-M _) < 0, 'negative -M works');
+ok( (-A _) < 0, 'negative -A works');
+ok( (-C _) < 0, 'negative -A works');
+ok(unlink($f), 'unlink tmp file');
 
 exit 0 unless $does_gmtime;
 
--- ./t/lib/os2_process.t-pre	Sat Sep 13 12:00:50 2003
+++ ./t/lib/os2_process.t	Tue Sep 16 19:49:22 2003
@@ -24,7 +24,7 @@ BEGIN {			# Remap I/O to the parent's wi
 }
 
 use strict;
-use Test::More tests => 230;
+use Test::More tests => 232;
 use OS2::Process;
 
 sub SWP_flags ($) {
@@ -407,9 +407,14 @@ ok $my_pos, 'got my position';
   ok IsWindowShowing $k_hwnd, 'kid is showing';
   ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
   ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
+  SKIP: {
+    skip 'if defaultVIO=MAXIMIZED, new windows are shifted, but maximize to UL corner', 1 unless $fl & 0x800;
+    ok hWindowPos_set({x => $ppos[0], y => $ppos[1]}, $k_hwnd), 'x,y-restore for de-minimization of MAXIMIZED';
+  }
   @nkpos = WindowPos $k_hwnd;
   is_deeply([@ppos[0..5]], [@nkpos[0..5]], 'position restored');
 
+
   # Now the other way
   ok hWindowPos_set( {flags => 0x400}, $k_hwnd), 'set to minimized';
   ok !IsWindowShowing $k_hwnd, 'kid is not showing';
@@ -452,6 +457,10 @@ ok $my_pos, 'got my position';
   ok IsWindowShowing $k_hwnd, 'kid is showing';
   ok IsWindowVisible $k_hwnd, 'kid is flaged as visible';
   ok IsWindowEnabled $k_hwnd, 'kid is flaged as enabled';
+  SKIP: {
+    skip 'if defaultVIO=MAXIMIZED, new windows are shifted, but maximize to UL corner', 1 unless $fl & 0x800;
+    ok hWindowPos_set({x => $ppos[0], y => $ppos[1]}, $k_hwnd), 'x,y-restore for de-minimization of MAXIMIZED';
+  }
   @nkpos = WindowPos $k_hwnd;
   is_deeply([@ppos[0..5]], [@nkpos[0..5]], 'position restored');
 
--- ./os2/os2.c-pre	Sat Sep 13 14:26:24 2003
+++ ./os2/os2.c	Thu Sep 18 14:47:46 2003
@@ -619,6 +619,7 @@ static const struct {
   {&pmwin_handle, NULL, 745},		/* WinFlashWindow */
   {&pmwin_handle, NULL, 780},		/* WinLoadPointer */
   {&pmwin_handle, NULL, 828},		/* WinQuerySysPointer */
+  {&doscalls_handle, NULL, 417},	/* DosReplaceModule */
 };
 
 HMODULE
@@ -781,7 +782,7 @@ get_sysinfo(ULONG pid, ULONG flags)
 	return 0;
     }
     psi = (PQTOPLEVEL)pbuffer;
-    if (psi && pid && pid != psi->procdata->pid) {
+    if (psi && pid && psi->procdata && pid != psi->procdata->pid) {
       Safefree(psi);
       Perl_croak_nocontext("panic: wrong pid in sysinfo");
     }
@@ -1828,6 +1829,29 @@ XS(XS_File__Copy_syscopy)
     XSRETURN(1);
 }
 
+/* APIRET APIENTRY DosReplaceModule (PCSZ pszOld, PCSZ pszNew, PCSZ pszBackup); */
+
+DeclOSFuncByORD(ULONG,replaceModule,ORD_DosReplaceModule,
+		(char *old, char *new, char *backup), (old, new, backup))
+
+XS(XS_OS2_replaceModule); /* prototype to pass -Wmissing-prototypes */
+XS(XS_OS2_replaceModule)
+{
+    dXSARGS;
+    if (items < 1 || items > 3)
+	Perl_croak(aTHX_ "Usage: OS2::replaceModule(target [, source [, backup]])");
+    {
+	char *	target = (char *)SvPV_nolen(ST(0));
+	char *	source = (items < 2) ? Nullch : (char *)SvPV_nolen(ST(1));
+	char *	backup = (items < 3) ? Nullch : (char *)SvPV_nolen(ST(2));
+
+	if (!replaceModule(target, source, backup))
+	    croak_with_os2error("replaceModule() error");
+    }
+    XSRETURN_EMPTY;
+}
+
+
 #define PERL_PATCHLEVEL_H_IMPLICIT	/* Do not init local_patches. */
 #include "patchlevel.h"
 #undef PERL_PATCHLEVEL_H_IMPLICIT
@@ -3478,6 +3502,7 @@ Xs_OS2_init(pTHX)
         newXS("Cwd::sys_is_relative", XS_Cwd_sys_is_relative, file);
         newXS("Cwd::sys_cwd", XS_Cwd_sys_cwd, file);
         newXS("Cwd::sys_abspath", XS_Cwd_sys_abspath, file);
+        newXS("OS2::replaceModule", XS_OS2_replaceModule, file);
         newXSproto("OS2::_control87", XS_OS2__control87, file, "$$");
         newXSproto("OS2::get_control87", XS_OS2_get_control87, file, "");
         newXSproto("OS2::set_control87", XS_OS2_set_control87, file, ";$$");
--- ./os2/os2ish.h-pre	Mon Sep 22 20:22:48 2003
+++ ./os2/os2ish.h	Mon Sep 22 20:15:18 2003
@@ -49,6 +49,8 @@
  */
 #undef USEMYBINMODE
 
+#define SOCKET_OPEN_MODE	"b"
+
 /* Stat_t:
  *	This symbol holds the type used to declare buffers for information
  *	returned by stat().  It's usually just struct stat.  It may be necessary
--- ./os2/OS2/Process/Process.pm-pre	Thu Sep 11 14:48:24 2003
+++ ./os2/OS2/Process/Process.pm	Fri Sep 19 19:54:24 2003
@@ -573,6 +573,64 @@ sub kbdhStatus_set {
   _kbdStatus_set($o,$h);
 }
 
+# Large buffer works at least for read from pipes
+sub __term_mirror_screen {   # Read from fd=$in and write to the console
+  my $in = shift;
+  open IN, "<&=$in" or die "open <&=$in: $!";
+  # Attempt to redirect to STDERR/OUT is not very useful, but try this anyway...
+  open OUT, '>', '/dev/con' or open OUT, '>&STDERR' or open OUT, '>&STDOUT'
+        or warn "Cannot reopen STDOUT to /dev/con or STDERR/STDOUT";
+  select OUT; $| = 1; local $SIG{TERM} = sub { die "screenwriter exits...\n"};
+  eval { print while sysread IN, $_, 1<<16; }
+}
+
+sub __term_mirror {   # Read from fd=$in and pass through; same for $out
+  my $pid;
+  local $SIG{TERM} = sub { die "keyreader exits...\n" };
+  my ($in, $out) = (shift, shift);
+  my %in = @_;
+  Title_set $in{title}			if exists $in{title};
+  &scrsize_set(split /,/, $in{scrsize})	if exists $in{scrsize};
+
+  $pid = system 1, $^X, '-MOS2::Process',
+	 '-we', 'OS2::Process::__term_mirror_screen shift', $in;
+  $pid > 0 or die "Cannot start a grandkid";
+
+  open STDIN, '</dev/con' or warn "reopen stdin: $!";
+  open OUT, ">&=$out" or die "Cannot open &=$out for writing: $!";
+  select OUT;    $| = 1;  binmode OUT;	# need binmode since sysread() is bin
+  $SIG{PIPE} = sub { die "writing to a closed pipe" };
+  # Turn Nodelay on kbd.  Pipe is automatically nodelay...
+  if ($in{read_by_key}) {
+    if (eval {require Term::ReadKey; 1}) {
+      Term::ReadKey::ReadMode(4);
+    } else { warn }
+  }
+  print while sysread STDIN, $_, 1<<($flag ? 16 : 0);
+}
+
+sub io_term {	# arguments: hash with keys read_by_key/title/scrsize
+  local $^F = 40;     # XXXX Fixme!
+  local $\  = '';
+  my ($in1, $out1, $in2, $out2);
+
+  pipe $in1, $out1 or return;
+  pipe $in2, $out2 or do { close($in1), close($out1), return };
+
+  # system P_SESSION will fail if there is another process
+  # in the same session with a "dependent" asynchronous child session.
+  my @i = map +('-I', $_), @INC;	# Propagate @INC
+  my $kpid = system 4, $^X, @i, '-we', <<'EOS', fileno $in1, fileno $out2, @_;
+     END {sleep($sleep || 5)}
+     use OS2::Process; $sleep = 1;
+     OS2::Process::__term_mirror(@ARGV);
+EOS
+  close $in1 or warn;
+  close $out2 or warn;
+  warn "system P_SESSION, $^X: $!, $^E" and do { close($in2), close($out1), return }
+    unless $kpid > 0;
+  return ($in2, $out1, $kpid);
+}
 
 # Autoload methods go after __END__, and are processed by the autosplit program.
 
--- ./lib/CPAN.pm-pre	Thu Jul 31 13:56:22 2003
+++ ./lib/CPAN.pm	Sun Sep 21 19:46:24 2003
@@ -259,7 +259,7 @@ package CPAN::Complete;
 ) unless @CPAN::Complete::COMMANDS;
 
 package CPAN::Index;
-use vars qw($LAST_TIME $DATE_OF_02 $DATE_OF_03);
+use vars qw($LAST_TIME $DATE_OF_02 $DATE_OF_03 $BUILD_DIRS);
 @CPAN::Index::ISA = qw(CPAN::Debug);
 $LAST_TIME ||= 0;
 $DATE_OF_03 ||= 0;
@@ -807,6 +807,10 @@ sub cleanup {
 	  $subroutine eq '(eval)';
   }
   return if $ineval && !$End;
+  if ($CPAN::Index::BUILD_DIRS and $CPAN::Index::BUILD_DIRS->{'*new*'}) {
+    CPAN::Index->write_metadata_cache();
+    $CPAN::Frontend->mywarn("List of tested dirs updated.\n");
+  }
   return unless defined $META->{LOCK};
   return unless -f $META->{LOCK};
   $META->savehist;
@@ -842,8 +846,9 @@ sub savehist {
     close $fh;
 }
 
+# Actually, this means: tested, but not installed...
 sub is_tested {
-    my($self,$what) = @_;
+    my($self,$what,) = @_;
     $self->{is_tested}{$what} = 1;
 }
 
@@ -860,8 +865,14 @@ sub set_perl5lib {
     $env = $ENV{PERLLIB} unless defined $env;
     my @env;
     push @env, $env if defined $env and length $env;
-    my @dirs = map {("$_/blib/arch", "$_/blib/lib")} keys %{$self->{is_tested}};
-    $CPAN::Frontend->myprint("Prepending @dirs to PERL5LIB.\n");
+    my @dirs = map {("$_/blib/arch", "$_/blib/lib")} sort keys %{$self->{is_tested}};
+    if (@dirs < 15) {
+       $CPAN::Frontend->myprint("Prepending @dirs to PERL5LIB.\n");
+    } else {
+       my @d = map {s/^\Q$CPAN::Config->{'build_dir'}/%BUILDDIR%/; $_ }
+	 sort keys %{$self->{is_tested}};
+       $CPAN::Frontend->myprint("Prepending blib/arch and blib/lib subdirs of @d to PERL5LIB; %BUILDDIR%=$CPAN::Config->{'build_dir'}.\n");
+    }
     $ENV{PERL5LIB} = join $Config::Config{path_sep}, @dirs, @env;
 }
 
@@ -1285,7 +1296,7 @@ sub missing_config_data {
          "pager",
          "makepl_arg", "make_arg", "make_install_arg", "urllist",
          "inhibit_startup_message", "ftp_proxy", "http_proxy", "no_proxy",
-         "prerequisites_policy",
+         "prerequisites_policy", "expire_old_builds",
          "cache_metadata",
         ) {
 	push @miss, $_ unless defined $CPAN::Config->{$_};
@@ -1493,13 +1504,14 @@ sub o {
 	    $CPAN::Frontend->myprint(":\n");
 	    for $k (sort keys %CPAN::Config::can) {
 		$v = $CPAN::Config::can{$k};
-		$CPAN::Frontend->myprint(sprintf "    %-18s %s\n", $k, $v);
+		# use distinctive whitespace to make the commands stand out
+		$CPAN::Frontend->myprint(sprintf "      %-10s %s\n", $k, $v);
 	    }
 	    $CPAN::Frontend->myprint("\n");
 	    for $k (sort keys %$CPAN::Config) {
                 CPAN::Config->prettyprint($k);
 	    }
-	    $CPAN::Frontend->myprint("\n");
+	    # $CPAN::Frontend->myprint("\n");	# Why second empty line?
 	} elsif (!CPAN::Config->edit(@o_what)) {
 	    $CPAN::Frontend->myprint(qq{Type 'o conf' to view configuration }.
                                      qq{edit options\n\n});
@@ -3411,6 +3423,11 @@ sub write_metadata_cache {
     $cache->{last_time} = $LAST_TIME;
     $cache->{DATE_OF_02} = $DATE_OF_02;
     $cache->{PROTOCOL} = PROTOCOL;
+    if ($BUILD_DIRS) {
+	$cache->{'CPAN-sitearchexp'} = $Config::Config{sitearchexp};
+	delete $CPAN::Index::BUILD_DIRS->{'*new*'};
+        $cache->{'CPAN-tested-dirs'} = $BUILD_DIRS;
+    }
     $CPAN::Frontend->myprint("Going to write $metadata_file\n");
     eval { Storable::nstore($cache, $metadata_file) };
     $CPAN::Frontend->mywarn($@) if $@; # ?? missing "\n" after $@ in mywarn ??
@@ -3471,6 +3488,12 @@ sub read_metadata_cache {
                             # does initialize to some protocol
     $LAST_TIME = $cache->{last_time};
     $DATE_OF_02 = $cache->{DATE_OF_02};
+    # Do not trust build directories of different version of Perl:
+    delete $cache->{'CPAN-tested-dirs'}
+	if exists $cache->{'CPAN-sitearchexp'}
+	    and $cache->{'CPAN-sitearchexp'} ne $Config::Config{sitearchexp};
+    $BUILD_DIRS = $cache->{'CPAN-tested-dirs'}
+	if exists $cache->{'CPAN-tested-dirs'};
     $CPAN::Frontend->myprint("  Database was generated on $DATE_OF_02\n")
 	if defined $DATE_OF_02; # An old cache may not contain DATE_OF_02
     return;
@@ -4486,6 +4509,8 @@ or
 #	$switch = "-MExtUtils::MakeMaker ".
 #	    "-Mops=:default,:filesys_read,:filesys_open,require,chdir"
 #	    if $] > 5.00310;
+	local $ENV{PERL5LIB} = $ENV{PERL5LIB} || $ENV{PERLLIB} || "";
+	$CPAN::META->set_perl5lib;
 	$system = "$perl $switch Makefile.PL $CPAN::Config->{makepl_arg}";
     }
     unless (exists $self->{writemakefile}) {
@@ -4547,6 +4572,8 @@ or
       return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
     }
     $system = join " ", $CPAN::Config->{'make'}, $CPAN::Config->{make_arg};
+    local $ENV{PERL5LIB} = $ENV{PERL5LIB} || $ENV{PERLLIB} || "";
+    $CPAN::META->set_perl5lib;
     if (system($system) == 0) {
 	 $CPAN::Frontend->myprint("  $system -- OK\n");
 	 $self->{'make'} = "YES";
@@ -4682,9 +4709,65 @@ sub prereq_pm {
   return $self->{prereq_pm} = \%p;
 }
 
+#-> sub CPAN::Distribution::tested_ok ;
+sub tested_ok {
+  my($self) = @_;
+  return unless $CPAN::Index::BUILD_DIRS and $CPAN::Config->{expire_old_builds};
+  my $dir = $CPAN::Index::BUILD_DIRS->{$self->id};
+  return unless $dir and -d $dir;
+  my $cpan_test_ok = File::Spec->catfile($dir, '.cpantok');
+  return unless -f $cpan_test_ok;
+  return if $CPAN::Config->{expire_old_builds} > 0
+	    and -M $cpan_test_ok > $CPAN::Config->{expire_old_builds};
+  local *T;
+  open T, $cpan_test_ok and <T> eq "$Config::Config{sitearchexp}\n" and close T
+    or return;
+  my $date = -M $cpan_test_ok;
+  eval { File::Find::find sub {
+	  -M $_ >= $date
+	    or warn("File `$File::Find::name' newer than $cpan_test_ok: "
+		    . (-M _) . " days vs. $date days\n"),
+	       die 'update'
+	}, $dir ; 1} and return $dir;
+  warn "error scanning $dir: $@" unless $@ =~ /^update\b/;
+  return;
+}
+
+#-> sub CPAN::Distribution::mark_tested_ok ;
+sub mark_tested_ok {
+  my($self) = @_;
+  my $dir = $self->{build_dir};
+  return unless -d $dir;
+  my $cpan_test_ok = File::Spec->catfile($dir, '.cpantok');
+  local *T;
+  open T, "> $cpan_test_ok" or warn("error touching $cpan_test_ok: $!\n"), return;
+  # Something very build-specific
+  print T "$Config::Config{sitearchexp}\n";
+  close T or warn("error touching $cpan_test_ok: $!\n"), return;
+  $CPAN::Index::BUILD_DIRS ||= {};
+  $CPAN::Index::BUILD_DIRS->{'*new*'} ||= 0;
+  $CPAN::Index::BUILD_DIRS->{'*new*'}++
+    unless exists $CPAN::Index::BUILD_DIRS->{$self->id}
+      and $CPAN::Index::BUILD_DIRS->{$self->id} eq $dir;
+  $CPAN::Index::BUILD_DIRS->{$self->id} = $dir;
+  return 1;
+}
+
 #-> sub CPAN::Distribution::test ;
 sub test {
     my($self) = @_;
+    my $tested_dir = $self->tested_ok;
+    if ($tested_dir) {
+	 $self->{'build_dir'} = $tested_dir;
+	 $CPAN::Frontend->myprint("Skipping test for " . $self->id . ": test was successful in $tested_dir\n");
+	 $CPAN::META->is_tested($self->{'build_dir'});
+	 $self->{make_test} = "YES";
+	 chdir $self->{'build_dir'} or
+	    Carp::croak("Couldn't chdir to $self->{'build_dir'}");
+	 $self->debug("Changed directory to $self->{'build_dir'}")
+	    if $CPAN::DEBUG;
+	 return;
+    }
     $self->make;
     if ($CPAN::Signal){
       delete $self->{force_update};
@@ -4723,13 +4806,14 @@ sub test {
         return;
     }
 
-    local $ENV{PERL5LIB} = $ENV{PERL5LIB} || "";
+    local $ENV{PERL5LIB} = $ENV{PERL5LIB} || $ENV{PERLLIB} || "";
     $CPAN::META->set_perl5lib;
     my $system = join " ", $CPAN::Config->{'make'}, "test";
     if (system($system) == 0) {
 	 $CPAN::Frontend->myprint("  $system -- OK\n");
 	 $CPAN::META->is_tested($self->{'build_dir'});
 	 $self->{make_test} = "YES";
+	 $self->mark_tested_ok();
     } else {
 	 $self->{make_test} = "NO";
          $self->{badtestcnt}++;
@@ -6751,6 +6835,9 @@ defined:
   cpan_home          local directory reserved for this package
   dontload_hash      anonymous hash: modules in the keys will not be
                      loaded by the CPAN::has_inst() routine
+  expire_old_builds  Timeout in days; after this time the module is rebuild
+		     even if it was successfully build, and the build directory
+		     is still present.  -1 means 'never rebuild'.
   gzip		     location of external program gzip
   histfile           file to maintain history between sessions
   histsize           maximum number of lines to keep in histfile
--- ./lib/dumpvar.pl-pre	Wed Sep 10 23:31:38 2003
+++ ./lib/dumpvar.pl	Thu Sep 18 15:21:16 2003
@@ -30,6 +30,7 @@ sub main::dumpValue {
   local $^W=0;
   (print "undef\n"), return unless defined $_[0];
   (print &stringify($_[0]), "\n"), return unless ref $_[0];
+  push @_, -1 if @_ == 1;
   dumpvar::unwrap($_[0],0, $_[1]);
 }
 
--- ./lib/perl5db.pl-pre	Fri Jul 25 00:22:40 2003
+++ ./lib/perl5db.pl	Fri Sep 19 19:41:38 2003
@@ -1498,7 +1498,7 @@ Console> if not. (Note that Mac OS X ret
 
 Several other systems don't use a specific console. We C<undef $console>
 for those (Windows using a slave editor/graphical debugger, NetWare, OS/2
-with a slave editor, Epoc).
+with a slave editor or xterm, Epoc).
 
 =cut
 
@@ -1512,10 +1512,8 @@ with a slave editor, Epoc).
         $console = undef;
     }
 
-    # In OS/2, we need to use STDIN to get textmode too, even though
-    # it pretty much looks like Unix otherwise.
-    if (defined $ENV{OS2_SHELL} and ($slave_editor or $ENV{WINDOWID}))
-    {    # In OS/2
+    if ($^O eq 'os2' and ($slave_editor or $ENV{WINDOWID}))
+    {    # uncomplete support of /dev/con on xterm and other X terminals
         $console = undef;
     }
     # EPOC also falls into the 'got to use STDIN' camp.
@@ -2054,6 +2052,8 @@ the new command. This is faster, but per
             # No signal is active.
             $signal = 0;
 
+	    $cmd =~ s/\r+\z//;	# Remove spurious \r due to wrong binmode...
+
             # Handle continued commands (ending with \):
             $cmd =~ s/\\$/\n/ && do {
                 $cmd .= &readline("  cont: ");
@@ -2397,7 +2397,10 @@ above the current one and then displays 
                     eval { require PadWalker; PadWalker->VERSION(0.08) }
                       or &warn(
                         $@ =~ /locate/
-                        ? "PadWalker module not found - please install\n"
+                        ? <<EOM
+PadWalker module not found - please install; try the command
+  perl -MCPAN -e "install PadWalker"
+EOM
                         : $@
                       )
                       and next CMD;
@@ -5788,69 +5791,70 @@ qq[3>&1 xterm -title "Daughter Perl debu
 
 XXX It behooves an OS/2 expert to write the necessary documentation for this!
 
+Starts a separate session (so a new console) with a kid Perl program; this
+program mirrors user's input of this session to one filehandle ($out), and
+displays data coming through $in filehandle.
+
+Since this kid program should not be debugged, we massage C<PERL5OPT>
+and C<PERL5LIB> environment variables to make the kid as reliable as possible.
+
+B<LIMITATIONS>: with the current logic the kid should inherit the filehandles
+created by pipe() calls; this we can't start it with C<P_INDEPENDENT> flag.
+However, in any session only one process can start a new session without
+this flag; thus only one window per session can be created.  (To fix this,
+one should communicate via named pipes or sockets...)
+
+Since the depended-sessions are killed when a parent terminates, the kids
+print C<Process terminated by SIGKILL> (?) messages; they are visible for a
+moment before the session closes.
+
 =cut
 
 # This example function resets $IN, $OUT itself
 sub os2_get_fork_TTY {
-    local $^F = 40;     # XXXX Fixme!
-    local $\  = '';
-    my ($in1, $out1, $in2, $out2);
-
     # Having -d in PERL5OPT would lead to a disaster...
     local $ENV{PERL5OPT} = $ENV{PERL5OPT} if $ENV{PERL5OPT};
     $ENV{PERL5OPT} =~ s/(?:^|(?<=\s))-d\b//  if $ENV{PERL5OPT};
     $ENV{PERL5OPT} =~ s/(?:^|(?<=\s))-d\B/-/ if $ENV{PERL5OPT};
     print $OUT "Making kid PERL5OPT->`$ENV{PERL5OPT}'.\n" if $ENV{PERL5OPT};
+
+    # Propagate libraries
     local $ENV{PERL5LIB} = $ENV{PERL5LIB} ? $ENV{PERL5LIB} : $ENV{PERLLIB};
     $ENV{PERL5LIB} = '' unless defined $ENV{PERL5LIB};
-    $ENV{PERL5LIB} = join ';', @ini_INC, split /;/, $ENV{PERL5LIB};
+    $ENV{PERL5LIB} = join ';', @INC, @ini_INC, split /;/, $ENV{PERL5LIB};
+
     (my $name = $0) =~ s,^.*[/\\],,s;
-    my @args;
 
-    if (
-            pipe $in1, $out1
-        and pipe $in2, $out2
-
-        # system P_SESSION will fail if there is another process
-        # in the same session with a "dependent" asynchronous child session.
-        and @args = (
-            $rl, fileno $in1, fileno $out2,
-            "Daughter Perl debugger $pids $name"
-        )
-        and (
-            ($kpid = CORE::system 4, $^X, '-we',
-                <<'ES', @args) >= 0    # P_SESSION
-END {sleep 5 unless $loaded}
-BEGIN {open STDIN,  '</dev/con' or warn "reopen stdin: $!"}
-use OS2::Process;
-
-my ($rl, $in) = (shift, shift);        # Read from $in and pass through
-set_title pop;
-system P_NOWAIT, $^X, '-we', <<EOS or die "Cannot start a grandkid";
-  open IN, '<&=$in' or die "open <&=$in: \$!";
-  \$| = 1; print while sysread IN, \$_, 1<<16;
+    # What follows until <<<<< is mostly almost exactly
+    #  require OS2::Process; my ($in, $out, $pid) = OS2::Process::io_term @args
+    local $^F = 40;     # XXXX Fixme!
+    local $\  = '';
+    my ($in1, $out1, $in2, $out2);
+
+    pipe $in1, $out1 or return;
+    pipe $in2, $out2 or do { close($in1), close($out1), return };
+
+    # system P_SESSION=4 will fail if there is another process
+    # in the same session with a "dependent" asynchronous child session.
+    my @args = (($rl ? (read_by_key => 1) : ()),
+		# scrsize => '40,50',
+		title => "Daughter Perl debugger $pids $name");
+    my $kpid = system 4, $^X, '-we', <<'EOS', fileno $in1, fileno $out2, @args;
+       END {sleep($sleep || 5)}
+       use OS2::Process; $sleep = 1;
+       OS2::Process::__term_mirror(@ARGV);
 EOS
+    close $in1 or warn;
+    close $out2 or warn;
+    warn "system P_SESSION, $^X: $!, $^E" and do { close($in2), close($out1), return }
+      unless $kpid > 0;
+    # <<<<<<<<<<<<<
 
-my $out = shift;
-open OUT, ">&=$out" or die "Cannot open &=$out for writing: $!";
-select OUT;    $| = 1;
-require Term::ReadKey if $rl;
-Term::ReadKey::ReadMode(4) if $rl; # Nodelay on kbd.  Pipe is automatically nodelay...
-print while sysread STDIN, $_, 1<<($rl ? 16 : 0);
-ES
-            or warn "system P_SESSION: $!, $^E" and 0
-        )
-        and close $in1
-        and close $out2
-      )
-    {
-        $pidprompt = '';    # Shown anyway in titlebar
-        reset_IN_OUT($in2, $out1);
-        $tty = '*reset*';
-        return '';          # Indicate that reset_IN_OUT is called
-    } ## end if (pipe $in1, $out1 and...
-    return;
-} ## end sub os2_get_fork_TTY
+    $pidprompt = '';    # Shown anyway in titlebar
+    reset_IN_OUT($in2, $out1);
+    $tty = '*reset*';
+    return '';          # Indicate that reset_IN_OUT is called
+}
 
 =head2 C<create_IN_OUT($flags)>
 
@@ -6763,8 +6767,8 @@ B<m> I<expr>		Evals expression in list c
 		on the first element of the result.
 B<m> I<class>		Prints methods callable via the given class.
 B<M>		Show versions of loaded modules.
-B<y> [I<n> [I<Vars>]]   List lexicals in higher scope <n>.  Vars same as B<V>.
-
+B<y> [I<n> [I<Vars>]]    List lexicals in higher scope <n>.  Vars same as B<V>.
+		Requires the module B<PadWalker>.
 B<<> ?			List Perl commands to run before each prompt.
 B<<> I<expr>		Define Perl command to run before each prompt.
 B<<<> I<expr>		Add to the list of Perl commands to run before each prompt.
@@ -6801,7 +6805,7 @@ B<R>		Pure-man-restart of debugger, some
 		and command-line options may be lost.
 		Currently the following settings are preserved:
 		history, breakpoints and actions, debugger B<O>ptions 
-		and the following command-line options: I<-w>, I<-I>, I<-e>.
+		and the following command-line options: I<-w>, I<-I>, I<-T>, I<-e>.
 
 B<o> [I<opt>] ...	Set boolean option to true
 B<o> [I<opt>B<?>]	Query options
@@ -6869,12 +6873,11 @@ I<Debugger controls:>                   
   B<|>[B<|>]I<db_cmd>  Send output to pager        B<$psh>\[B<$psh>\] I<syscmd> Run cmd in a subprocess
   B<q> or B<^D>     Quit                        B<R>           Attempt a restart
 I<Data Examination:>     B<expr>     Execute perl code, also see: B<s>,B<n>,B<t> I<expr>
-  B<x>|B<m> I<expr>       Evals expr in list context, dumps the result or lists methods.
-  B<p> I<expr>         Print expression (uses script's current package).
-  B<S> [[B<!>]I<pat>]     List subroutine names [not] matching pattern
-  B<V> [I<Pk> [I<Vars>]]  List Variables in Package.  Vars can be ~pattern or !pattern.
-  B<X> [I<Vars>]       Same as \"B<V> I<current_package> [I<Vars>]\".
-  B<y> [I<n> [I<Vars>]]   List lexicals in higher scope <n>.  Vars same as B<V>.
+  B<x>|B<m> I<expr>     Evals I<expr> in list context, dumps the result or lists methods.
+  B<p> I<expr>       Print expression I<expr> (uses script's current package).
+  B<S> [[B<!>]I<pat>]   List subroutine names [not] matching pattern I<pat>.
+  B<X> [I<Vars>]     List Variables in current package.  I<Vars> can be ~pattern or !pat
+  B<V> [I<Pk> [I<Vars>]] Same as B<X> for package I<Pk>.  Type B<h y> for access to lexicals.
 For more help, type B<h> I<cmd_letter>, or run B<$doccmd perldebug> for all docs.
 END_SUM
 
--- ./lib/File/Path.pm-pre	Wed Aug 13 23:52:38 2003
+++ ./lib/File/Path.pm	Thu Sep 18 11:30:18 2003
@@ -157,7 +157,8 @@ sub mkpath {
  	}
 	print "mkdir $path\n" if $verbose;
 	unless (mkdir($path,$mode)) {
-	    my $e = $!;
+	    my ($e, $e1) = ($!, $^E);
+	    $e .= "; $e1" if $e ne $e1;
 	    # allow for another process to have created it meanwhile
 	    croak "mkdir $path: $e" unless -d $path;
 	}
--- ./lib/CPAN/FirstTime.pm-pre	Tue Jul 29 09:48:00 2003
+++ ./lib/CPAN/FirstTime.pm	Thu Sep 18 01:26:24 2003
@@ -384,6 +384,19 @@ Typical frequently used setting:
 Your choice: ",$default);
 
     #
+    # Should we trust old builds?
+    #
+
+    $default = exists $CPAN::Config->{expire_old_builds} ?
+		exists $CPAN::Config->{expire_old_builds} : -1 ;
+    $CPAN::Config->{expire_old_builds} =
+	prompt("When should we expire old successfully tested builds?
+The value is in days; the value of -1 means 'never rebuild'; the value of 0
+means 'rebuild each time the distribution is tested'.
+
+Your choice: ",$default);
+
+    #
     # Alarm period
     #
 
