FAQ
Hello,

Here is simple script:
-----------------------
close STDOUT;
open my $fh, ">/tmp/test2";
print STDERR "FILE FD: ", fileno($fh), "\n";
open *STDOUT, ">/tmp/test";
print STDERR "new STDOUT FD: ". fileno(STDOUT) ."\n";
system("/bin/echo", "boo");
------------------------

STDERR output:
------------------------
FILE FD: 1
new STDOUT FD: 3
------------------------

As you can guess output of the system call is in /tmp/test2.

I have several questions:
1) Can you help me write a wrapper function for code blocks with
system() and open "|-" to protect FD #1?
2) Can system() do something about that? Shouldn't it do some magic
after fork and before exec. For example: fork, check perl's STDOUT, if
it's fd #1 then do nothing, if it's not then dup2(stdout's_fd, 1) or
close fd #1 if STDOUT in perl is closed and only then fork. Not sure
if it's possible, but I think it's sane and desireable behaviour.
3) Can perl protect FDs 1, 2 and 3?

If somebody is interested in real situation then I can describe on
request. In a few words: mod_perl/apache that close FD #1, DBI that
gets it for connection and third party extension that calls
system("/program/that/prints/to/STDOUT").

--
Best regards, Ruslan.

Search Discussions

  • Ruslan Zakirov at Apr 16, 2010 at 12:34 am
    Hello,

    I asked questions quoted below a few weeks ago, but nobody commented.
    Is the problem poorly described, author is a moron or picked at a sore
    place?
    On Thu, Apr 1, 2010 at 11:50 PM, Ruslan Zakirov wrote:
    Hello,

    Here is simple script:
    -----------------------
    close STDOUT;
    open my $fh, ">/tmp/test2";
    print STDERR "FILE FD: ", fileno($fh), "\n";
    open *STDOUT, ">/tmp/test";
    print STDERR "new STDOUT FD: ". fileno(STDOUT) ."\n";
    system("/bin/echo", "boo");
    ------------------------

    STDERR output:
    ------------------------
    FILE FD: 1
    new STDOUT FD: 3
    ------------------------

    As you can guess output of the system call is in /tmp/test2.

    I have several questions:
    1) Can you help me write a wrapper function for code blocks with
    system() and open "|-" to protect FD #1?
    2) Can system() do something about that? Shouldn't it do some magic
    after fork and before exec. For example: fork, check perl's STDOUT, if
    it's fd #1 then do nothing, if it's not then dup2(stdout's_fd, 1) or
    close fd #1 if STDOUT in perl is closed and only then fork. Not sure
    if it's possible, but I think it's sane and desireable behaviour.
    3) Can perl protect FDs 1, 2 and 3?

    If somebody is interested in real situation then I can describe on
    request. In a few words: mod_perl/apache that close FD #1, DBI that
    gets it for connection and third party extension that calls
    system("/program/that/prints/to/STDOUT").

    --
    Best regards, Ruslan.
    --
    Best regards, Ruslan.
  • David Golden at Apr 16, 2010 at 2:36 am
    I don't think you can assume that the desired behavior is always to
    have the fd's protected. And from what I recall of C open(), you get
    the lowest unused fd. So to "protect" means to open the fd's to
    something (/dev/null?) and that will screw with anything that is
    looking to see whether it was executed with open/closed fd's.

    I think you need to write a wrapper to do what you need for the
    particular situation.

    -- David
    On Thu, Apr 15, 2010 at 8:34 PM, Ruslan Zakirov wrote:
    Hello,

    I asked questions quoted below a few weeks ago, but nobody commented.
    Is the problem poorly described, author is a moron or picked at a sore
    place?
    On Thu, Apr 1, 2010 at 11:50 PM, Ruslan Zakirov wrote:
    Hello,

    Here is simple script:
    -----------------------
    close STDOUT;
    open my $fh, ">/tmp/test2";
    print STDERR "FILE FD: ", fileno($fh), "\n";
    open *STDOUT, ">/tmp/test";
    print STDERR "new STDOUT FD: ". fileno(STDOUT) ."\n";
    system("/bin/echo", "boo");
    ------------------------

    STDERR output:
    ------------------------
    FILE FD: 1
    new STDOUT FD: 3
    ------------------------

    As you can guess output of the system call is in /tmp/test2.

    I have several questions:
    1) Can you help me write a wrapper function for code blocks with
    system() and open "|-" to protect FD #1?
    2) Can system() do something about that? Shouldn't it do some magic
    after fork and before exec. For example: fork, check perl's STDOUT, if
    it's fd #1 then do nothing, if it's not then dup2(stdout's_fd, 1) or
    close fd #1 if STDOUT in perl is closed and only then fork. Not sure
    if it's possible, but I think it's sane and desireable behaviour.
    3) Can perl protect FDs 1, 2 and 3?

    If somebody is interested in real situation then I can describe on
    request. In a few words: mod_perl/apache that close FD #1, DBI that
    gets it for connection and third party extension that calls
    system("/program/that/prints/to/STDOUT").

    --
    Best regards, Ruslan.
    --
    Best regards, Ruslan.
  • Ruslan Zakirov at Apr 16, 2010 at 11:22 am
    Hello, David.

    I want to describe a problem I'm facing. mod_perl with C code closes
    STDOUT and opens it again, however it misuses perl API in some way
    that new STDOUT is opened on FD != 1 and next descriptors related
    operation takes over FD #1. In my case it's connection to mysql. Third
    party code calls system($cmd), cmd prints to "STDOUT" and closes the
    connection with junk. It's very hard to debug such issues and I was
    really surprised when I figured out that the current perl STDOUT is
    not accounted in system() and open "|-".

    As such behaviour been there for a while then may be it's possible to
    write a pragma, for example "respect_std_streams_on_exec" :) I'm just
    not sure if it's possible, is it?
    On Fri, Apr 16, 2010 at 6:35 AM, David Golden wrote:
    I don't think you can assume that the desired behavior is always to
    have the fd's protected. And from what I recall of C open(), you get
    the lowest unused fd.  So to "protect" means to open the fd's to
    something (/dev/null?) and that will screw with anything that is
    looking to see whether it was executed with open/closed fd's.

    I think you need to write a wrapper to do what you need for the
    particular situation.

    -- David
    On Thu, Apr 15, 2010 at 8:34 PM, Ruslan Zakirov wrote:
    Hello,

    I asked questions quoted below a few weeks ago, but nobody commented.
    Is the problem poorly described, author is a moron or picked at a sore
    place?
    On Thu, Apr 1, 2010 at 11:50 PM, Ruslan Zakirov wrote:
    Hello,

    Here is simple script:
    -----------------------
    close STDOUT;
    open my $fh, ">/tmp/test2";
    print STDERR "FILE FD: ", fileno($fh), "\n";
    open *STDOUT, ">/tmp/test";
    print STDERR "new STDOUT FD: ". fileno(STDOUT) ."\n";
    system("/bin/echo", "boo");
    ------------------------

    STDERR output:
    ------------------------
    FILE FD: 1
    new STDOUT FD: 3
    ------------------------

    As you can guess output of the system call is in /tmp/test2.

    I have several questions:
    1) Can you help me write a wrapper function for code blocks with
    system() and open "|-" to protect FD #1?
    2) Can system() do something about that? Shouldn't it do some magic
    after fork and before exec. For example: fork, check perl's STDOUT, if
    it's fd #1 then do nothing, if it's not then dup2(stdout's_fd, 1) or
    close fd #1 if STDOUT in perl is closed and only then fork. Not sure
    if it's possible, but I think it's sane and desireable behaviour.
    3) Can perl protect FDs 1, 2 and 3?

    If somebody is interested in real situation then I can describe on
    request. In a few words: mod_perl/apache that close FD #1, DBI that
    gets it for connection and third party extension that calls
    system("/program/that/prints/to/STDOUT").

    --
    Best regards, Ruslan.
    --
    Best regards, Ruslan.


    --
    Best regards, Ruslan.
  • Torsten Förtsch at Apr 16, 2010 at 11:36 am

    On Friday 16 April 2010 13:22:38 Ruslan Zakirov wrote:
    I want to describe a problem I'm facing. mod_perl with C code closes
    STDOUT and opens it again, however it misuses perl API in some way
    that new STDOUT is opened on FD != 1 and next descriptors related
    operation takes over FD #1.
    This has been fixed in mod_perl trunk recently.

    Torsten Förtsch

    --
    Need professional modperl support? Hire me! (http://foertsch.name)

    Like fantasy? http://kabatinte.net

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupperl5-porters @
categoriesperl
postedApr 1, '10 at 7:51p
activeApr 16, '10 at 11:36a
posts5
users3
websiteperl.org

People

Translate

site design / logo © 2022 Grokbase