[ic] How can I use POSIX functions in [perl] tags?

Mike Heins interchange-users@icdevgroup.org
Fri Nov 22 09:14:00 2002


Quoting Jonathan Clark (jonc@webmaint.com):
> > 	I need to use the ceil() function from POSIX package, eg:
> >
> > [perl]
> > 	use POSIX;
> > 	my $realvalue = ....
> > 	return ceil($realvalue);
> > [/perl]
> >
> > but Safe.pm won't let me.
> > I've tried setting SafeUntrap, but that doesn't work either, eg:
> >
> > SafeUntrap ceil;
> > or
> > SafeUntrap POSIX::ceil;
> > -- i'm new to perl - not sure how to specify function namespace, is this
> > correct?
> 
> Why not write your perl into a global usertag?
> 

This is true, you can do:

UserTag ceil Order arg
UserTag ceil Routine  sub { return POSIX::ceil(@_) }

(YOu can do that becasue we use POSIX as a part of IC and it doesn't
need to be "use"d.)

Then you just do $Tag->ceil() or [ceil [loop-code]].

It might be nice on occasion to do something like that, but the
problem with sharing routines with Safe is that they must do
things which don't violate Safe either. For instance, we could
provide a directive called SafeShare:

    SafeShare  POSIX::ceil

Which would do:

    $safe->share(@{$Vend::Cfg->{SafeShare});

The only problem is that their namespaces would probably still
be outside what is allowed with Safe and it wouldn't work except
in very simple cases.

For something like POSIX, a simple library routine would be
best:

UserTag  posix  Order  function arg
UserTag  posix  addAttr 
UserTag  posix  Routine <<EOR
sub {
    my ($func, $arg) = @_;
    no strict 'refs';
    my $sub = \&{"POSIX::$func"};

    if(ref $sub ne 'CODE') {
        logError("posix: %s not a valid routine", $func);
        return undef;
    }

    if(     ref($arg) eq 'HASH'  ) {
        return $sub->(%$arg);
    }
    elsif(  ref($arg) eq 'ARRAY'  ) {
        return $sub->(@$arg);
    }
    else {
        return $sub->($arg);
    }
}
EOR

Now you could just call anywhare:

    $Tag->posix('ceil', $number);
    $Tag->posix('chmod', [ 0644, 'file1', 'file2' ]);

or 
    
    [posix func=ceil arg="[scratch number]"]
    [posix func=chmod arg.0=0644 arg.1=file1 arg.2=file2]


This would be a bit dangerous, though, as POSIX has many routines
which allow you to read and write files. You might want to qualify
the routines allowed:

    my %allowed_funcs = qw/
        ceil         1
        floor        1
        getpwnam     1
        fopen        0
    /;
        
    unless ($allowed{$func}) {
        logError("ALERT: attempt to use POSIX function $func");
        return undef;
    }

-- 
Mike Heins
Perusion -- Expert Interchange Consulting    http://www.perusion.com/
phone +1.513.523.7621      <mike@perusion.com>

People who want to share their religious views with you
almost never want you to share yours with them. -- Dave Barry