LD_LIBRARY_PATH trick

mpeters on 2008-05-15T23:05:53

I have this problem a lot. I need to link some Perl module against some C library that is not in the standard system libs. Usually this is because it's a locally installed C thingy (like Swish-e or some payment processor API) that I don't want to pollute the system install. Plus it's nice and easy if the whole application is all bundled together.

The easy way to do this is to set the $ENV{LD_LIBRARY_PATH} from your shell to point to the right place. But this is a bother, and not to mention really hard to do if you need some dynamic bits to figure out what the right path is.

And for security reasons, programs can't set their own local version of LD_LIBRARY_PATH and have it be respected by the system's loader. It has to be done by the calling process (in most cases the shell).

This little trick let's a script set it's own LD_LIBRARY_PATH by relaunching the same program with the same arguments as a new sub-process. Simply put a BEGIN block like this in your script:


BEGIN {
    if(! $ENV{LD_LIBRARY_PATH} ) {
        $ENV{LD_LIBRARY_PATH} = join(':', @some_paths_I_need);
        my $self_cmd = "$^X $0 " . join(' ', @ARGV);
        system($self_cmd);
        exit;
    }
}


system(LIST)

hdp on 2008-05-16T03:10:46

otherwise the shell might hose you.

Re:system(LIST)

Aristotle on 2008-05-16T10:25:29

Might? With that broken join I’d say it’s a certainty that at some point the shell will hose him. Plus it’s less and simpler code:

BEGIN {
    if(! $ENV{LD_LIBRARY_PATH} ) {
        $ENV{LD_LIBRARY_PATH} = join(':', @some_paths_I_need);
        system($^X, $0, @ARGV);
        exit;
    }
}

Also: why system(...); exit and not exec?

Re:system(LIST)

mpeters on 2008-05-16T13:43:27

Just out of curiousity, why is that join broken?

Also, I didn't use exec because I didn't know how the security restrictions around LD_LIBRARY_PATH were enforced. Using exec means the process continues to have the same pid, system gives me an entirely new process. I wasn't sure if having the same pid would allow me to do what I wanted to do.

But thanks for the clarification. It works correctly (at least on the Linux machine I tried it on).

Re:system(LIST)

Aristotle on 2008-05-16T14:22:45

why is that join broken?

Because you’re not shell-quoting anything. If there happens to be any space in there, the new copy of the script will have different @ARGV contents. That’s before we even get to other shell meta-characters.

Re:system(LIST)

mpeters on 2008-05-16T13:39:05

You're right about using the list. I was actually debugging it to make sure the command was what I wanted it to be so I was combining it into a string so I could print it to the screen before executing. I just forgot to change it after the fact.