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

It's been a while since I wrote any system code, and I was expermenting with nested closures. I came up with this gem, but wondered if you peeps could take a quick look.

I'd be interested in your comments on the safety of the system level calls and the s"appropriate" use of the nested closures.

#!/usr/bin/perl -w use strict; use POSIX ":sys_wait_h"; $SIG{CHLD} = sub {wait}; sub logger { my $file = shift; my $handle; open($handle,">$file") || die "in pain: $file: $!"; select($handle); $| =1; select(STDOUT); return sub { my $prefix = shift; return sub { print $handle "$prefix ".shift()."\n" }; }; } # for demo purposes, just to get some overlap my $warn = logger("warnings"); my $error = logger("errors"); my @identity = qw(identity1 identity2 identity3 identity4); foreach my $i (1..4) { my $identity = shift(@identity); unless (my $pid = fork()) { my $wlog = &$warn("$identity: "); my $elog = &$error("$identity: "); # make things a little more tidy sub logwarn { &$wlog(shift); } sub logerror { &$elog(shift); } foreach my $t (1..3) { sleep 2; logwarn("random warning $t"); logerror("random error $t"); } exit(0); } sleep(2); } my $kid; do { $kid = waitpid(-1,&WNOHANG); } until $kid == -1;

--
Brother Marvell

¤

Replies are listed 'Best First'.
Re: safety in system calls
by damian1301 (Curate) on Jun 15, 2001 at 21:04 UTC
    If you want to make sure that you are safe you should always use warnings, strict.pm, and taint mode(if you can). As an extra, you should try using the CPAN module Safe.

    Now since I am so bored, I just want to clean up a bit of that code.

    my @identity = qw(identity1 identity2 identity3 identity4); foreach my $i (1..4) { my $identity = shift(@identity); #...


    Wouldn't it be much better if you just iterated over the identity array because you don't use $i anywhere in there? ..:
    my @identity = qw(identity1 identity2 identity3 identity4); foreach my $identity (@identity) { #...


    Tiptoeing up to a Perl hacker.
    Dave AKA damian

      Yeah, OK, I changed things round a bit here and there. It was a quick test hack.

      I'll look into those modules and modes.

      Cheers

      --
      Brother Marvell

Re: safety in system calls
by runrig (Abbot) on Jun 15, 2001 at 21:17 UTC
    Your 'my $handle' line should be something like this:
    my $handle = new IO::File(">$file") or die "Can't open $file: $!"; # Or in 5.005 or later to avoid having to use IO::File # (doesn't seem to work in 5.004) my $handle = \do { local *FH }; open ($handle, ">$file") or die ..etc.
    Update:Do you really want the WNOHANG on the waitpid loop? You'll just be chewing up CPU until all the children exit. Better (I think) to leave out the WNOHANG and let the process block.

    Update2:hmm, just plain 'my $handle' seems to work ok in 5.6 - I wonder when that happened? Does that mean that this particular use for Dominus' Globjects (and for that matter, alot of the reason for FileHandle and IO::File) is now pointless?

      Once again, the code was not really thought about too for the test section.

      This whole area of perl is one which I've never really found a great explanation for. If anyone can recommend a node explaining how it works, fully, then that would be splendid.

      --
      Brother Marvell

      ¤