various win32-ish changes merged from maint-5.005
Gurusamy Sarathy [Mon, 1 Feb 1999 06:27:35 +0000 (06:27 +0000)]
p4raw-id: //depot/perl@2746

19 files changed:
README.win32
embedvar.h
globvar.sym
lib/ExtUtils/MM_Unix.pm
objXSUB.h
op.c
perl.h
perlvars.h
pp.c
sv.c
t/io/fs.t
toke.c
win32/Makefile
win32/config.bc
win32/config.vc
win32/config_sh.PL
win32/makefile.mk
win32/runperl.c
win32/win32.c

index b9f6b15..e696ab3 100644 (file)
@@ -107,7 +107,7 @@ make for building extensions using MakeMaker.
 
 =item Mingw32 with EGCS or GCC
 
-ECGS-1.0.2 binaries can be downloaded from:
+ECGS binaries can be downloaded from:
 
     ftp://ftp.xraylith.wisc.edu/pub/khan/gnu-win32/mingw32/
 
@@ -151,7 +151,12 @@ a perl interpreter that supports the Perl Object abstraction (courtesy
 ActiveState Tool Corp.)  PERL_OBJECT uses C++, and the binaries are
 therefore incompatible with the regular C build.  However, the
 PERL_OBJECT build does provide something called the C-API, for linking
-it with extensions that won't compile under PERL_OBJECT.  PERL_OBJECT
+it with extensions that won't compile under PERL_OBJECT. Using the C_API
+is typically requested through:
+
+    perl Makefile.PL CAPI=TRUE
+
+PERL_OBJECT requires VC++ 5.0 (Service Pack 3 recommended) or later. It
 is not yet supported under GCC or EGCS.  WARNING:  Binaries built with
 PERL_OBJECT enabled are B<not> compatible with binaries built without.
 Perl installs PERL_OBJECT binaries under a distinct architecture name,
@@ -187,10 +192,7 @@ Perl will also build without des_fcrypt(), but the crypt() builtin will
 fail at run time.
 
 You will also have to make sure CCHOME points to wherever you installed
-your compiler.  Make sure this path has no spaces in it.  If you
-insist on spaces in your path names, there is no telling what else
-will fail, but you can try putting the path in double quotes.  Some
-parts of perl try to accomodate that, but not all pieces do.
+your compiler.
 
 The default value for CCHOME in the makefiles for Visual C++
 may not be correct for some versions.  Make sure the default exists
@@ -261,7 +263,7 @@ you will need to add two components to your PATH environment variable,
 C<$INST_TOP\$VERSION\bin>, and C<$INST_TOP\$VERSION\bin\$ARCHNAME>.
 For example:
 
-    set PATH c:\perl\5.005\bin;c:\perl\5.005\bin\MSWin32-x6;%PATH%
+    set PATH c:\perl\5.005\bin;c:\perl\5.005\bin\MSWin32-x86;%PATH%
 
 
 =head2 Usage Hints
@@ -745,7 +747,9 @@ Borland support was added in 5.004_01 (Gurusamy Sarathy).
 
 GCC/mingw32 support was added in 5.005 (Nick Ing-Simmons).
 
-Last updated: 29 November 1998
+Support for PERL_OBJECT was added in 5.005 (ActiveState Tool Corp).
+
+Last updated: 18 January 1999
 
 =cut
 
index 2d25d41..8c7c2a7 100644 (file)
 #define PL_Yes                 (PL_Vars.GYes)
 #define PL_amagic_generation   (PL_Vars.Gamagic_generation)
 #define PL_an                  (PL_Vars.Gan)
+#define PL_bitcount            (PL_Vars.Gbitcount)
 #define PL_bufend              (PL_Vars.Gbufend)
 #define PL_bufptr              (PL_Vars.Gbufptr)
 #define PL_collation_ix                (PL_Vars.Gcollation_ix)
 #define PL_curthr              (PL_Vars.Gcurthr)
 #define PL_debug               (PL_Vars.Gdebug)
 #define PL_do_undump           (PL_Vars.Gdo_undump)
+#define PL_efloatbuf           (PL_Vars.Gefloatbuf)
+#define PL_efloatsize          (PL_Vars.Gefloatsize)
 #define PL_egid                        (PL_Vars.Gegid)
 #define PL_error_count         (PL_Vars.Gerror_count)
 #define PL_euid                        (PL_Vars.Geuid)
 #define PL_eval_owner          (PL_Vars.Geval_owner)
 #define PL_evalseq             (PL_Vars.Gevalseq)
 #define PL_expect              (PL_Vars.Gexpect)
+#define PL_filter_debug                (PL_Vars.Gfilter_debug)
 #define PL_gid                 (PL_Vars.Ggid)
+#define PL_glob_index          (PL_Vars.Gglob_index)
 #define PL_he_root             (PL_Vars.Ghe_root)
 #define PL_hexdigit            (PL_Vars.Ghexdigit)
 #define PL_hints               (PL_Vars.Ghints)
 #define PL_sh_path             (PL_Vars.Gsh_path)
 #define PL_sighandlerp         (PL_Vars.Gsighandlerp)
 #define PL_specialsv_list      (PL_Vars.Gspecialsv_list)
+#define PL_srand_called                (PL_Vars.Gsrand_called)
 #define PL_subline             (PL_Vars.Gsubline)
 #define PL_subname             (PL_Vars.Gsubname)
 #define PL_sv_mutex            (PL_Vars.Gsv_mutex)
 #define PL_utf8_totitle                (PL_Vars.Gutf8_totitle)
 #define PL_utf8_toupper                (PL_Vars.Gutf8_toupper)
 #define PL_utf8_upper          (PL_Vars.Gutf8_upper)
+#define PL_uudmap              (PL_Vars.Guudmap)
 #define PL_xiv_arenaroot       (PL_Vars.Gxiv_arenaroot)
 #define PL_xiv_root            (PL_Vars.Gxiv_root)
 #define PL_xnv_root            (PL_Vars.Gxnv_root)
 #define PL_GYes                        PL_Yes
 #define PL_Gamagic_generation  PL_amagic_generation
 #define PL_Gan                 PL_an
+#define PL_Gbitcount           PL_bitcount
 #define PL_Gbufend             PL_bufend
 #define PL_Gbufptr             PL_bufptr
 #define PL_Gcollation_ix       PL_collation_ix
 #define PL_Gcurthr             PL_curthr
 #define PL_Gdebug              PL_debug
 #define PL_Gdo_undump          PL_do_undump
