in reply to Re^2: Is require still required?
in thread Is require still required?
The PERL5LIB environment variable is the only one that is set in the empty environment that launches the perl binary (to find the Sybase::Simple module). And indeed, in an empty environment, the XS .so blob that implements the actual database access layer in Sybase::CTlib (on which Sybase::Simple depends) refers to libraries that can't be resolved (and this is how these Sybase libraries work by design):$ env -i PERL5LIB=.local/lib/perl5 perl -MSybase::Simple Can't load '.local/lib/perl5/x86_64-linux-thread-multi/auto/Sybase/CTl +ib/CTlib.so' for module Sybase::CTlib: libsybct_r64.so: cannot open s +hared object file: No such file or directory at /usr/lib64/perl5/Dyna +Loader.pm line 193. at .local/lib/perl5/Sybase/Simple.pm line 19. Compilation failed in require at .local/lib/perl5/Sybase/Simple.pm lin +e 19. BEGIN failed--compilation aborted at .local/lib/perl5/Sybase/Simple.pm + line 19. Compilation failed in require. BEGIN failed--compilation aborted. $
The code I arrived at from your linked comment to 'steal' the environment from a subshell (with the added requirement of merging with any existing %ENV values), is:$ env -i ldd .local/lib/perl5/x86_64-linux-thread-multi/auto/Sybase/CT +lib/CTlib.so linux-vdso.so.1 (0x00007ffcebdce000) libsybct_r64.so => not found libsybcs_r64.so => not found libsybblk_r64.so => not found libperl.so.5.32 => /lib64/libperl.so.5.32 (0x00007f4970c00000) libc.so.6 => /lib64/libc.so.6 (0x00007f4970800000) libm.so.6 => /lib64/libm.so.6 (0x00007f4970b25000) libcrypt.so.2 => /lib64/libcrypt.so.2 (0x00007f4970fc3000) /lib64/ld-linux-x86-64.so.2 (0x00007f4971032000) $
But this still fails (even though the environment is modified correctly (the first line is the content of $ENV{LD_LIBRARY_PATH}):#!/usr/bin/perl BEGIN { my $shellcode = <<__KOEKOEK__; . sybsdk/SYBASE.sh perl -MData::Dumper -e 'print Dumper [\%ENV]' __KOEKOEK__ %ENV = (%ENV => @{eval qx{/bin/sh -c "$shellcode"}}); }; print $ENV{LD_LIBRARY_PATH}; require Sybase::Simple;
If we modify the script to just dump the %ENV hash, we see that all environment variables were indeed set correctly in the parent process from our detour in the qx{} subshell:$ env -i PERL5LIB=.local/lib/perl5 perl ./do_shell_source.pl ~/sybsdk/DataAccess64/ODBC/lib:~/sybsdk/DataAccess/ODBC/lib:~/sybsdk/O +CS-20_0/lib:~/sybsdk/OCS-20_0/lib3p64:~/sybsdk/OCS-20_0/lib3p: Can't load '.local/lib/perl5/x86_64-linux-thread-multi/auto/Sybase/CTl +ib/CTlib.so' for module Sybase::CTlib: libsybct_r64.so: cannot open s +hared object file: No such file or directory at /usr/lib64/perl5/Dyna +Loader.pm line 193. at .local/lib/perl5/Sybase/Simple.pm line 19. Compilation failed in require at .local/lib/perl5/Sybase/Simple.pm lin +e 19. BEGIN failed--compilation aborted at .local/lib/perl5/Sybase/Simple.pm + line 19. Compilation failed in require at ./do_shell_source.pl line 14. $
#!/usr/bin/perl BEGIN { my $shellcode = <<__KOEKOEK__; . sybsdk/SYBASE.sh perl -MData::Dumper -e 'print Dumper [\%ENV]' __KOEKOEK__ %ENV = (%ENV => @{eval qx{/bin/sh -c "$shellcode"}}); }; use DDP; p %ENV;
And this corresponds to what's inside the (Sybase provided) shell script file for their proprietary libraries that is meant to be sourced in the shell's environment:$ env -i PERL5LIB=.local/lib/perl5 perl ./do_shell_source.pl { _ "/usr/bin/perl", INCLUDE "~/sybsdk/OCS-20_0/include:", LD_LIBRARY_PATH "~/sybsdk/DataAccess64/ODBC/lib:~/sybsdk/DataAcc +ess/ODBC/lib:~/sybsdk/OCS-20_0/lib:~/sybsdk/OCS-20_0/lib3p64:~/sybsdk +/OCS-20_0/lib3p:", LIB "~/sybsdk/OCS-20_0/lib:", PATH "~/sybsdk/tools/bin:~/sybsdk/OCS-20_0/bin:/usr/l +ocal/bin:/usr/bin", PERL5LIB ".local/lib/perl5", PWD "/tmp", SAP_JRE8 "~/sybsdk/shared/SAPJRE-8_1_062_64BIT", SAP_JRE8_64 "~/sybsdk/shared/SAPJRE-8_1_062_64BIT", SHLVL 0, SYBASE "~/sybsdk", SYBASE_OCS "OCS-20_0", SYBROOT "~/sybsdk" } $
So, coming back around again: a re-exec is still required in this case (due to the semantics and interaction of LD_LIBRARY_PATH and the system's dynamic linker). Moreover, because a Perl script file is first compiled before it is executed, any statements that fire at compile time (like use) need to be deferred to runtime (using require) when LD_LIBRARY_PATH potentially needs adjustments. Otherwise, the use Sybase::Simple; statements gets triggered before the re-exec through a shell that first sets LD_LIBRARY_PATH, causing compilation to abort due to DynaLoader getting an error from the OS's ld.so when trying to resolve libraries a module's XS .so file is linked to.$ cat sybsdk/SYBASE.sh # # SAP Product Environment variables # SAP_JRE8="~/sybsdk/shared/SAPJRE-8_1_062_64BIT" export SAP_JRE8 SAP_JRE8_64="~/sybsdk/shared/SAPJRE-8_1_062_64BIT" export SAP_JRE8_64 SYBASE_OCS="OCS-20_0" export SYBASE_OCS INCLUDE="~/sybsdk/OCS-20_0/include":$INCLUDE export INCLUDE LIB="~/sybsdk/OCS-20_0/lib":$LIB export LIB PATH="~/sybsdk/OCS-20_0/bin":$PATH export PATH # # Replace lib, lib3p, and lib3p64 with devlib, devlib3p, and devlib3p6 +4 when debugging # LD_LIBRARY_PATH="~/sybsdk/OCS-20_0/lib:~/sybsdk/OCS-20_0/lib3p64:~/syb +sdk/OCS-20_0/lib3p":$LD_LIBRARY_PATH export LD_LIBRARY_PATH SYBASE="~/sybsdk" export SYBASE LD_LIBRARY_PATH="~/sybsdk/DataAccess/ODBC/lib":$LD_LIBRARY_PATH export LD_LIBRARY_PATH LD_LIBRARY_PATH="~/sybsdk/DataAccess64/ODBC/lib":$LD_LIBRARY_PATH export LD_LIBRARY_PATH SYBROOT="~/sybsdk" export SYBROOT PATH="~/sybsdk/tools/bin":$PATH export PATH $
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: Is require still required?
by NERDVANA (Priest) on Feb 12, 2024 at 19:50 UTC | |
|
Re^4: Is require still required?
by mpeppler (Vicar) on Feb 12, 2024 at 08:09 UTC | |
|
Re^4: Is require still required?
by LanX (Saint) on Feb 06, 2024 at 23:18 UTC | |
|
Re^4: Is require still required?
by bliako (Abbot) on Feb 12, 2024 at 12:19 UTC | |
by LanX (Saint) on Feb 12, 2024 at 12:50 UTC |