This is a live mirror of the Perl 5 development currently hosted at
move Win32's $^X code to where all other OSes' $^X code lives origin/tonyc/126753-dollar-caret-X
authorDaniel Dragan <>
Sat, 28 Nov 2015 05:29:17 +0000 (00:29 -0500)
committerTony Cook <>
Tue, 1 Dec 2015 22:17:09 +0000 (09:17 +1100)
Back when the code in perllib.c was first added in 1999, in
commit 80252599d4 the large define tree function that today in 2015 is
Perl_set_caret_X was an unremarkable single statement

Over the years Perl_set_caret_X grew and grew with OS specific code. Move
the Win32 $^X code to match how all the other OSes do it. Fix a problem
where full perl's $^X is always absolute because perl5**.dll uses
GetModuleFileNameW in perllib.c, but miniperl's $^X is always a relative
path because it's coming from libc/command prompt/make tool/
Win32 miniperl's $^X being relative causes inefficiencies in EUMM as a
relative $^X is wrong the moment chdir executes in any perl process.
EUMM contains code to search PATH and some other places to guess/figure out
the absolute patch to the current perl to write the absolute perl path
into the makefile. By making $^X absolute on all Win32 perl build variants,
this find absolute perl path code won't execute in EUMM. It also harmonizes
behavior with other OSes and between Win32 mini and full perl. See details
in RT ticket for this patch.


index fe884e4..67b8418 100644 (file)
--- a/caretx.c
+++ b/caretx.c
@@ -126,6 +126,14 @@ Perl_set_caret_X(pTHX) {
         sv_setpvn(caret_x, buf, len);
+#  elif defined(WIN32)
+    char *ansi;
+    WCHAR widename[MAX_PATH];
+    GetModuleFileNameW(NULL, widename, sizeof(widename)/sizeof(WCHAR));
+    ansi = win32_ansipath(widename);
+    sv_setpv(caret_x, ansi);
+    win32_free(ansi);
+    return;
 #  endif
     /* Fallback to this:  */
     sv_setpv(caret_x, PL_origargv[0]);
index 0e44a24..cf7bf56 100644 (file)
@@ -211,14 +211,8 @@ RunPerl(int argc, char **argv, char **env)
     int exitstatus;
     PerlInterpreter *my_perl, *new_perl = NULL;
-    char *arg0 = argv[0];
-    char *ansi = NULL;
     bool use_environ = (env == environ);
-    WCHAR widename[MAX_PATH];
-    GetModuleFileNameW(NULL, widename, sizeof(widename)/sizeof(WCHAR));
-    argv[0] = ansi = win32_ansipath(widename);
 #define PERLVAR(prefix,var,type) /**/
 #define PERLVARA(prefix,var,type) /**/
@@ -269,11 +263,6 @@ RunPerl(int argc, char **argv, char **env)
-    /* Some RTLs may want to free argv[] after main() returns. */
-    argv[0] = arg0;
-    if (ansi)
-        win32_free(ansi);
     return (exitstatus);