+#define PL_Gefloatbuf          PL_efloatbuf
+#define PL_Gefloatsize         PL_efloatsize
 #define PL_Gegid               PL_egid
 #define PL_Gerror_count                PL_error_count
 #define PL_Geuid               PL_euid
 #define PL_Geval_owner         PL_eval_owner
 #define PL_Gevalseq            PL_evalseq
 #define PL_Gexpect             PL_expect
+#define PL_Gfilter_debug       PL_filter_debug
 #define PL_Ggid                        PL_gid
+#define PL_Gglob_index         PL_glob_index
 #define PL_Ghe_root            PL_he_root
 #define PL_Ghexdigit           PL_hexdigit
 #define PL_Ghints              PL_hints
 #define PL_Gsh_path            PL_sh_path
 #define PL_Gsighandlerp                PL_sighandlerp
 #define PL_Gspecialsv_list     PL_specialsv_list
+#define PL_Gsrand_called       PL_srand_called
 #define PL_Gsubline            PL_subline
 #define PL_Gsubname            PL_subname
 #define PL_Gsv_mutex           PL_sv_mutex
 #define PL_Gutf8_totitle       PL_utf8_totitle
 #define PL_Gutf8_toupper       PL_utf8_toupper
 #define PL_Gutf8_upper         PL_utf8_upper
+#define PL_Guudmap             PL_uudmap
 #define PL_Gxiv_arenaroot      PL_xiv_arenaroot
 #define PL_Gxiv_root           PL_xiv_root
 #define PL_Gxnv_root           PL_xnv_root
index 0bf1fee..3cb8ccc 100644 (file)
@@ -37,6 +37,7 @@ psig_ptr
 regkind
 simple
 utf8skip
+uuemap
 varies
 vtbl_sv
 vtbl_env
