chargrill has asked for the wisdom of the Perl Monks concerning the following question:

At work (on windows) I was trying to install File::Flat via cpan, and ran into an issue in the make test where it was expecting certain operations to fail if the installing user wasn't root (or perhaps the other way around, that exact point isn't important at the moment), and was of course making that determination (root v. non-root UID) based on the value of $>. I knew I had administrative rights on the machine, which ought to translate into root-like privileges from the world of unix. My first attempt to update the failing test was something like this: (previously)

$root = $> == 0 ? 1 : 0;
(my change)
$> = eval "use Win32" || ! $@ ? Win32::IsAdminUser() ? 1 : 0 : $>; # or something like that $root = $> == 0 ? 1 : 0;

Which I could never get to work.

On a unix (or unix-like OS such as my Mac), I guess I can understand and accept why I can't change "$>"...

$ perl -e '$> = 0; print "$!\n"; print "$>\n"' Operation not permitted 501 $

But should these same constraints apply to Windows/cygwin? Especially in the following case?

$ perl -e 'use Win32;print Win32::IsAdminUser(),"\n";$>=0; print $!,"\ +n"; print $>,"\n"' 1 Invalid Argument 4638 $

Does $> have a little extra magic that even applies across the great Win32 divide?

I've since thought that perhaps this might work (not trying to set $> at all), and looks like it ought to work:

$root = eval "use Win32" || ! $@ ? Win32::IsAdminUser() ? 1 : 0 : $> = += 0 ? 1 : 0;

At any rate, what's going on with $>? :)



--chargrill
$,=42;for(34,0,-3,9,-11,11,-17,7,-5){$*.=pack'c'=>$,+=$_}for(reverse s +plit//=>$* ){$%++?$ %%2?push@C,$_,$":push@c,$_,$":(push@C,$_,$")&&push@c,$"}$C[$# +C]=$/;($#C >$#c)?($ c=\@C)&&($ C=\@c):($ c=\@c)&&($C=\@C);$%=$|;for(@$c){print$_^ +$$C[$%++]}

Replies are listed 'Best First'.
Re: Does $> have a little extra magic?
by zer (Deacon) on Mar 21, 2006 at 16:42 UTC
    $> and $< are unix UID RID's. Windows doesnt exactly use the same system. I am not too familiar with the WIN32 modules. But let me see if there is a way to get the admin info by other means.
    #!/usr/bin/perl my $pid = open (PS, "net user $ENV{USERNAME}|") || die "Can't Execute" +; while (<PS>){ $root = 1 if (/^Local Group Memberships/ && /\*Administrators/); } print "user is admin" if $root;

    This uses the net command within windows services. Gets your user information. if your local group includes admin then it sets root to 1. Whether this helps you or not it may be useful if you are designing group specific software

      Having since arrived at the office,

      $root = eval "use Win32" || ! $@ ? Win32::IsAdminUser() ? 1 : 0 : $> = += 0 ? 1 : 0;

      ... has all appearances of working as expected. Win32::IsAdminUser() seems to report what I'm interested in. I guess I'm just puzzled by perl's adherance to unix-y properties (with regards to $>) when run on Windows.



      --chargrill
      $,=42;for(34,0,-3,9,-11,11,-17,7,-5){$*.=pack'c'=>$,+=$_}for(reverse s +plit//=>$* ){$%++?$ %%2?push@C,$_,$":push@c,$_,$":(push@C,$_,$")&&push@c,$"}$C[$# +C]=$/;($#C >$#c)?($ c=\@C)&&($ C=\@c):($ c=\@c)&&($C=\@C);$%=$|;for(@$c){print$_^ +$$C[$%++]}

        You have to admit - that's kinda ugly ;-)

        # Try Windows first. my $root = eval { require Win32; Win32::IsAdminUser(); }; # If that didn't work, try Unix. $root = $> == 0 if $@;
        Also has the advantage of avoiding eval STR. String evals are nasty and to be avoided where possible.