From c005276d70bbb028e0919d6184cb88d51f17ef2d Mon Sep 17 00:00:00 2001 From: rschupp Date: Thu, 14 Mar 2024 15:13:20 +0100 Subject: [PATCH] investigate #86 - myldr/mktmpdir.c: par_setup_libpath() sets the value of environment variable $Config{ldlibpthname} for the (inner) packed executable, but some perl distributions (e.g. Strawberry) do not specify $Config{ldlibpthname}. Hardwire "PATH" for MSWin32 and otherwise complain if this Config is undefined. - add t/85-ldlibpthname.t: check that the value of the environment variable for searching for DLLs, $ENV{$Config{ldlibpthname}}, starts with ithe cache directory, $ENV{PAR_TEMP} --- MANIFEST | 1 + myldr/Makefile.PL | 7 ++++++- myldr/boot.c | 2 +- myldr/internals.c | 2 +- myldr/mktmpdir.c | 22 +++++++++++----------- myldr/mktmpdir.h | 3 +++ t/85-ldlibpthname.t | 31 +++++++++++++++++++++++++++++++ 7 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 t/85-ldlibpthname.t diff --git a/MANIFEST b/MANIFEST index 7035a6f..739a796 100644 --- a/MANIFEST +++ b/MANIFEST @@ -69,6 +69,7 @@ t/30-current_exec.t t/40-packer_cd_option.t t/80-doublecolon.t t/85-crt-glob.t +t/85-ldlibpthname.t t/85-myfile.t t/86-xs-exe.t t/86-xs-par.t diff --git a/myldr/Makefile.PL b/myldr/Makefile.PL index c2d4559..77804b3 100644 --- a/myldr/Makefile.PL +++ b/myldr/Makefile.PL @@ -230,10 +230,15 @@ WriteMakefile( sub MY::postamble { + # Strawberry perl doesn't set $Config{ldlibpthname} + my $ldlibpthname = $^O eq 'MSWin32' ? "PATH" : ($Config{ldlibpthname} || "NA"); + warn "No \$Config{ldlibpthname} specified for your OS ($^O)". + "- PAR::Packer functionality may be limited" if $ldlibpthname eq "NA"; + my $make_frag = <<"EOT"; LD=$ld CC=$cc -CFLAGS=$cflags -DLDLIBPTHNAME=\\"$Config{ldlibpthname}\\" -DPARL_EXE=\\"parl$exe\\" -DPAR_PACKER_VERSION=\\"\$(VERSION)\\" +CFLAGS=$cflags -DLDLIBPTHNAME=$ldlibpthname -DPARL_EXE=parl$exe -DPAR_PACKER_VERSION=\$(VERSION) OPTIMIZE=$optimize LDFLAGS=$Config{ldflags} PERL_LDFLAGS=$ldflags diff --git a/myldr/boot.c b/myldr/boot.c index f5ccfad..96d5a19 100644 --- a/myldr/boot.c +++ b/myldr/boot.c @@ -253,7 +253,7 @@ void spawn_perl(const char *argv0, const char *my_perl, const char *stmpdir) } #endif -char pp_version_info[] = "@(#) Packed by PAR::Packer " PAR_PACKER_VERSION; +char pp_version_info[] = "@(#) Packed by PAR::Packer " stringify(PAR_PACKER_VERSION); /* the contents of this string (in the executable myldr/boot) * will be patched by script/par.pl if option "--clean" is used with pp diff --git a/myldr/internals.c b/myldr/internals.c index 9a8d297..e60a09c 100644 --- a/myldr/internals.c +++ b/myldr/internals.c @@ -51,7 +51,7 @@ XS(XS_Internals_PAR_BOOT) { * this scalar so that a packed script may refer to the version * of PAR::Packer it was built with. */ - sv_setpv(get_sv("PAR::Packer::VERSION", GV_ADD), PAR_PACKER_VERSION); + sv_setpv(get_sv("PAR::Packer::VERSION", GV_ADD), stringify(PAR_PACKER_VERSION)); TAINT_NOT; diff --git a/myldr/mktmpdir.c b/myldr/mktmpdir.c index 2c07fbd..0af929a 100644 --- a/myldr/mktmpdir.c +++ b/myldr/mktmpdir.c @@ -63,21 +63,20 @@ static int isSafeDir(const char* val) void par_setup_libpath( const char * stmpdir ) { - const char *val = NULL; - char *ld_path = LDLIBPTHNAME; - char *ld_path_env = NULL; + const char *ldlibpthname = stringify(LDLIBPTHNAME); + const char *val; - if ( (val = par_getenv(ld_path)) == NULL || strlen(val) == 0 ) { - par_setenv(ld_path, stmpdir); + if ( (val = par_getenv(ldlibpthname)) == NULL || strlen(val) == 0 ) { + par_setenv(ldlibpthname, stmpdir); } - else if ( !strstr(val, stmpdir) ) { + else { /* prepend stmpdir to (value of) environment variable */ - ld_path_env = malloc( + char *new_val = malloc( strlen(stmpdir) + strlen(path_sep) + strlen(val) + 1); sprintf( - ld_path_env, "%s%s%s", + new_val, "%s%s%s", stmpdir, path_sep, val); - par_setenv(ld_path, ld_path_env); + par_setenv(ldlibpthname, new_val); } } @@ -252,11 +251,12 @@ char *par_mktmpdir ( char **argv ) { #else #define STREQ(a,b) (strcmp(a,b) == 0) #endif + const char *parl_exe = stringify(PARL_EXE); int prog_len = strlen(progname); - int parl_len = strlen(PARL_EXE); + int parl_len = strlen(parl_exe); if (prog_len >= parl_len - && STREQ(progname + prog_len - parl_len, PARL_EXE) + && STREQ(progname + prog_len - parl_len, parl_exe) && (prog_len == parl_len || progname[prog_len - parl_len - 1] == dir_sep[0]) && argv[1] && strlen(argv[1]) >= 4 diff --git a/myldr/mktmpdir.h b/myldr/mktmpdir.h index e148ccc..4475aad 100644 --- a/myldr/mktmpdir.h +++ b/myldr/mktmpdir.h @@ -67,6 +67,9 @@ #define par_lstat stat #endif +#define _stringify(s) #s +#define stringify(s) _stringify(s) + #if defined(WIN32) || defined(OS2) static const char *dir_sep = "\\"; static const char *path_sep = ";"; diff --git a/t/85-ldlibpthname.t b/t/85-ldlibpthname.t new file mode 100644 index 0000000..782c5fb --- /dev/null +++ b/t/85-ldlibpthname.t @@ -0,0 +1,31 @@ +#!/usr/bin/perl -w + +use strict; +use Config; +use Data::Dumper; + +use Test::More; +require "./t/utils.pl"; + +my $ldlibpthname = $^O eq 'MSWin32' ? "PATH" : $Config{ldlibpthname}; +plan skip_all => "No \$Config{ldlibpthname} specified" unless $ldlibpthname; + +plan tests => 3; + +my $exe = pp_ok(-e => <<"..."); + use Data::Dumper; + my \$data = { + par_temp => \$ENV{PAR_TEMP}, + ldlibpth => \$ENV{$ldlibpthname}, + }; + print Data::Dumper->new([\$data], ['data'])->Indent(1)->Useqq(1)->Dump(); +... + +my ($out) = run_ok($exe); +our $data; +eval $out; +ok($data->{ldlibpth} =~ /^\Q$data->{par_temp}\E($|\Q$Config{path_sep}\E)/, + "PAR_TEMP is first item in $ldlibpthname as seen by packed executable") + or diag($out); + +