index a5a4459..60f03d8 100644 (file)
@@ -2763,9 +2763,11 @@ sub ppd {
     foreach $prereq (sort keys %{$self->{PREREQ_PM}}) {
         my $pre_req = $prereq;
         $pre_req =~ s/::/-/g;
-        push(@m, ". qq{\\t\\t<DEPENDENCY NAME=\\\"$pre_req\\\" />\\n}");
+        my ($dep_ver) = join ",", (split (/\./, $self->{PREREQ_PM}{$prereq}), (0) x 4) [0 .. 3];
+        push(@m, ". qq{\\t\\t<DEPENDENCY NAME=\\\"$pre_req\\\" VERSION=\\\"$dep_ver\\\" />\\n}");
     }
     push(@m, ". qq{\\t\\t<OS NAME=\\\"\$(OSNAME)\\\" />\\n}");
+    push(@m, ". qq{\\t\\t<ARCHITECTURE NAME=\\\"$Config{'archname'}\\\" />\\n}");
     my ($bin_location) = $self->{BINARY_LOCATION};
     $bin_location =~ s/\\/\\\\/g;
     if ($self->{PPM_INSTALL_SCRIPT}) {
@@ -3539,6 +3541,7 @@ and Win32 do.
 
 sub perl_archive
 {
+ return '$(PERL_INC)' . "/$Config{libperl}" if $^O eq "beos";
  return "";
 }
 
index 97845f8..9c8460f 100644 (file)
--- a/objXSUB.h
+++ b/objXSUB.h
@@ -52,6 +52,8 @@
 #define PL_basetime            pPerl->PL_basetime
 #undef  PL_beginav
 #define PL_beginav             pPerl->PL_beginav
+#undef  PL_bitcount
+#define PL_bitcount            pPerl->PL_bitcount
 #undef  PL_bodytarget
 #define PL_bodytarget          pPerl->PL_bodytarget
 #undef  PL_bostr
 #define PL_dumpindent          pPerl->PL_dumpindent
 #undef  PL_e_script
 #define PL_e_script            pPerl->PL_e_script
+#undef  PL_efloatbuf
+#define PL_efloatbuf           pPerl->PL_efloatbuf
+#undef  PL_efloatsize
+#define PL_efloatsize          pPerl->PL_efloatsize
 #undef  PL_egid
 #define PL_egid                        pPerl->PL_egid
 #undef  PL_endav
 #define PL_fdpid               pPerl->PL_fdpid
 #undef  PL_filemode
 #define PL_filemode            pPerl->PL_filemode
+#undef  PL_filter_debug
+#define PL_filter_debug                pPerl->PL_filter_debug
 #undef  PL_firstgv
 #define PL_firstgv             pPerl->PL_firstgv
 #undef  PL_forkprocess
 #define PL_gensym              pPerl->PL_gensym
 #undef  PL_gid
 #define PL_gid                 pPerl->PL_gid
+#undef  PL_glob_index
+#define PL_glob_index          pPerl->PL_glob_index
 #undef  PL_globalstash
 #define PL_globalstash         pPerl->PL_globalstash
 #undef  PL_he_root
 #define PL_specialsv_list      pPerl->PL_specialsv_list
 #undef  PL_splitstr
 #define PL_splitstr            pPerl->PL_splitstr
+#undef  PL_srand_called
+#define PL_srand_called                pPerl->PL_srand_called
 #undef  PL_stack_base
 #define PL_stack_base          pPerl->PL_stack_base
 #undef  PL_stack_max
 #define PL_utf8_toupper                pPerl->PL_utf8_toupper
 #undef  PL_utf8_upper
 #define PL_utf8_upper          pPerl->PL_utf8_upper
+#undef  PL_uudmap
+#define PL_uudmap              pPerl->PL_uudmap
 #undef  PL_warnhook
 #define PL_warnhook            pPerl->PL_warnhook
 #undef  PL_watchaddr
diff --git a/op.c b/op.c
index 035247b..94fbc15 100644 (file)
--- a/op.c
+++ b/op.c
@@ -4763,10 +4763,8 @@ ck_glob(OP *o)
        gv = gv_fetchpv("CORE::GLOBAL::glob", FALSE, SVt_PVCV);
 
     if (gv && GvIMPORTED_CV(gv)) {
-       static int glob_index;
-
        append_elem(OP_GLOB, o,
-                   newSVOP(OP_CONST, 0, newSViv(glob_index++)));
+                   newSVOP(OP_CONST, 0, newSViv(PL_glob_index++)));
        o->op_type = OP_LIST;
        o->op_ppaddr = PL_ppaddr[OP_LIST];
        cLISTOPo->op_first->op_type = OP_PUSHMARK;
diff --git a/perl.h b/perl.h
index c7e328a..c493bd0 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -1806,7 +1806,7 @@ char *getlogin _((void));
 #define UNLINK unlnk
 I32 unlnk _((char*));
 #else
-#define UNLINK unlink
+#define UNLINK PerlLIO_unlink
 #endif
 
 #ifndef HAS_SETREUID
@@ -1936,6 +1936,10 @@ EXTCONST char PL_no_func[]
 EXTCONST char PL_no_myglob[]
   INIT("\"my\" variable %s can't be in a package");
 
+EXTCONST char PL_uuemap[]
+  INIT("`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_");
+
+
 #ifdef DOINIT
 EXT char *PL_sig_name[] = { SIG_NAME };
 EXT int   PL_sig_num[]  = { SIG_NUM };
index 3860345..2909387 100644 (file)
@@ -130,7 +130,7 @@ PERLVAR(Gthisexpr,  I32)            /* name id for nothing_in_common() */
 PERLVAR(Glast_uni,     char *)         /* position of last named-unary op */
 PERLVAR(Glast_lop,     char *)         /* position of last list operator */
 PERLVAR(Glast_lop_op,  OPCODE)         /* last list operator */
-PERLVAR(Gin_my,        bool)                   /* we're compiling a "my" declaration */
+PERLVAR(Gin_my,                bool)           /* we're compiling a "my" declaration */
 PERLVAR(Gin_my_stash,  HV *)           /* declared class of this "my" declaration */
 #ifdef FCRYPT
 PERLVAR(Gcryptseen,    I32)            /* has fast crypt() been initialized? */
@@ -200,3 +200,12 @@ PERLVAR(Gyyerrflag,        int)
 PERLVAR(Gyychar,       int)
 PERLVAR(Gyyval,                YYSTYPE)
 PERLVAR(Gyylval,       YYSTYPE)
+
+PERLVAR(Gglob_index,   int)
+PERLVAR(Gefloatbuf,    char*)
+PERLVAR(Gefloatsize,   STRLEN)
+PERLVAR(Gsrand_called, bool)
+PERLVAR(Guudmap[256],  char)
+PERLVAR(Gbitcount,     char *)
+PERLVAR(Gfilter_debug, int)
+
diff --git a/pp.c b/pp.c
index b378d7d..cd8c078 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -107,8 +107,6 @@ static SV* refto _((SV* sv));
 static U32 seed _((void));
 #endif
 
-static bool srand_called = FALSE;
-
 /* variations on pp_null */
 
 #ifdef I_UNISTD
@@ -1596,9 +1594,9 @@ PP(pp_rand)
        value = POPn;
     if (value == 0.0)
        value = 1.0;
-    if (!srand_called) {
+    if (!PL_srand_called) {
        (void)seedDrand01((Rand_seed_t)seed());
-       srand_called = TRUE;
+       PL_srand_called = TRUE;
     }
     value *= Drand01();
     XPUSHn(value);
@@ -1614,7 +1612,7 @@ PP(pp_srand)
     else
        anum = POPu;
     (void)seedDrand01((Rand_seed_t)anum);
-    srand_called = TRUE;
+    PL_srand_called = TRUE;
     EXTEND(SP, 1);
     RETPUSHYES;
 }
@@ -3171,9 +3169,6 @@ mul128(SV *sv, U8 m)
 
 /* Explosives and implosives. */
 
-static const char uuemap[] =
-    "`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
-static char uudmap[256];        /* Initialised on first use */
 #if 'I' == 73 && 'J' == 74
 /* On an ASCII/ISO kind of system */
 #define ISUUCHAR(ch)    ((ch) >= ' ' && (ch) < 'a')
@@ -3182,7 +3177,7 @@ static char uudmap[256];        /* Initialised on first use */
   Some other sort of character set - use memchr() so we don't match
   the null byte.
  */
-#define ISUUCHAR(ch)    (memchr(uuemap, (ch), sizeof(uuemap)-1) || (ch) == ' ')
+#define ISUUCHAR(ch)    (memchr(PL_uuemap, (ch), sizeof(PL_uuemap)-1) || (ch) == ' ')
 #endif
 
 PP(pp_unpack)
@@ -3222,7 +3217,6 @@ PP(pp_unpack)
     I32 checksum = 0;
     register U32 culong;
     double cdouble;
-    static char* bitcount = 0;
     int commas = 0;
 
     if (gimme != G_ARRAY) {            /* arrange to do first one only */
@@ -3310,21 +3304,21 @@ PP(pp_unpack)
            if (pat[-1] == '*' || len > (strend - s) * 8)
                len = (strend - s) * 8;
            if (checksum) {
-               if (!bitcount) {
-                   Newz(601, bitcount, 256, char);
+               if (!PL_bitcount) {
+                   Newz(601, PL_bitcount, 256, char);
                    for (bits = 1; bits < 256; bits++) {
-                       if (bits & 1)   bitcount[bits]++;
-                       if (bits & 2)   bitcount[bits]++;
-                       if (bits & 4)   bitcount[bits]++;
-                       if (bits & 8)   bitcount[bits]++;
-                       if (bits & 16)  bitcount[bits]++;
-                       if (bits & 32)  bitcount[bits]++;
-                       if (bits & 64)  bitcount[bits]++;
-                       if (bits & 128) bitcount[bits]++;
+                       if (bits & 1)   PL_bitcount[bits]++;
+                       if (bits & 2)   PL_bitcount[bits]++;
+                       if (bits & 4)   PL_bitcount[bits]++;
+                       if (bits & 8)   PL_bitcount[bits]++;
+                       if (bits & 16)  PL_bitcount[bits]++;
+                       if (bits & 32)  PL_bitcount[bits]++;
+                       if (bits & 64)  PL_bitcount[bits]++;
+                       if (bits & 128) PL_bitcount[bits]++;
                    }
                }
                while (len >= 8) {
-                   culong += bitcount[*(unsigned char*)s++];
+                   culong += PL_bitcount[*(unsigned char*)s++];
                    len -= 8;
                }
                if (len) {
@@ -3853,16 +3847,16 @@ PP(pp_unpack)
              * algorithm, the code will be character-set independent
              * (and just as fast as doing character arithmetic)
              */
-            if (uudmap['M'] == 0) {
+            if (PL_uudmap['M'] == 0) {
                 int i;
  
-                for (i = 0; i < sizeof(uuemap); i += 1)
-                    uudmap[uuemap[i]] = i;
+                for (i = 0; i < sizeof(PL_uuemap); i += 1)
+                    PL_uudmap[PL_uuemap[i]] = i;
                 /*
                  * Because ' ' and '`' map to the same value,
                  * we need to decode them both the same.
                  */
-                uudmap[' '] = 0;
+                PL_uudmap[' '] = 0;
             }
 
            along = (strend - s) * 3 / 4;
@@ -3874,22 +3868,22 @@ PP(pp_unpack)
                char hunk[4];
 
                hunk[3] = '\0';
-               len = uudmap[*s++] & 077;
+               len = PL_uudmap[*s++] & 077;
                while (len > 0) {
                    if (s < strend && ISUUCHAR(*s))
-                       a = uudmap[*s++] & 077;
+                       a = PL_uudmap[*s++] & 077;
                    else
                        a = 0;
                    if (s < strend && ISUUCHAR(*s))
-                       b = uudmap[*s++] & 077;
+                       b = PL_uudmap[*s++] & 077;
                    else
                        b = 0;
                    if (s < strend && ISUUCHAR(*s))
-                       c = uudmap[*s++] & 077;
+                       c = PL_uudmap[*s++] & 077;
                    else
                        c = 0;
                    if (s < strend && ISUUCHAR(*s))
-                       d = uudmap[*s++] & 077;
+                       d = PL_uudmap[*s++] & 077;
                    else
                        d = 0;
                    hunk[0] = (a << 2) | (b >> 4);
@@ -3950,24 +3944,24 @@ doencodes(register SV *sv, register char *s, register I32 len)
 {
     char hunk[5];
 
-    *hunk = uuemap[len];
+    *hunk = PL_uuemap[len];
     sv_catpvn(sv, hunk, 1);
     hunk[4] = '\0';
     while (len > 2) {
-       hunk[0] = uuemap[(077 & (*s >> 2))];
-       hunk[1] = uuemap[(077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017)))];
-       hunk[2] = uuemap[(077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03)))];
-       hunk[3] = uuemap[(077 & (s[2] & 077))];
+       hunk[0] = PL_uuemap[(077 & (*s >> 2))];
+       hunk[1] = PL_uuemap[(077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017)))];
+       hunk[2] = PL_uuemap[(077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03)))];
+       hunk[3] = PL_uuemap[(077 & (s[2] & 077))];
        sv_catpvn(sv, hunk, 4);
        s += 3;
        len -= 3;
     }
     if (len > 0) {
        char r = (len > 1 ? s[1] : '\0');
-       hunk[0] = uuemap[(077 & (*s >> 2))];
-       hunk[1] = uuemap[(077 & (((*s << 4) & 060) | ((r >> 4) & 017)))];
-       hunk[2] = uuemap[(077 & ((r << 2) & 074))];
-       hunk[3] = uuemap[0];
+       hunk[0] = PL_uuemap[(077 & (*s >> 2))];
+       hunk[1] = PL_uuemap[(077 & (((*s << 4) & 060) | ((r >> 4) & 017)))];
+       hunk[2] = PL_uuemap[(077 & ((r << 2) & 074))];
+       hunk[3] = PL_uuemap[0];
        sv_catpvn(sv, hunk, 4);
     }
     sv_catpvn(sv, "\n", 1);
diff --git a/sv.c b/sv.c
index 6d900ce..2dea64f 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -4413,10 +4413,6 @@ sv_vcatpvfn(SV *sv, const char *pat, STRLEN patlen, va_list *args, SV **svargs,
        char *eptr = Nullch;
        STRLEN elen = 0;
        char ebuf[TYPE_DIGITS(int) * 2 + 16]; /* large enough for "%#.#f" */
-
-       static char *efloatbuf = Nullch;
-       static STRLEN efloatsize = 0;
-
        char c;
        int i;
        unsigned base;
@@ -4758,10 +4754,10 @@ sv_vcatpvfn(SV *sv, const char *pat, STRLEN patlen, va_list *args, SV **svargs,
                need = width;
 
            need += 20; /* fudge factor */
-           if (efloatsize < need) {
-               Safefree(efloatbuf);
-               efloatsize = need + 20; /* more fudge */
-               New(906, efloatbuf, efloatsize, char);
+           if (PL_efloatsize < need) {
+               Safefree(PL_efloatbuf);
+               PL_efloatsize = need + 20; /* more fudge */
+               New(906, PL_efloatbuf, PL_efloatsize, char);
            }
 
            eptr = ebuf + sizeof ebuf;
@@ -4786,10 +4782,10 @@ sv_vcatpvfn(SV *sv, const char *pat, STRLEN patlen, va_list *args, SV **svargs,
                *--eptr = '#';
            *--eptr = '%';
 
-           (void)sprintf(efloatbuf, eptr, nv);
+           (void)sprintf(PL_efloatbuf, eptr, nv);
 
-           eptr = efloatbuf;
-           elen = strlen(efloatbuf);
+           eptr = PL_efloatbuf;
+           elen = strlen(PL_efloatbuf);
 
 #ifdef LC_NUMERIC
            /*
index c15f772..f09d66c 100755 (executable)
--- a/t/io/fs.t
+++ b/t/io/fs.t
@@ -9,24 +9,23 @@ BEGIN {
 
 use Config;
 
-$Is_Dosish = ($^O eq 'dos' or $^O eq 'os2' or $^O eq 'mint');
+$Is_Dosish = ($^O eq 'MSWin32' or $^O eq 'dos' or
+             $^O eq 'os2' or $^O eq 'mint');
 
-# avoid win32 (for now)
-do { print "1..0\n"; exit(0); } if $^O eq 'MSWin32';
-
-print "1..26\n";
+print "1..28\n";
 
 $wd = (($^O eq 'MSWin32') ? `cd` : `pwd`);
 chop($wd);
 
-if ($^O eq 'MSWin32') { `del tmp`; `mkdir tmp`; }
+if ($^O eq 'MSWin32') { `del tmp 2>nul`; `mkdir tmp`; }
 else {  `rm -f tmp 2>/dev/null; mkdir tmp 2>/dev/null`; }
 chdir './tmp';
 `/bin/rm -rf a b c x` if -x '/bin/rm';
 
 umask(022);
 
-if ((umask(0)&0777) == 022) {print "ok 1\n";} else {print "not ok 1\n";}
+if ($^O eq 'MSWin32') { print "ok 1 # skipped: bogus umask()\n"; }
+elsif ((umask(0)&0777) == 022) {print "ok 1\n";} else {print "not ok 1\n";}
 open(fh,'>x') || die "Can't create x";
 close(fh);
 open(fh,'>a') || die "Can't create a";
@@ -98,8 +97,9 @@ $foo = (utime 500000000,500000000 + $delta,'b');
 if ($foo == 1) {print "ok 16\n";} else {print "not ok 16 $foo\n";}
 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
     $blksize,$blocks) = stat('b');
-if ($ino) {print "ok 17\n";} else {print "not ok 17\n";}
-if ($wd =~ m#/afs/# || $^O eq 'amigaos' || $^O eq 'dos')
+if ($^O eq 'MSWin32') { print "ok 17 # skipped: bogus (stat)[1]\n"; }
+elsif ($ino) {print "ok 17\n";} else {print "not ok 17\n";}
+if ($wd =~ m#/afs/# || $^O eq 'amigaos' || $^O eq 'dos' || $^O eq 'MSWin32')
     {print "ok 18 # skipped: granularity of the filetime\n";}
 elsif ($atime == 500000000 && $mtime == 500000000 + $delta)
     {print "ok 18\n";}
@@ -113,7 +113,6 @@ if ($ino == 0) {print "ok 20\n";} else {print "not ok 20\n";}
 unlink 'c';
 
 chdir $wd || die "Can't cd back to $wd";
-rmdir 'tmp';
 
 unlink 'c';
 if ($^O ne 'MSWin32' and `ls -l perl 2>/dev/null` =~ /^l.*->/) {
@@ -156,4 +155,11 @@ else {
   if (-z "Iofs.tmp") {print "ok 26\n"} else {print "not ok 26\n"}
   close FH;
 }
-unlink "Iofs.tmp";
+
+# check if rename() works on directories
+rename 'tmp', 'tmp1' or print "not ";
+print "ok 27\n";
+-d 'tmp1' or print "not ";
+print "ok 28\n";
+
+END { rmdir 'tmp1'; unlink "Iofs.tmp"; }
diff --git a/toke.c b/toke.c
index 66d9947..f697741 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -1450,13 +1450,12 @@ incl_perldb(void)
  * Note that IoTOP_NAME, IoFMT_NAME, IoBOTTOM_NAME, if set for
  * private use must be set using malloc'd pointers.
  */
-static int filter_debug = 0;
 
 SV *
 filter_add(filter_t funcp, SV *datasv)
 {
     if (!funcp){ /* temporary handy debugging hack to be deleted */
-       filter_debug = atoi((char*)datasv);
+       PL_filter_debug = atoi((char*)datasv);
        return NULL;
     }
     if (!PL_rsfp_filters)
@@ -1466,7 +1465,7 @@ filter_add(filter_t funcp, SV *datasv)
     if (!SvUPGRADE(datasv, SVt_PVIO))
         die("Can't upgrade filter_add data to SVt_PVIO");
     IoDIRP(datasv) = (DIR*)funcp; /* stash funcp into spare field */
-    if (filter_debug) {
+    if (PL_filter_debug) {
        STRLEN n_a;
        warn("filter_add func %p (%s)", funcp, SvPV(datasv, n_a));
     }
@@ -1480,7 +1479,7 @@ filter_add(filter_t funcp, SV *datasv)
 void
 filter_del(filter_t funcp)
 {
-    if (filter_debug)
+    if (PL_filter_debug)
        warn("filter_del func %p", funcp);
     if (!PL_rsfp_filters || AvFILLp(PL_rsfp_filters)<0)
        return;
@@ -1510,7 +1509,7 @@ filter_read(int idx, SV *buf_sv, int maxlen)
     if (idx > AvFILLp(PL_rsfp_filters)){       /* Any more filters?    */
        /* Provide a default input filter to make life easy.    */
        /* Note that we append to the line. This is handy.      */
-       if (filter_debug)
+       if (PL_filter_debug)
            warn("filter_read %d: from rsfp\n", idx);
        if (maxlen) { 
            /* Want a block */
@@ -1539,13 +1538,13 @@ filter_read(int idx, SV *buf_sv, int maxlen)
     }
     /* Skip this filter slot if filter has been deleted        */
     if ( (datasv = FILTER_DATA(idx)) == &PL_sv_undef){
-       if (filter_debug)
+       if (PL_filter_debug)
            warn("filter_read %d: skipped (filter deleted)\n", idx);
        return FILTER_READ(idx+1, buf_sv, maxlen); /* recurse */
     }
     /* Get function pointer hidden within datasv       */
     funcp = (filter_t)IoDIRP(datasv);
-    if (filter_debug) {
+    if (PL_filter_debug) {
        STRLEN n_a;
        warn("filter_read %d: via function %p (%s)\n",
                idx, funcp, SvPV(datasv,n_a));
@@ -2134,7 +2133,7 @@ int yylex(PERL_YYLEX_PARAM_DECL)
                    else
                        newargv = PL_origargv;
                    newargv[0] = ipath;
-                   execv(ipath, newargv);
+                   PerlProc_execv(ipath, newargv);
                    croak("Can't exec %s", ipath);
                }
                if (d) {
index bee48c0..3b3c4d4 100644 (file)
@@ -111,12 +111,8 @@ INST_VER   = \5.00554
 # set the install locations of the compiler include/libraries
 # Running VCVARS32.BAT is *required* when using Visual C.
 # Some versions of Visual C don't define MSVCDIR in the environment,
-# so you may have to set CCHOME explicitly.
-#
-# If the path contains spaces, you can try putting it in double
-# quotes, but support for this is not well-tested, and various
-# other things may break, so you're kinda on your own if you are
-# into specious paths. :-)
+# so you may have to set CCHOME explicitly (spaces in the path name should
+# not be quoted)
 #
 #CCHOME                = f:\msvc20
 CCHOME         = $(MSVCDIR)
@@ -135,7 +131,8 @@ CCLIBDIR    = $(CCHOME)\lib
 #BUILDOPT      = -DPERL_POLLUTE
 
 #
-# specify space-separated list of extra directories to look for libraries
+# specify semicolon-separated list of extra directories that modules will
+# look for libraries (spaces in path names need not be quoted)
 #
 EXTRALIBDIRS   =
 
@@ -590,14 +587,14 @@ CFG_VARS  =                                       \
                "INST_VER=$(INST_VER)"                  \
                "archname=$(ARCHNAME)"                  \
                "cc=$(CC)"                              \
-               "ccflags=$(OPTIMIZE) $(DEFINES) $(OBJECT)"      \
+               "ccflags=$(OPTIMIZE:"=\") $(DEFINES) $(OBJECT)" \
                "cf_email=$(EMAIL)"                     \
                "d_crypt=$(D_CRYPT)"                    \
                "d_mymalloc=$(PERL_MALLOC)"             \
                "libs=$(LIBFILES)"                      \
-               "incpath=$(CCINCDIR)"                   \
-               "libperl=$(PERLIMPLIB:..\=)"                    \
-               "libpth=$(CCLIBDIR) $(EXTRALIBDIRS)"    \
+               "incpath=$(CCINCDIR:"=\")"              \
+               "libperl=$(PERLIMPLIB:..\=)"            \
+               "libpth=$(CCLIBDIR:"=\");$(EXTRALIBDIRS:"=\")"  \
                "libc=$(LIBC)"                          \
                "make=nmake"                            \
                "static_ext=$(STATIC_EXT)"              \
@@ -605,8 +602,8 @@ CFG_VARS    =                                       \
                "nonxs_ext=$(NONXS_EXT)"                \
                "usethreads=$(USE_THREADS)"             \
                "usemultiplicity=$(USE_MULTI)"          \
-               "LINK_FLAGS=$(LINK_FLAGS)"              \
-               "optimize=$(OPTIMIZE)"
+               "LINK_FLAGS=$(LINK_FLAGS:"=\")"         \
+               "optimize=$(OPTIMIZE:"=\")"
 
 #
 # Top targets
@@ -645,7 +642,7 @@ regen_config_h:
        perl configpm
        cd win32
        -del /f $(CFGH_TMPL)
-       -mkdir ..\lib\CORE
+       -mkdir $(COREDIR)
        -perl -I..\lib config_h.PL "INST_VER=$(INST_VER)"
        rename config.h $(CFGH_TMPL)
 
@@ -657,7 +654,7 @@ $(CONFIGPM) : $(MINIPERL) ..\config.sh config_h.PL ..\minimod.pl
        $(XCOPY) ..\ext\re\re.pm $(LIBDIR)\*.*
        $(RCOPY) include $(COREDIR)\*.*
        $(MINIPERL) -I..\lib config_h.PL "INST_VER=$(INST_VER)" \
-           || $(MAKE) $(MAKEFLAGS) $(CONFIGPM)
+           || $(MAKE) /$(MAKEFLAGS) $(CONFIGPM)
 
 $(MINIPERL) : $(MINIDIR) $(MINI_OBJ)
        $(LINK32) -subsystem:console -out:$@ @<<
index c460453..d91fbb9 100644 (file)
@@ -546,7 +546,7 @@ shrpenv=''
 shsharp='true'
 sig_name='ZERO NUM01 INT QUIT ILL NUM05 NUM06 NUM07 FPE KILL NUM10 SEGV NUM12 PIPE ALRM TERM USR1 USR2 CHLD NUM19 USR3 BREAK ABRT STOP NUM24 CONT CLD'
 sig_name_init='"ZERO", "NUM01", "INT", "QUIT", "ILL", "NUM05", "NUM06", "NUM07", "FPE", "KILL", "NUM10", "SEGV", "NUM12", "PIPE", "ALRM", "TERM", "USR1", "USR2", "CHLD", "NUM19", "USR3", "BREAK", "ABRT", "STOP", "NUM24", "CONT", "CLD", 0'
-sig_num='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 18 '
+sig_num='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 18 0'
 sig_num_init='0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 18, 0'
 signal_t='void'
 sitearch='~INST_TOP~\site~INST_VER~\lib\~archname~'
index 81bd724..1a99dd9 100644 (file)
@@ -546,7 +546,7 @@ shrpenv=''
 shsharp='true'
 sig_name='ZERO NUM01 INT QUIT ILL NUM05 NUM06 NUM07 FPE KILL NUM10 SEGV NUM12 PIPE ALRM TERM NUM16 NUM17 NUM18 NUM19 CHLD BREAK ABRT STOP NUM24 CONT CLD'
 sig_name_init='"ZERO", "NUM01", "INT", "QUIT", "ILL", "NUM05", "NUM06", "NUM07", "FPE", "KILL", "NUM10", "SEGV", "NUM12", "PIPE", "ALRM", "TERM", "NUM16", "NUM17", "NUM18", "NUM19", "CHLD", "BREAK", "ABRT", "STOP", "NUM24", "CONT", "CLD", 0'
-sig_num='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 20 '
+sig_num='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 20 0'
 sig_num_init='0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 20, 0'
 signal_t='void'
 sitearch='~INST_TOP~\site~INST_VER~\lib\~archname~'
index 59e64f9..1d4b2fb 100644 (file)
@@ -1,3 +1,15 @@
+# take a semicolon separated path list and turn it into a quoted
+# list of paths that Text::Parsewords will grok
+sub mungepath {
+    my $p = shift;
+    # remove leading/trailing semis/spaces
+    $p =~ s/^[ ;]+//;
+    $p =~ s/[ ;]+$//;
+    $p =~ s/'/"/g;
+    my @p = map { $_ = "\"$_\"" if /\s/ and !/^".*"$/; $_ } split /;/, $p;
+    return join(' ', @p);
+}
+
 my %opt;
 while (@ARGV && $ARGV[0] =~ /^([\w_]+)=(.*)$/)
  {
@@ -17,6 +29,9 @@ $opt{'cf_email'} = $opt{'cf_by'} . '@' . (gethostbyname('localhost'))[0]
        unless $opt{'cf_email'};
 $opt{'usemymalloc'} = 'y' if $opt{'d_mymalloc'} eq 'define';
 
+$opt{libpth} = mungepath($opt{libpth}) if exists $opt{libpth};
+$opt{incpath} = mungepath($opt{incpath}) if exists $opt{incpath};
+
 while (<>)
  {
   s/~([\w_]+)~/$opt{$1}/g;
index 56f17ea..dab54d6 100644 (file)
@@ -122,12 +122,8 @@ CCTYPE             *= BORLAND
 # set the install locations of the compiler include/libraries
 # Running VCVARS32.BAT is *required* when using Visual C.
 # Some versions of Visual C don't define MSVCDIR in the environment,
-# so you may have to set CCHOME explicitly.
-#
-# If the path contains spaces, you can try putting it in double
-# quotes, but support for this is not well-tested, and various
-# other things may break, so you're kinda on your own if you are
-# into specious paths. :-)
+# so you may have to set CCHOME explicitly (spaces in the path name should
+# not be quoted)
 #
 CCHOME         *= C:\bc5
 #CCHOME                *= $(MSVCDIR)
@@ -147,7 +143,8 @@ CCLIBDIR    *= $(CCHOME)\lib
 #BUILDOPT      *= -DPERL_POLLUTE
 
 #
-# specify space-separated list of extra directories to look for libraries
+# specify semicolon-separated list of extra directories that modules will
+# look for libraries (spaces in path names need not be quoted)
 #
 EXTRALIBDIRS   *=
 
@@ -220,7 +217,7 @@ IMPLIB              = implib -c
 # Options
 #
 RUNTIME                = -D_RTLDLL
-INCLUDES       = -I$(COREDIR) -I.\include -I. -I.. -I$(CCINCDIR)
+INCLUDES       = -I$(COREDIR) -I.\include -I. -I.. -I"$(CCINCDIR)"
 #PCHFLAGS      = -H -Hc -H=c:\temp\bcmoduls.pch 
 DEFINES                = -DWIN32 $(BUILDOPT) $(CRYPT_FLAG)
 LOCDEFS                = -DPERLDLL -DPERL_CORE
@@ -240,7 +237,7 @@ LINK_DBG    =
 
 CFLAGS         = -w -g0 -tWM -tWD $(INCLUDES) $(DEFINES) $(LOCDEFS) \
                $(PCHFLAGS) $(OPTIMIZE)
-LINK_FLAGS     = $(LINK_DBG) -L$(CCLIBDIR) $(EXTRALIBDIRS:^"-L")
+LINK_FLAGS     = $(LINK_DBG) -L"$(CCLIBDIR)"
 OBJOUT_FLAG    = -o
 EXEOUT_FLAG    = -e
 LIBOUT_FLAG    = 
@@ -278,7 +275,7 @@ LINK_DBG    =
 .ENDIF
 
 CFLAGS         = $(INCLUDES) $(DEFINES) $(LOCDEFS) $(OPTIMIZE)
-LINK_FLAGS     = $(LINK_DBG) -L$(CCLIBDIR) $(EXTRALIBDIRS:^"-L")
+LINK_FLAGS     = $(LINK_DBG) -L"$(CCLIBDIR)"
 OBJOUT_FLAG    = -o
 EXEOUT_FLAG    = -o
 LIBOUT_FLAG    = 
@@ -705,14 +702,14 @@ CFG_VARS  =                                       \
                "INST_VER=$(INST_VER)"                  \
                "archname=$(ARCHNAME)"                  \
                "cc=$(CC)"                              \
-               "ccflags=$(OPTIMIZE) $(DEFINES) $(OBJECT)"      \
+               "ccflags=$(OPTIMIZE:s/"/\"/) $(DEFINES) $(OBJECT)"      \
                "cf_email=$(EMAIL)"                     \
                "d_crypt=$(D_CRYPT)"                    \
                "d_mymalloc=$(PERL_MALLOC)"             \
                "libs=$(LIBFILES:f)"                    \
-               "incpath=$(CCINCDIR)"                   \
+               "incpath=$(CCINCDIR:s/"/\"/)"           \
                "libperl=$(PERLIMPLIB:f)"               \
-               "libpth=$(strip $(CCLIBDIR) $(EXTRALIBDIRS) $(LIBFILES:d))" \
+               "libpth=$(CCLIBDIR:s/"/\"/);$(EXTRALIBDIRS:s/"/\"/)"    \
                "libc=$(LIBC)"                          \
                "make=dmake"                            \
                "_o=$(o)" "obj_ext=$(o)"                \
@@ -722,8 +719,8 @@ CFG_VARS    =                                       \
                "nonxs_ext=$(NONXS_EXT)"                \
                "usethreads=$(USE_THREADS)"             \
                "usemultiplicity=$(USE_MULTI)"          \
-               "LINK_FLAGS=$(LINK_FLAGS)"              \
-               "optimize=$(OPTIMIZE)"
+               "LINK_FLAGS=$(LINK_FLAGS:s/"/\"/)"              \
+               "optimize=$(OPTIMIZE:s/"/\"/)"
 
 #
 # Top targets
@@ -738,9 +735,9 @@ $(DYNALOADER)$(o) : $(DYNALOADER).c $(CORE_H) $(EXTDIR)\DynaLoader\dlutils.c
 
 $(GLOBEXE) : perlglob$(o)
 .IF "$(CCTYPE)" == "BORLAND"
-       $(CC) -c -w -v -tWM -I$(CCINCDIR) perlglob.c
+       $(CC) -c -w -v -tWM -I"$(CCINCDIR)" perlglob.c
        $(LINK32) -Tpe -ap $(LINK_FLAGS) c0x32$(o) perlglob$(o) \
-           $(CCLIBDIR)\32BIT\wildargs$(o),$@,,import32.lib cw32mt.lib,
+           "$(CCLIBDIR)\32BIT\wildargs$(o)",$@,,import32.lib cw32mt.lib,
 .ELIF "$(CCTYPE)" == "GCC"
        $(LINK32) $(LINK_FLAGS) -o $@ perlglob$(o) $(LIBFILES)
 .ELSE
@@ -768,7 +765,7 @@ regen_config_h:
        -cd .. && del /f perl.exe
        cd .. && perl configpm
        -del /f $(CFGH_TMPL)
-       -mkdir ..\lib\CORE
+       -mkdir $(COREDIR)
        -perl -I..\lib config_h.PL "INST_VER=$(INST_VER)"
        rename config.h $(CFGH_TMPL)
 
index 3947f9e..8cf521d 100644 (file)
@@ -1,9 +1,8 @@
-
-#ifdef PERL_OBJECT
-#define USE_SOCKETS_AS_HANDLES
 #include "EXTERN.h"
 #include "perl.h"
 
+#ifdef PERL_OBJECT
+
 #define NO_XSLOCKS
 #include "XSUB.H"
 #include "win32iop.h"
@@ -37,8 +36,17 @@ main(int argc, char **argv, char **env)
 {
     CPerlHost host;
     int exitstatus = 1;
+#ifndef __BORLANDC__
+    /* XXX this _may_ be a problem on some compilers (e.g. Borland) that
+     * want to free() argv after main() returns.  As luck would have it,
+     * Borland's CRT does the right thing to argv[0] already. */
+    char szModuleName[MAX_PATH];
+
+    GetModuleFileName(NULL, szModuleName, sizeof(szModuleName));
+    argv[0] = szModuleName;
+#endif
 
-    if(!host.PerlCreate())
+    if (!host.PerlCreate())
        exit(exitstatus);
 
     exitstatus = host.PerlParse(xs_init, argc, argv, NULL);
@@ -74,6 +82,14 @@ __declspec(dllimport) int RunPerl(int argc, char **argv, char **env, void *ios);
 int
 main(int argc, char **argv, char **env)
 {
+#ifndef __BORLANDC__
+    /* XXX this _may_ be a problem on some compilers (e.g. Borland) that
+     * want to free() argv after main() returns.  As luck would have it,
+     * Borland's CRT does the right thing to argv[0] already. */
+    char szModuleName[MAX_PATH];
+    GetModuleFileName(NULL, szModuleName, sizeof(szModuleName));
+    argv[0] = szModuleName;
+#endif
     return RunPerl(argc, argv, env, (void*)0);
 }
 
index e9619d6..2c74fc2 100644 (file)
@@ -191,9 +191,9 @@ get_emd_part(char *prev_path, char *trailing_path, ...)
 
     sprintf(base, "%5.3f", (double) 5 + ((double) PATCHLEVEL / (double) 1000));
 
-    GetModuleFileName((w32_perldll_handle == INVALID_HANDLE_VALUE)
-                     ? GetModuleHandle(NULL)
-                     : w32_perldll_handle, mod_name, sizeof(mod_name));
+    GetModuleFileName((HMODULE)((w32_perldll_handle == INVALID_HANDLE_VALUE)
+                               ? GetModuleHandle(NULL) : w32_perldll_handle),
+                     mod_name, sizeof(mod_name));
     ptr = strrchr(mod_name, '\\');
     while (ptr && strip) {
         /* look for directories to skip back */
@@ -201,8 +201,11 @@ get_emd_part(char *prev_path, char *trailing_path, ...)
        *ptr = '\0';
        ptr = strrchr(mod_name, '\\');
        if (!ptr || stricmp(ptr+1, strip) != 0) {
-           *optr = '\\';
-           ptr = optr;
+           if(!(*strip == '5' && *(ptr+1) == '5' && strncmp(strip, base, 5) == 0
+                   && strncmp(ptr+1, base, 5) == 0)) {
+               *optr = '\\';
+               ptr = optr;
+           }
        }
        strip = va_arg(ap, char *);
     }
@@ -494,7 +497,7 @@ do_aspawn(void *vreally, void **vmark, void **vsp)
                           (const char*)(really ? SvPV(really,n_a) : argv[0]),
                           (const char* const*)argv);
 
-    if (status < 0 && errno == ENOEXEC) {
+    if (status < 0 && (errno == ENOEXEC || errno == ENOENT)) {
        /* possible shell-builtin, invoke with shell */
        int sh_items;
        sh_items = w32_perlshell_items;
@@ -1773,51 +1776,102 @@ win32_pclose(FILE *pf)
 DllExport int
 win32_rename(const char *oname, const char *newname)
 {
-    char szNewWorkName[MAX_PATH+1];
-    WIN32_FIND_DATA fdOldFile, fdNewFile;
-    HANDLE handle;
-    char *ptr;
-
-    if ((strchr(oname, '\\') || strchr(oname, '/'))
-       && strchr(newname, '\\') == NULL
-       && strchr(newname, '/') == NULL)
-    {
-       strcpy(szNewWorkName, oname);
-       if ((ptr = strrchr(szNewWorkName, '\\')) == NULL)
-           ptr = strrchr(szNewWorkName, '/');
-       strcpy(++ptr, newname);
+    /* XXX despite what the documentation says about MoveFileEx(),
+     * it doesn't work under Windows95!
+     */
+    if (IsWinNT()) {
+       if (!MoveFileEx(oname,newname,
+                       MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING)) {
+           DWORD err = GetLastError();
+           switch (err) {
+           case ERROR_BAD_NET_NAME:
+           case ERROR_BAD_NETPATH:
+           case ERROR_BAD_PATHNAME:
+           case ERROR_FILE_NOT_FOUND:
+           case ERROR_FILENAME_EXCED_RANGE:
+           case ERROR_INVALID_DRIVE:
+           case ERROR_NO_MORE_FILES:
+           case ERROR_PATH_NOT_FOUND:
+               errno = ENOENT;
+               break;
+           default:
+               errno = EACCES;
+               break;
+           }
+           return -1;
+       }
+       return 0;
     }
-    else
-       strcpy(szNewWorkName, newname);
-
-    if (stricmp(oname, szNewWorkName) != 0) {
-       // check that we're not being fooled by relative paths
-       // and only delete the new file
-       //  1) if it exists
-       //  2) it is not the same file as the old file
-       //  3) old file exist
-       // GetFullPathName does not return the long file name on some systems
-       handle = FindFirstFile(oname, &fdOldFile);
-       if (handle != INVALID_HANDLE_VALUE) {
-           FindClose(handle);
-    
-           handle = FindFirstFile(szNewWorkName, &fdNewFile);
-    
-           if (handle != INVALID_HANDLE_VALUE)
-               FindClose(handle);
+    else {
+       int retval = 0;
+       char tmpname[MAX_PATH+1];
+       char dname[MAX_PATH+1];
+       char *endname = Nullch;
+       STRLEN tmplen = 0;
+       DWORD from_attr, to_attr;
+
+       /* if oname doesn't exist, do nothing */
+       from_attr = GetFileAttributes(oname);
+       if (from_attr == 0xFFFFFFFF) {
+           errno = ENOENT;
+           return -1;
+       }
+
+       /* if newname exists, rename it to a temporary name so that we
+        * don't delete it in case oname happens to be the same file
+        * (but perhaps accessed via a different path)
+        */
+       to_attr = GetFileAttributes(newname);
+       if (to_attr != 0xFFFFFFFF) {
+           /* if newname is a directory, we fail
+            * XXX could overcome this with yet more convoluted logic */
+           if (to_attr & FILE_ATTRIBUTE_DIRECTORY) {
+               errno = EACCES;
+               return -1;
+           }
+           tmplen = strlen(newname);
+           strcpy(tmpname,newname);
+           endname = tmpname+tmplen;
+           for (; endname > tmpname ; --endname) {
+               if (*endname == '/' || *endname == '\\') {
+                   *endname = '\0';
+                   break;
+               }
+           }
+           if (endname > tmpname)
+               endname = strcpy(dname,tmpname);
            else
-               fdNewFile.cFileName[0] = '\0';
-
-           if (strcmp(fdOldFile.cAlternateFileName,
-                      fdNewFile.cAlternateFileName) != 0
-               && strcmp(fdOldFile.cFileName, fdNewFile.cFileName) != 0)
-           {
-               // file exists and not same file
-               DeleteFile(szNewWorkName);
+               endname = ".";
+
+           /* get a temporary filename in same directory
+            * XXX is this really the best we can do? */
+           if (!GetTempFileName((LPCTSTR)endname, "plr", 0, tmpname)) {
+               errno = ENOENT;
+               return -1;
+           }
+           DeleteFile(tmpname);
+
+           retval = rename(newname, tmpname);
+           if (retval != 0) {
+               errno = EACCES;
+               return retval;
            }
        }
+
+       /* rename oname to newname */
+       retval = rename(oname, newname);
+
+       /* if we created a temporary file before ... */
+       if (endname != Nullch) {
+           /* ...and rename succeeded, delete temporary file/directory */
+           if (retval == 0)
+               DeleteFile(tmpname);
+           /* else restore it to what it was */
+           else
+               (void)rename(tmpname, newname);
+       }
+       return retval;
     }
-    return rename(oname, newname);
 }
 
 DllExport int
@@ -2346,7 +2400,7 @@ XS(w32_Spawn)
     if (items != 3)
        croak("usage: Win32::Spawn($cmdName, $args, $PID)");
 
-    cmd = SvPV(ST(0), n_a);
+    cmd = SvPV(ST(0),n_a);
     args = SvPV(ST(1), n_a);
 
     memset(&stStartInfo, 0, sizeof(stStartInfo));   /* Clear the block */