Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Detecting lchown and falling back to chown

by andy314 (Initiate)
on Feb 01, 2008 at 16:11 UTC ( #665593=perlquestion: print w/replies, xml ) Need Help??
andy314 has asked for the wisdom of the Perl Monks concerning the following question:

I need to be able to use change the ownership of symlinks in Perl, where the function "lchown" comes in handy. However my script is supposed to run an work (at least for non symlinks) on older Perl versions or builds of perl which do not support lchown.
My best working attempt so far has been:
eval('use POSIX qw(lchown);'); if (defined &lchown) { eval('sub best_chown($$$) { lchown(@_); }'); } else { eval('sub best_chown($$$) { chown(@_); }'); } # ... use best_chown from now on ....

However this seemed a little ugly (too many evals and unnatural). Is there a better way?

Replies are listed 'Best First'.
Re: Detecting lchown and falling back to chown
by Fletch (Chancellor) on Feb 01, 2008 at 16:20 UTC

    Probably could get away with just one eval (the one checking for lchown (untested):

    eval( 'use POSIX qw( lchown )' ); if( defined &lchown ) { *best_chown = sub ($$$) { lchown( @_ ) }; } else { *best_chown = sub ($$$) { chown( @_ ) }; }

    Update: And I don't think your prototype for chown looks right; CORE::chown is (@) . . .

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

      I am new enough to perl to not even know how to find the right prototype ... I guessed that it takes 3 parameters, so $$$ made sense. I guess RTFM would help .. Thank you for info.

      Any speed/functionality differences between your code and the eval version? Or just code cleanliness?

        Primarily cleanliness (don't do more string evals than you absolutely have to); and given that you'll probably only run this chunk of code once per invocation anyway it's premature optimization to really worry whether 3 string evals is killing your performance (hint: it's probably not going to be even measurable).

        The cake is a lie.
        The cake is a lie.
        The cake is a lie.

Re: Detecting lchown and falling back to chown
by bluto (Curate) on Feb 01, 2008 at 16:40 UTC
    FWIW, if you have lchown available you'll chown the symlink but not the target. If you don't, you'll chown the target, but not the symlink.

    That seems kind of strange to me, but YMMV. I could see that if lchown was defined you'd want to change the symlink, but how you handle the target seems like it should always be the same (i.e. always chown the target, or always avoid it).

      The program is supposed to recreate permissions of files. It would be run over both symlinks and non-symlinks, and over non-symlinks any function will do, however for symlinks I would need lchown. So I want my script to have full functionality on systems with lchown and at least partial functionality on systems without it.

      However you are right .. I do not really want to even attempt the chown if it is a symlink and I do not have lchown. I guess this would be more appropriate:
      sub best_chown($$$) { chown(@_) unless -l $_[0]; }

      Does this make sense?
        Messed up the parameter order. Should probably be (I never call it for more than 1 file at a time):
        sub best_chown($$$) { chown(@_) unless -l $_[2]; }

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://665593]
Approved by almut
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (9)
As of 2018-05-21 09:29 GMT
Find Nodes?
    Voting Booth?