summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>1999-02-01 06:27:35 +0000
committerGurusamy Sarathy <gsar@cpan.org>1999-02-01 06:27:35 +0000
commit80252599d4b7fb26eec4e3a0f451b4387c5dcc19 (patch)
treeaf33a52bae818e292c641108bbbc11b8b1b4f8c2
parent34f744a4168d1ae5fad32a9241fb076a6b2c3fa8 (diff)
downloadperl-80252599d4b7fb26eec4e3a0f451b4387c5dcc19.tar.gz
various win32-ish changes merged from maint-5.005
p4raw-id: //depot/perl@2746
-rw-r--r--README.win3220
-rw-r--r--embedvar.h14
-rw-r--r--globvar.sym1
-rw-r--r--lib/ExtUtils/MM_Unix.pm5
-rw-r--r--objXSUB.h14
-rw-r--r--op.c4
-rw-r--r--perl.h6
-rw-r--r--perlvars.h11
-rw-r--r--pp.c72
-rw-r--r--sv.c18
-rwxr-xr-xt/io/fs.t28
-rw-r--r--toke.c15
-rw-r--r--win32/Makefile27
-rw-r--r--win32/config.bc2
-rw-r--r--win32/config.vc2
-rw-r--r--win32/config_sh.PL15
-rw-r--r--win32/makefile.mk33
-rw-r--r--win32/runperl.c24
-rw-r--r--win32/win32.c148
19 files changed, 290 insertions, 169 deletions
diff --git a/README.win32 b/README.win32
index b9f6b15d09..e696ab3e0e 100644
--- a/README.win32
+++ b/README.win32
@@ -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
diff --git a/embedvar.h b/embedvar.h
index 2d25d41947..8c7c2a7807 100644
--- a/embedvar.h
+++ b/embedvar.h
@@ -667,6 +667,7 @@
#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)
@@ -683,6 +684,8 @@
#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)
@@ -691,7 +694,9 @@
#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)
@@ -757,6 +762,7 @@
#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)
@@ -781,6 +787,7 @@
#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)
@@ -799,6 +806,7 @@
#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
@@ -815,6 +823,8 @@
#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
@@ -823,7 +833,9 @@
#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
@@ -889,6 +901,7 @@
#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
@@ -913,6 +926,7 @@
#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
diff --git a/globvar.sym b/globvar.sym
index 0bf1fee262..3cb8ccc3e4 100644
--- a/globvar.sym
+++ b/globvar.sym
@@ -37,6 +37,7 @@ psig_ptr
regkind
simple
utf8skip
+uuemap
varies
vtbl_sv
vtbl_env
diff --git a/lib/ExtUtils/MM_Unix.pm b/lib/ExtUtils/MM_Unix.pm
index a5a4459207..60f03d8ddd 100644
--- a/lib/ExtUtils/MM_Unix.pm
+++ b/lib/ExtUtils/MM_Unix.pm
@@ -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 "";
}
diff --git a/objXSUB.h b/objXSUB.h
index 97845f84fa..9c8460fc4e 100644
--- 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
@@ -170,6 +172,10 @@
#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
@@ -206,6 +212,8 @@
#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
@@ -220,6 +228,8 @@
#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
@@ -638,6 +648,8 @@
#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
@@ -752,6 +764,8 @@
#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 035247ba07..94fbc159ba 100644
--- 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 c7e328a2a3..c493bd0d39 100644
--- 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 };
diff --git a/perlvars.h b/perlvars.h
index 3860345409..29093870cb 100644
--- a/perlvars.h
+++ b/perlvars.h
@@ -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 b378d7d21c..cd8c07826e 100644
--- 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 6d900cee0e..2dea64f701 100644
--- 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
/*
diff --git a/t/io/fs.t b/t/io/fs.t
index c15f7728f5..f09d66c39e 100755
--- 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 66d9947e64..f697741714 100644
--- 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) {
diff --git a/win32/Makefile b/win32/Makefile
index bee48c0764..3b3c4d4894 100644
--- a/win32/Makefile
+++ b/win32/Makefile
@@ -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:$@ @<<
diff --git a/win32/config.bc b/win32/config.bc
index c460453782..d91fbb977a 100644
--- a/win32/config.bc
+++ b/win32/config.bc
@@ -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~'
diff --git a/win32/config.vc b/win32/config.vc
index 81bd72435e..1a99dd99e4 100644
--- a/win32/config.vc
+++ b/win32/config.vc
@@ -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~'
diff --git a/win32/config_sh.PL b/win32/config_sh.PL
index 59e64f9675..1d4b2fb5c3 100644
--- a/win32/config_sh.PL
+++ b/win32/config_sh.PL
@@ -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;
diff --git a/win32/makefile.mk b/win32/makefile.mk
index 56f17ea77c..dab54d643b 100644
--- a/win32/makefile.mk
+++ b/win32/makefile.mk
@@ -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)
diff --git a/win32/runperl.c b/win32/runperl.c
index 3947f9ef37..8cf521d4ea 100644
--- a/win32/runperl.c
+++ b/win32/runperl.c
@@ -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);
}
diff --git a/win32/win32.c b/win32/win32.c
index e9619d637c..2c74fc25af 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -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 */