IO::Scalar insanity

Discussion in 'Perl Misc' started by bill, Mar 1, 2005.

  1. bill

    bill Guest

    I run into the need to do this *all* the time, but I have not come
    up with a solution. This need arises almost invariably during the
    debugging of a CGI script. At the beginning of the run I want to
    inspect all the input that the CGI script will read from STDIN,
    but I want to then "restore" this input back to the STDIN stream
    so that execution/debugging session can proceed normally.

    I *think* the best solution would be to slurp all the text into a
    lexical

    my $input = do { local $/; <STDIN> };
    # {
    # open my $out, ">debugging_data" or die "$!\n";
    # print $out $input;
    # close $out or die "$!\n";
    # }

    associate this lexical with an IO::Scalar handle

    my $SH = IO::Scalar->new(\$input);

    and then redefine STDIN so that it points to this IO::Scalar.
    *This* is the part that I just can't figure out. Following what
    I see in tutorials and books, I have tried

    open(STDIN, "<&$SH") or die "$!\n";

    but the open fails with an "invalid argument" error message. I've
    also tried

    open(STDIN, "<&=$SH") or die "$!\n";

    (which fails with the same error), and

    *STDIN = *SH;

    and many variants thereof, all of which fail silently.

    It is obvious that I have *no clue* and am just wildly trying out
    random stuff.

    I've read every bit of documentation I can think of, but I have
    not hit on the answer to this question. I know this is all very
    basic, but if someone could spell it out for me I'd greatly appreciate
    it.

    bill
     
    bill, Mar 1, 2005
    #1
    1. Advertising

  2. bill wrote:
    > I run into the need to do this *all* the time, but I have not come
    > up with a solution. This need arises almost invariably during the
    > debugging of a CGI script. At the beginning of the run I want to
    > inspect all the input that the CGI script will read from STDIN,
    > but I want to then "restore" this input back to the STDIN stream
    > so that execution/debugging session can proceed normally.
    >
    > I *think* the best solution would be to slurp all the text into a
    > lexical
    >
    > my $input = do { local $/; <STDIN> };
    > # {
    > # open my $out, ">debugging_data" or die "$!\n";
    > # print $out $input;
    > # close $out or die "$!\n";
    > # }
    >
    > associate this lexical with an IO::Scalar handle
    >
    > my $SH = IO::Scalar->new(\$input);
    >
    > and then redefine STDIN so that it points to this IO::Scalar.
    > *This* is the part that I just can't figure out. Following what
    > I see in tutorials and books, I have tried
    >
    > open(STDIN, "<&$SH") or die "$!\n";


    you probably want to open it on the file descriptor (take a look at fileno):

    redwood 24357 $ perl -le 'open IN,"</etc/passwd";open STDIN,"<&".fileno(IN);
    $a=<STDIN>;
    print "$a\n"'
    root:x:0:1:Super-User:/:/sbin/sh


    *but* what you probably want to be doing is using the CGI module to
    parse your cgi parameters. You can initialize this from a FileHandle or
    IO::File object as necessary, so you could slurp STDIN into a lexical
    variable, create an IO::String object from this, dump out the results
    and then initialize the CGI object from this. Also check out
    restore_parameters in the CGI module.

    It is highly likely that I am missing something obvious here.

    Mark
     
    Mark Clements, Mar 1, 2005
    #2
    1. Advertising

  3. bill <> wrote in news:d02hah$k8r$1
    @reader2.panix.com:


    > I run into the need to do this *all* the time, but I have not come
    > up with a solution. This need arises almost invariably during the
    > debugging of a CGI script. At the beginning of the run I want to
    > inspect all the input that the CGI script will read from STDIN,
    > but I want to then "restore" this input back to the STDIN stream
    > so that execution/debugging session can proceed normally.


    http://search.cpan.org/~lds/CGI.pm-
    3.05/CGI.pm#CREATING_A_NEW_QUERY_OBJECT_FROM_AN_INPUT_FILE

    I am curious why that is not a satisfactory method.

    Sinan.
     
    A. Sinan Unur, Mar 1, 2005
    #3
  4. bill

    kj Guest

    In <d02hah$k8r$> bill <> writes:

    >I run into the need to do this *all* the time, but I have not come
    >up with a solution. This need arises almost invariably during the
    >debugging of a CGI script. At the beginning of the run I want to
    >inspect all the input that the CGI script will read from STDIN,
    >but I want to then "restore" this input back to the STDIN stream
    >so that execution/debugging session can proceed normally.


    >I *think* the best solution would be to slurp all the text into a
    >lexical


    > my $input = do { local $/; <STDIN> };
    > # {
    > # open my $out, ">debugging_data" or die "$!\n";
    > # print $out $input;
    > # close $out or die "$!\n";
    > # }


    >associate this lexical with an IO::Scalar handle


    > my $SH = IO::Scalar->new(\$input);


    >and then redefine STDIN so that it points to this IO::Scalar.
    >*This* is the part that I just can't figure out. Following what
    >I see in tutorials and books, I have tried


    > open(STDIN, "<&$SH") or die "$!\n";


    >but the open fails with an "invalid argument" error message. I've
    >also tried


    > open(STDIN, "<&=$SH") or die "$!\n";


    >(which fails with the same error), and


    > *STDIN = *SH;


    >and many variants thereof, all of which fail silently.


    >It is obvious that I have *no clue* and am just wildly trying out
    >random stuff.


    >I've read every bit of documentation I can think of, but I have
    >not hit on the answer to this question. I know this is all very
    >basic, but if someone could spell it out for me I'd greatly appreciate
    >it.


    Not so basic, I think. IIRC Perl can't do what you want it to do;
    something having to do with needing a real file descriptor associated
    with the handle before it can dupe it; IO::Scalar and the like
    don't provide the FILENO method, AFAIK.

    But how about putting this at some suitable location in your source:

    my $peek = do { local $/; <STDIN> };

    unless (my $pid = open(STDIN, "-|")) {
    die "Fork failed: $!" unless defined $pid;
    print $peek;
    exit 0;
    }

    The subsequent parent code will read from STDIN as before, but now
    it's coming from the child process.

    kj

    --
    NOTE: In my address everything before the first period is backwards;
    and the last period, and everything after it, should be discarded.
     
    kj, Mar 1, 2005
    #4
  5. bill

    kj Guest

    In <Xns960C9E508FAA6asu1cornelledu@127.0.0.1> "A. Sinan Unur" <> writes:

    >bill <> wrote in news:d02hah$k8r$1
    >@reader2.panix.com:



    >> I run into the need to do this *all* the time, but I have not come
    >> up with a solution. This need arises almost invariably during the
    >> debugging of a CGI script. At the beginning of the run I want to
    >> inspect all the input that the CGI script will read from STDIN,
    >> but I want to then "restore" this input back to the STDIN stream
    >> so that execution/debugging session can proceed normally.


    >http://search.cpan.org/~lds/CGI.pm-
    >3.05/CGI.pm#CREATING_A_NEW_QUERY_OBJECT_FROM_AN_INPUT_FILE


    >I am curious why that is not a satisfactory method.


    For starters, it assumes that the CGI script is implemented through
    CGI.pm, which may not be the case. Even when the script is
    implemented using CGI.pm, if it was written by someone else in a
    less than perspicuous style, I prefer to minimize the amount of
    such code that I must understand.

    kj

    --
    NOTE: In my address everything before the first period is backwards;
    and the last period, and everything after it, should be discarded.
     
    kj, Mar 1, 2005
    #5
  6. kj <> wrote in
    news:d02ohk$es4$:

    > In <Xns960C9E508FAA6asu1cornelledu@127.0.0.1> "A. Sinan Unur"
    > <> writes:
    >
    >>bill <> wrote in news:d02hah$k8r$1
    >>@reader2.panix.com:

    >
    >
    >>> I run into the need to do this *all* the time, but I have not come
    >>> up with a solution. This need arises almost invariably during the
    >>> debugging of a CGI script. At the beginning of the run I want to
    >>> inspect all the input that the CGI script will read from STDIN,
    >>> but I want to then "restore" this input back to the STDIN stream
    >>> so that execution/debugging session can proceed normally.

    >
    >>http://search.cpan.org/~lds/CGI.pm-
    >>3.05/CGI.pm#CREATING_A_NEW_QUERY_OBJECT_FROM_AN_INPUT_FILE

    >
    >>I am curious why that is not a satisfactory method.

    >
    > For starters, it assumes that the CGI script is implemented through
    > CGI.pm, which may not be the case.


    I am not going to get into that argument.

    > Even when the script is implemented using CGI.pm, if it was written
    > by someone else in a less than perspicuous style, I prefer to minimize
    > the amount of such code that I must understand.


    This makes no sense. How can coding style be an issue when we are talking
    about passing parameters using an input file? No matter how bad the
    original coding style, the way you would initialize a new CGI object from
    a parameter file is the same.

    Sinan.
     
    A. Sinan Unur, Mar 1, 2005
    #6
  7. On Tue, 1 Mar 2005, kj wrote:

    > In <Xns960C9E508FAA6asu1cornelledu@127.0.0.1> "A. Sinan Unur" <> writes:
    >
    > >http://search.cpan.org/~lds/CGI.pm-
    > >3.05/CGI.pm#CREATING_A_NEW_QUERY_OBJECT_FROM_AN_INPUT_FILE

    >
    > >I am curious why that is not a satisfactory method.

    >
    > For starters, it assumes that the CGI script is implemented through
    > CGI.pm, which may not be the case.


    Anyone who's expert enough to produce a safe and reliable
    implementation that doesn't use CGI.pm will have no difficulty in
    solving that problem without any help from us.

    > Even when the script is implemented using CGI.pm, if it was written
    > by someone else in a less than perspicuous style, I prefer to
    > minimize the amount of such code that I must understand.


    It sounds as if you're trying to solve a problem that has rather
    little technical content, but is more an exercise in sociology.
     
    Alan J. Flavell, Mar 2, 2005
    #7
  8. bill

    kj Guest

    In <> "Alan J. Flavell" <> writes:

    >On Tue, 1 Mar 2005, kj wrote:


    >> In <Xns960C9E508FAA6asu1cornelledu@127.0.0.1> "A. Sinan Unur" <> writes:
    >>
    >> >http://search.cpan.org/~lds/CGI.pm-
    >> >3.05/CGI.pm#CREATING_A_NEW_QUERY_OBJECT_FROM_AN_INPUT_FILE

    >>
    >> >I am curious why that is not a satisfactory method.

    >>
    >> For starters, it assumes that the CGI script is implemented through
    >> CGI.pm, which may not be the case.


    >Anyone who's expert enough to produce a safe and reliable
    >implementation that doesn't use CGI.pm will have no difficulty in
    >solving that problem without any help from us.


    The OP didn't specify whether he was debugging his own code, or
    that what he was debugging was a "safe and reliable" anything.

    kj

    --
    NOTE: In my address everything before the first period is backwards;
    and the last period, and everything after it, should be discarded.
     
    kj, Mar 2, 2005
    #8
  9. On Wed, 2 Mar 2005, kj wrote, quoting me:

    > >Anyone who's expert enough to produce a safe and reliable
    > >implementation that doesn't use CGI.pm will have no difficulty in
    > >solving that problem without any help from us.

    >
    > The OP didn't specify whether he was debugging his own code, or
    > that what he was debugging was a "safe and reliable" anything.


    And what conclusion would you draw from that? (I've already drawn
    mine, by the way.)
     
    Alan J. Flavell, Mar 2, 2005
    #9
  10. bill

    bill Guest

    Thanks for all the help.

    BTW, the code I'm debugging is indeed something I wrote, but it
    uses SOAP::Lite, whose documentation I find pretty unhelpful and
    whose code I find absolutely impenetrable. I have no idea whether
    SOAP::Lite uses CGI.pm for its "CGI-based" servers.

    I am surprised to learn that one can't make a string/buffer look
    like STDIN in a Perl script. I could *swear* I saw this done
    somewhere.

    bill
     
    bill, Mar 2, 2005
    #10
  11. bill

    kj Guest

    In <> "Alan J. Flavell" <> writes:

    >On Wed, 2 Mar 2005, kj wrote, quoting me:


    >> >Anyone who's expert enough to produce a safe and reliable
    >> >implementation that doesn't use CGI.pm will have no difficulty in
    >> >solving that problem without any help from us.

    >>
    >> The OP didn't specify whether he was debugging his own code, or
    >> that what he was debugging was a "safe and reliable" anything.


    >And what conclusion would you draw from that?


    See my previous posts on this thread.

    >(I've already drawn
    >mine, by the way.)


    Oh, goodie!

    kj


    --
    NOTE: In my address everything before the first period is backwards;
    and the last period, and everything after it, should be discarded.
     
    kj, Mar 2, 2005
    #11
  12. On Wed, 2 Mar 2005, kj wrote:

    > In <> "Alan J. Flavell" <> writes:
    >
    > >On Wed, 2 Mar 2005, kj wrote, quoting me:

    >
    > >> >Anyone who's expert enough to produce a safe and reliable
    > >> >implementation that doesn't use CGI.pm will have no difficulty in
    > >> >solving that problem without any help from us.
    > >>
    > >> The OP didn't specify whether he was debugging his own code, or
    > >> that what he was debugging was a "safe and reliable" anything.

    >
    > >And what conclusion would you draw from that?

    >
    > See my previous posts on this thread.


    Thank you for offering me the opportunity to review your contributions
    this thread. I've done so, and I don't see anything which relates to
    the issue of safe and reliable CGI scripts.

    If you're of the opinion that it doesn't matter whether CGI scripts
    are safe or reliable, then there's this guy called Matt who you might
    like to meet.

    OTOH if you'd care to read Lincoln Stein's web security FAQ, I think
    you might find there's quite a lot of pratfalls lying in wait for
    those who don't take the issues seriously.

    ttfn
     
    Alan J. Flavell, Mar 2, 2005
    #12
  13. bill wrote:

    > I run into the need to do this *all* the time, but I have not come
    > up with a solution. This need arises almost invariably during the
    > debugging of a CGI script. At the beginning of the run I want to
    > inspect all the input that the CGI script will read from STDIN,
    > but I want to then "restore" this input back to the STDIN stream
    > so that execution/debugging session can proceed normally.
    >
    > I *think* the best solution would be to slurp all the text into a
    > lexical


    If it's not too big.

    > my $input = do { local $/; <STDIN> };
    > # {
    > # open my $out, ">debugging_data" or die "$!\n";
    > # print $out $input;
    > # close $out or die "$!\n";
    > # }
    >
    > associate this lexical with an IO::Scalar handle
    >
    > my $SH = IO::Scalar->new(\$input);
    >
    > and then redefine STDIN so that it points to this IO::Scalar.
    > *This* is the part that I just can't figure out. Following what
    > I see in tutorials and books, I have tried
    >
    > open(STDIN, "<&$SH") or die "$!\n";


    You cannot use the two argument form of open() to do a filedescriptor
    duplication on a (blessed) GLOBref. You need to use the three arg form.

    Not that this is relevant since you cannot duplicate the underlying OS
    filedescriptor of a Perl file handle when the Perl file handle has no
    underlying OS filedescriptor (as in IO::Scalar).

    >
    > but the open fails with an "invalid argument" error message. I've
    > also tried
    >
    > open(STDIN, "<&=$SH") or die "$!\n";
    >
    > (which fails with the same error), and


    That is because you cannot reuse the underlying OS filedescriptor of a
    Perl file handle when the Perl file handle has no underlying OS
    filedescriptor..


    > *STDIN = *SH;
    >
    > and many variants thereof, all of which fail silently.


    Should be:

    *STDIN = $SH;

    I tried testing it here but I've not got IO::Scalar installed (it's
    rendered obsolete by Perl5.8). I replaced

    my $SH = IO::Scalar->new(\$input);

    with

    open( my $SH, '<', \$input);

    Seemed to work OK.
     
    Brian McCauley, Mar 4, 2005
    #13
  14. bill

    bill Guest

    In <d09qo0$92i$> Brian McCauley <> writes:

    >bill wrote:


    >> *STDIN = *SH;
    >>
    >> and many variants thereof, all of which fail silently.


    >Should be:


    > *STDIN = $SH;


    >I tried testing it here but I've not got IO::Scalar installed (it's
    >rendered obsolete by Perl5.8). I replaced


    > my $SH = IO::Scalar->new(\$input);


    >with


    > open( my $SH, '<', \$input);


    >Seemed to work OK.


    This appears to be the way to go (assuming v5.8 is available). I
    first tried (wishfully)

    open(STDIN, '<', \$input)

    which failed (for reasons I don't understand, but I imagine have
    to do with the old fileno issue you mentioned), but this worked

    open(my $SH, '<', \$input); # or die, etc.
    *STDIN = $SH;

    Thanks!

    bill
     
    bill, Mar 6, 2005
    #14
  15. bill

    Eric Bohlman Guest

    bill <> wrote in
    news:d0f7fe$k7m$:

    > This appears to be the way to go (assuming v5.8 is available). I
    > first tried (wishfully)
    >
    > open(STDIN, '<', \$input)
    >
    > which failed (for reasons I don't understand, but I imagine have
    > to do with the old fileno issue you mentioned), but this worked
    >
    > open(my $SH, '<', \$input); # or die, etc.
    > *STDIN = $SH;


    Your first attempt will work if you close STDIN first.
     
    Eric Bohlman, Mar 7, 2005
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Big D

    Viewstate Insanity

    Big D, Jan 6, 2004, in forum: ASP .Net
    Replies:
    6
    Views:
    572
    Big D
    Jan 6, 2004
  2. JavaEnquirer

    Java Management Insanity

    JavaEnquirer, Jul 20, 2005, in forum: Java
    Replies:
    6
    Views:
    415
  3. Tim Daneliuk

    re Insanity

    Tim Daneliuk, Jan 22, 2005, in forum: Python
    Replies:
    9
    Views:
    471
    Tim Daneliuk
    Jan 26, 2005
  4. Clint Olsen
    Replies:
    6
    Views:
    376
    Jeff 'japhy' Pinyan
    Nov 13, 2003
  5. Mark

    Replace scalar in another scalar

    Mark, Jan 27, 2005, in forum: Perl Misc
    Replies:
    4
    Views:
    171
    Arndt Jonasson
    Jan 27, 2005
Loading...

Share This Page