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

Case scenario: I want to run a perl interpreter over a socket, sort of perl shell. It's not all this process does, so I poll the interpreter socket(s) with select() and eval everything I sysread() from the sockets. I hook $SIG{__WARN__} and syswrite $@ and warnings to socket. So far, so cool... but what if I want to redirect stdout of this eval'd code to socket too?
local *STDOUT=$fh;

should work - I think - but it doesn't. I can't use print() on sockets (I tried). I don't want to make all remote code use syswrite instead of print - so, I try to redefine print() to a wrapper and eventually syswrite. But, it appears I can't do that. I could redefine chdir() just like man perlsub said, but the very same code with print() doesn't work.

What am I doing wrong? Any suggestions? Since this is a practical problem, anything fixing the problem of print() in eval'd code going to socket would be helpful.

Also, note that this has to run under cygwin perl, so some platform-dependent tricks may be unavailable. Recent versions of perl, however, aren't a problem.

-Kaatunut

Replies are listed 'Best First'.
(bbfu) Re: Remote interpreter (redefining print())
by bbfu (Curate) on May 08, 2001 at 01:39 UTC

    Check out this for info about why you can't override print.

    As for redirecting STDOUT to your socket, you'd probably want to use the dup form of open:

    open STDOUT, ">& $fh" or die;.

    Not totally sure if that will work for socket handles or not, and you most likely want to save a copy of the old STDOUT as well.

    HTH.

    Update: Oh, and for info on why your typeglob assignment might not be working, check out this node.

    bbfu
    Seasons don't fear The Reaper.
    Nor do the wind, the sun, and the rain.
    We can be like they are.

      You need to use the file descriptor, not the file itself:
      $fd = fileno($fh); open STDOUT, ">&$fd"
      Yes, this works for sockets. The typeglob assign just needs another star:
      local *STDOUT = *$fh;

        You need to use the file descriptor, not the file itself:

        Right, that's it. :-) I'm used to duping regular typeglob-style filehandles, in which case you can just use the name. But you're right that you need the fd for anonymous symbol-table entries (a la FileHandle).

        The typeglob assign just needs another star:

        Cool. I knew there was a way to do that but couldn't think what it needed. Good catch.

        bbfu
        Seasons don't fear The Reaper.
        Nor do the wind, the sun, and the rain.
        We can be like they are.