diff options
author | Gurusamy Sarathy <gsar@cpan.org> | 1999-02-01 06:27:35 +0000 |
---|---|---|
committer | Gurusamy Sarathy <gsar@cpan.org> | 1999-02-01 06:27:35 +0000 |
commit | 80252599d4b7fb26eec4e3a0f451b4387c5dcc19 (patch) | |
tree | af33a52bae818e292c641108bbbc11b8b1b4f8c2 | |
parent | 34f744a4168d1ae5fad32a9241fb076a6b2c3fa8 (diff) | |
download | perl-80252599d4b7fb26eec4e3a0f451b4387c5dcc19.tar.gz |
various win32-ish changes merged from maint-5.005
p4raw-id: //depot/perl@2746
-rw-r--r-- | README.win32 | 20 | ||||
-rw-r--r-- | embedvar.h | 14 | ||||
-rw-r--r-- | globvar.sym | 1 | ||||
-rw-r--r-- | lib/ExtUtils/MM_Unix.pm | 5 | ||||
-rw-r--r-- | objXSUB.h | 14 | ||||
-rw-r--r-- | op.c | 4 | ||||
-rw-r--r-- | perl.h | 6 | ||||
-rw-r--r-- | perlvars.h | 11 | ||||
-rw-r--r-- | pp.c | 72 | ||||
-rw-r--r-- | sv.c | 18 | ||||
-rwxr-xr-x | t/io/fs.t | 28 | ||||
-rw-r--r-- | toke.c | 15 | ||||
-rw-r--r-- | win32/Makefile | 27 | ||||
-rw-r--r-- | win32/config.bc | 2 | ||||
-rw-r--r-- | win32/config.vc | 2 | ||||
-rw-r--r-- | win32/config_sh.PL | 15 | ||||
-rw-r--r-- | win32/makefile.mk | 33 | ||||
-rw-r--r-- | win32/runperl.c | 24 | ||||
-rw-r--r-- | win32/win32.c | 148 |
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 ""; } @@ -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 @@ -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; @@ -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) + @@ -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); @@ -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 /* @@ -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"; } @@ -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 */ |