Defeating OS buffering?

Ask a Question related to PERL Miscellaneous, Design and Development.

  1. #1

    Default Defeating OS buffering?

    I'm trying to use Perl to automate a specific test process, but OS
    buffering is defeating some of the main utility of it. I run a
    program like this:

    open(TEST, "$testcmd |") or die "bah-- $!";
    while(<TEST>) {
    # do stuff
    }
    close(TEST);

    Part of the problem here is that the test referred to in $testcmd is a
    bash script that execs a C program, which I do not have source to.
    This C program doesn't print a lot of output, so as a consequence, I
    don't see any of it until the C program exits. Is there any way,
    short of modifying the C program, that I can defeat the OS buffering
    of the C program's output?

    -=Eric, fully expecting the answer to be "no". :(
    --
    Come to think of it, there are already a million monkeys on a million
    typewriters, and Usenet is NOTHING like Shakespeare.
    -- Blair Houghton.
    Eric Schwartz Guest

  2. Similar Questions and Discussions

    1. Defeating Form 'bots
      Although I've had forms on my site for several years, have recently been receiving too many forms filled out by robots (according to my domain...
    2. Spry Region Defeating Me
      I purchased the entire set of Adobe Creative Suite 3 Total Training Videos and have walked through the 2 DVDs of Dreamweaver CS3 lessons. I also...
    3. Player buffering
      Specifically when the player is used with Comcast.net home page and video news -- the player intially buffers the video clips complete and plays...
    4. Buffering Notification
      'NetStream.Buffer.Empty' is a message sent from a netStream's information status...using this I can if(info.code == "NetStream.Buffer.Empty"){...
    5. double buffering ?
      Hi, Is there a way to do something like double buffering in Java. I have a 3D sprite with a lot of models. I preload and initialize the whole 3D...
  3. #2

    Default Re: Defeating OS buffering?

    Eric Schwartz <emschwar@pobox.com> wrote:
    > I'm trying to use Perl to automate a specific test process, but OS
    > buffering is defeating some of the main utility of it. I run a
    > program like this:
    >
    > open(TEST, "$testcmd |") or die "bah-- $!";
    > while(<TEST>) {
    > # do stuff
    > }
    > close(TEST);
    >
    > Part of the problem here is that the test referred to in $testcmd is a
    > bash script that execs a C program, which I do not have source to.
    > This C program doesn't print a lot of output, so as a consequence, I
    > don't see any of it until the C program exits. Is there any way,
    > short of modifying the C program, that I can defeat the OS buffering
    > of the C program's output?
    >
    > -=Eric, fully expecting the answer to be "no". :(
    How about reading single bytes bytes from the program?

    open(TEST, "/home/t/c/a.out |") or die "bah-- $!";
    $|++;
    while( 0 != read TEST, $_, 1, 1 ) {
    print;
    }
    close(TEST);

    HTH,
    --
    Vlad
    Vlad Tepes Guest

  4. #3

    Default Re: Defeating OS buffering?

    Vlad Tepes <minceme@start.no> writes:
    > How about reading single bytes bytes from the program?
    >
    > open(TEST, "/home/t/c/a.out |") or die "bah-- $!";
    To reproduce this properly, you'd need a bash program that just did:

    exec /home/t/c/a.out

    and you'd invoke the bash program there.
    > $|++;
    This unbuffers STDOUT, which doesn't help when the problem is that the
    OS is buffering the TEST filehandle.
    > while( 0 != read TEST, $_, 1, 1 ) {
    > print;
    > }
    > close(TEST);
    How is reading input that doesn't show up a character at a time going
    to help? Either it's there, or it isn't; reading it in smaller chunks
    is just making things more inefficient without actually changing
    anything.
    > HTH,
    I'm afraid not. Thanks for the effort, anyhow.

    -=Eric
    --
    Come to think of it, there are already a million monkeys on a million
    typewriters, and Usenet is NOTHING like Shakespeare.
    -- Blair Houghton.
    Eric Schwartz Guest

  5. #4

    Default Re: Defeating OS buffering?

    Eric Schwartz <emschwar@pobox.com> wrote:
    > Vlad Tepes <minceme@start.no> writes:
    >
    >> open(TEST, "/home/t/c/a.out |") or die "bah-- $!";
    >
    > To reproduce this properly, you'd need a bash program that just did:
    >
    > exec /home/t/c/a.out
    Ok, now I have created a bash-script that exec'ed the a.out, and used
    that in the open-statement above. It worked nicely, doing what you
    wanted.

    Maybe I'm missing something?

    The script I used:

    #!/bin/bash
    exec "/home/t/c/a.out";

    The C-program:

    #include <stdio.h>
    #include <unistd.h>

    int main ( void ) {
    printf("Some text...");
    fflush(NULL);
    sleep(3);
    printf("some more text...\n");
    return(0);
    }

    The perl program:

    #!/usr/bin/perl
    use warnings;
    use strict;

    open(TEST, "/tmp/t.sh |") or die "bah-- $!";
    $|++;
    while( 0 != read TEST, $_, 1, 1 ){
    print;
    }
    close(TEST);

    Hope this helps,
    --
    Vlad
    Vlad Tepes Guest

  6. #5

    Default Re: Defeating OS buffering?

    "Vlad Tepes" <minceme@start.no> wrote in message
    news:bjo0fn$8gf$1@troll.powertech.no...
    > Eric Schwartz <emschwar@pobox.com> wrote:
    > > Vlad Tepes <minceme@start.no> writes:
    >
    [Other code]
    > The perl program:
    >
    > #!/usr/bin/perl
    > use warnings;
    > use strict;
    >
    > open(TEST, "/tmp/t.sh |") or die "bah-- $!";
    > $|++;
    > while( 0 != read TEST, $_, 1, 1 ){
    > print;
    > }
    > close(TEST);
    Or, as an FYI, you could rewrite the while as:

    print while (0 != read TEST, $_, 1, 1);


    Trent Curry Guest

  7. #6

    Default Re: Defeating OS buffering?

    "Eric Schwartz" <emschwar@pobox.com> wrote in message
    news:etod6e8zbl2.fsf@wormtongue.emschwar...
    > Vlad Tepes <minceme@start.no> writes:
    > > How about reading single bytes bytes from the program?
    > >
    > > open(TEST, "/home/t/c/a.out |") or die "bah-- $!";
    >
    > To reproduce this properly, you'd need a bash program that just did:
    >
    > exec /home/t/c/a.out
    >
    > and you'd invoke the bash program there.
    >
    > > $|++;
    >
    > This unbuffers STDOUT, which doesn't help when the problem is that the
    > OS is buffering the TEST filehandle.
    From perldoc perlvar:

    $OUTPUT_AUTOFLUSH
    $|

    If set to nonzero, forces a flush right away and after every write
    or print on the currently selected output channel. [Snipped rest]
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    So in this case, TEST is the currently selected output handle.


    Trent Curry Guest

  8. #7

    Default Re: Defeating OS buffering?

    Vlad Tepes <minceme@start.no> writes:

    <snip>
    > The C-program:
    >
    > #include <stdio.h>
    > #include <unistd.h>
    >
    > int main ( void ) {
    > printf("Some text...");
    > fflush(NULL);
    ^^^^^^^^^^^^^
    <snip>

    That's the problem. Take that out, and it won't work. As I said, I
    don't have control over the C program, so I can't make it fflush.

    -=Eric
    --
    Come to think of it, there are already a million monkeys on a million
    typewriters, and Usenet is NOTHING like Shakespeare.
    -- Blair Houghton.
    Eric Schwartz Guest

  9. #8

    Default Re: Defeating OS buffering?

    "Trent Curry" <tcurrey@no.no.no.i.said.no> writes:
    > "Eric Schwartz" <emschwar@pobox.com> wrote in message
    > news:etod6e8zbl2.fsf@wormtongue.emschwar...
    >> Vlad Tepes <minceme@start.no> writes:
    >> > $|++;
    >>
    >> This unbuffers STDOUT, which doesn't help when the problem is that the
    >> OS is buffering the TEST filehandle.
    >
    > From perldoc perlvar:
    >
    > $OUTPUT_AUTOFLUSH
    > $|
    >
    > If set to nonzero, forces a flush right away and after every write
    > or print on the currently selected output channel. [Snipped rest]
    > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    >
    > So in this case, TEST is the currently selected output handle.
    No, TEST is open for *INPUT*. Hint: if you can read from it, it's
    open for input. If you can write to it, it's open for output. And
    even if it were open for output, $| only works on filehandles that you
    select with the one-arg select(), which Vlad did not do.

    -=Eric
    --
    Come to think of it, there are already a million monkeys on a million
    typewriters, and Usenet is NOTHING like Shakespeare.
    -- Blair Houghton.
    Eric Schwartz Guest

  10. #9

    Default Re: Defeating OS buffering?

    Trent Curry <tcurrey@no.no.no.i.said.no> wrote:

    > So in this case, TEST is the currently selected output handle.

    Not unless there was a call to select() missing from the
    code that was posted.

    Why go on about output when the OP's problem is with _in_put?


    --
    Tad McClellan SGML consulting
    [email]tadmc@augustmail.com[/email] Perl programming
    Fort Worth, Texas
    Tad McClellan Guest

  11. #10

    Default Re: Defeating OS buffering?

    "Eric Schwartz" <emschwar@pobox.com> wrote in message
    news:etowucgxrim.fsf@wormtongue.emschwar...
    > "Trent Curry" <tcurrey@no.no.no.i.said.no> writes:
    > > "Eric Schwartz" <emschwar@pobox.com> wrote in message
    > > news:etod6e8zbl2.fsf@wormtongue.emschwar...
    > >> Vlad Tepes <minceme@start.no> writes:
    > >> > $|++;
    > >>
    > >> This unbuffers STDOUT, which doesn't help when the problem is that the
    > >> OS is buffering the TEST filehandle.
    > >
    > > From perldoc perlvar:
    > >
    > > $OUTPUT_AUTOFLUSH
    > > $|
    > >
    > > If set to nonzero, forces a flush right away and after every write
    > > or print on the currently selected output channel. [Snipped rest]
    > > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    > >
    > > So in this case, TEST is the currently selected output handle.
    >
    > No, TEST is open for *INPUT*. Hint: if you can read from it, it's
    > open for input. If you can write to it, it's open for output. And
    > even if it were open for output, $| only works on filehandles that you
    > select with the one-arg select(), which Vlad did not do.
    Sorry, you are right, I over looked that little but very significant part.
    Thanks for catching that.


    Trent Curry Guest

  12. #11

    Default Re: Defeating OS buffering?

    "Tad McClellan" <tadmc@augustmail.com> wrote in message
    news:slrnblv8km.58r.tadmc@magna.augustmail.com...
    > Trent Curry <tcurrey@no.no.no.i.said.no> wrote:
    >
    >
    > > So in this case, TEST is the currently selected output handle.
    >
    >
    > Not unless there was a call to select() missing from the
    > code that was posted.
    >
    > Why go on about output when the OP's problem is with _in_put?
    Sorry, that was my screw up. Over looked that part. My apologies.


    Trent Curry Guest

  13. #12

    Default Re: Defeating OS buffering?

    Eric Schwartz <emschwar@pobox.com> wrote:
    > Vlad Tepes <minceme@start.no> writes:
    >
    > <snip>
    >
    >> The C-program:
    >>
    >> #include <stdio.h>
    >> #include <unistd.h>
    >>
    >> int main ( void ) {
    >> printf("Some text...");
    >> fflush(NULL);
    > ^^^^^^^^^^^^^
    > <snip>
    >
    > That's the problem. Take that out, and it won't work. As I said, I
    > don't have control over the C program, so I can't make it fflush.
    Then I have to say pass. :-(

    I don't know if it is possible to force a program to flush it's output.
    And if it is, I suppose the solution will be OS-dependant.

    --
    Vlad
    Vlad Tepes Guest

  14. #13

    Default Re: Defeating OS buffering?

    In article <bjokeh$fat$2@troll.powertech.no>,
    Vlad Tepes <minceme@start.no> wrote:
    > Eric Schwartz <emschwar@pobox.com> wrote:
    >
    > > Vlad Tepes <minceme@start.no> writes:
    > >
    > > <snip>
    > >
    > >> The C-program:
    > >>
    > >> #include <stdio.h>
    > >> #include <unistd.h>
    > >>
    > >> int main ( void ) {
    > >> printf("Some text...");
    > >> fflush(NULL);
    > > ^^^^^^^^^^^^^
    > > <snip>
    > >
    > > That's the problem. Take that out, and it won't work. As I said, I
    > > don't have control over the C program, so I can't make it fflush.
    >
    > Then I have to say pass. :-(
    >
    > I don't know if it is possible to force a program to flush it's output.
    > And if it is, I suppose the solution will be OS-dependant.
    Not that this is going to be useful, but if you can put a ptty between
    the parent and the child, the child should revert to line buffering
    because it'll think its output is going to a device. I have no idea how
    to go about this in Perl, though (I used to know how to do it in C).
    Also, only works under *NIX variants, as far as I know.
    --
    Kevin Michael Vail | Dogbert: That's circular reasoning.
    [email]kevin@vaildc.net[/email] | Dilbert: I prefer to think of it as no loose ends.
    [url]http://www.vaildc.net/kevin/[/url]
    Kevin Michael Vail Guest

  15. #14

    Default Re: Defeating OS buffering?

    Eric Schwartz <emschwar@pobox.com> wrote in message news:<eto1xuoz66r.fsf@wormtongue.emschwar>...
    > Vlad Tepes <minceme@start.no> writes:
    >
    > <snip>
    >
    > > The C-program:
    > >
    > > #include <stdio.h>
    > > #include <unistd.h>
    > >
    > > int main ( void ) {
    > > printf("Some text...");
    > > fflush(NULL);
    > ^^^^^^^^^^^^^
    > <snip>
    >
    > That's the problem. Take that out, and it won't work. As I said, I
    > don't have control over the C program, so I can't make it fflush.
    It will probably fflush() implicitly on newline if it thinks it's
    STDOUT is going to an interactive terminal.

    I Expect (hint, hint) you could find something on CPAN that would
    allow you to fool a subprocess into thinking it's connected to a
    terminal.
    nobull@mail.com Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139