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

Greetings all my fellow monks,

After running this line:

run \@cmd, \$in, \$out, \$err, timeout( 3, exception => 'timeout' );
where cmd is a little program written in C, which mainly does some printf stuff.

I found that when "\n" is added to the the printf statement as printf("hello world\n"); I can get the output ("hello world") through $out without any problem,
but without it the output is always empty. (IMHO, the ``$out'' is also line-buffered as stdout.)

So, my question is, is there any way to get all the output generated by the C program regardless of the ending newline character?

Any help is appreciated.

Update 1: Here's my code.
#!/usr/bin/perl -w use strict; use warnings; use CGI qw/:standard/; use CGI::Carp qw/fatalsToBrowser warningsToBrowser/; use IPC::Run qw/run timeout/; if (param('in')) { $in = param('in'); print p("Input: $in\n"); } else { undef $in; } my @cmd = ( "/data2/tmp/a.exc" ); eval { local $| = 1; run \@cmd, \$in, \$out, \$err, timeout( 3, exception => 'timeo +ut' ); }; print "Timed out...\n\n" if $@ =~ /timeout/; print "ERROR: $err\n\n" if $err; chomp($out) && print "Output: $out\n" if $out; print "Expected output: ", param('out') if param('out');

It's slightly edited, removed the lines not related to the problem.

Update 2:

Sorry, I think it's all my fault:

chomp($out) && print "Output: $out\n" if $out;

This is where the problem lies...after removing chomp($out) &&, things back to normal again. Now I don't know what to say or explain....

A letter to NodeReaper:
The connection here was kinda weird on my attempt to send replies to this node.
I could reach the preview page at a good speed, but when I did the real submission, things became very slow, and finally I got a ``content-length: 0'' on my Opera window...
I think that's why you got many empty nodes. It's okay now.

Replies are listed 'Best First'.
Re: Get output after running IPC::Run
by Khen1950fx (Canon) on Nov 23, 2009 at 08:02 UTC
    IPC::Run runs "system" commands. They are typically executables found in one of the bins. In the absense of any workable code, all I can do is recommend that you make your little program executable and place it where it can be found. Also, your printf statement should print out something, whether or not there's a newline.
Re: Get output after running IPC::Run
by cdarke (Prior) on Nov 23, 2009 at 11:08 UTC
    You are probably suffering from buffering. Most implementations use line-buffering, so the buffer will not be flushed from C without the "\n".
    In Perl: local $|=1; or in your C: fflush(stdout);

      Hi cdarke,
      I've already added those to both of my programs, but the trick didn't work.

      More details: my Perl script is running under mod_perl2, what the script do, is accepting C source code uploading
      and compile & run it on-the-fly, send the input to the generated executable through ``$in'' and grab the output via ``$out''.

      The only problem I have is I can't get the output without the "\n", so I was wondering if there's a way to do it.

      To Khen1950fx, thanks for the response.

      I've submitted my reply many times but failed in this afternoon...

        accepting C source code uploading and compile & run it on-the-fly

        I sure hope there's some kind of sandbox. It wouldn't take very many lines of C to ruin your whole day.

Re: Get output after running IPC::Run
by zentara (Cardinal) on Nov 23, 2009 at 13:09 UTC
    is there any way to get all the output generated by the C program regardless of the ending newline character

    you could use IPC::Open3 and use sysread.... are you stuck using IPC::Run?.... see IPC::Run3 example for a different module example

    ...you are not stuck with IPC::Run.... there may be a better module for your purpose.... see IPC3 buffer limit problem too


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku
Re: Get output after running IPC::Run
by ikegami (Patriarch) on Nov 23, 2009 at 18:23 UTC
    That makes no sense. run doesn't care at all about line endings.
    use strict; use warnings; use IPC::Run qw( run ); my @cmd = ( perl => ( -e => 'print "x" x 100_000', ) ); run \@cmd, \'', \my $out, \my $err or die("Error returned by $cmd[0]: $?\n"); print("Receveived ", length($out), " chars\n");
    $ perl a.pl Receveived 100000 chars

    What don't you start by doing some error checking? What does run return? What does $? contain after run? Are you getting an exception from run or from the timeout?

      You are right...
      Everybody who still keeps an eye on this problem, please take a glance at update 2.
      Greatly thank you all for helping.

Re: Get output after running IPC::Run
by ikegami (Patriarch) on Nov 24, 2009 at 04:01 UTC

    Re update 2,

    chomp returns what it chomped, if anything. Since the string doesn't end with a newline (the content of $/), chomp returns an empty string or something equally false.

    So adjust $/ if you want to chomp something other than newlines. But even then, it makes no sense to check what chomp returns. Use

    chomp($out), print "Output: $out\n" if $out;
    or the saner
    if ($out) { chomp($out); print "Output: $out\n"; }

    Actually, why is the chomp conditional?

    chomp($out); print "Output: ", length($out) ? $out : "[nothing]", "\n";

      Hi,

      In the wrong previous revision of my code, ``&&'' is used mistakenly. Its actual meaning is ``,''.
      Realized what's wrong, I fixed my code. Also, thanks very much for the third one, it's much better.

      Thanks again.