in reply to Re^2: Really, really suffering from buffering
in thread Really, really suffering from buffering

It makes no difference whether you call fputs() from XS code or via a wrapper of an external library function - fputs() lives in the stdio implementation and does the same for both XS and library code.

And since stdio has its own ideas about buffering, I guess the safest thing to do is calling fflush() as you did. All that with much handwaving, since I'm not proficient with C.

I remember having read remarks and caveats wrt to stdio, and advice to use the PerlIO layer instead. Sorry for being too lazy to delve into docs/sources to bring up those bits... maybe another monk has them present? - thanks ;)

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
  • Comment on Re^3: Really, really suffering from buffering

Replies are listed 'Best First'.
Re^4: Really, really suffering from buffering
by syphilis (Archbishop) on Nov 20, 2007 at 00:14 UTC
    It makes no difference whether you call fputs() from XS code or via a wrapper of an external library function

    On win32, at least, there's certainly a difference - in that things get even worse if you call fputs() directly from XS code. The following compiles but there's a runtime error that results in a pop-up telling me that "perl.exe has stopped working". Probably a segfault:
    use warnings; use Inline C => <<'EOC'; void foo() { fputs("hello world", stdout); } EOC foo();
    I remember having read remarks and caveats wrt to stdio, and advice to use the PerlIO layer instead

    Yes (eg perldoc perlclib) ... but the C library function still expects a FILE* (not PerlIO*) as an argument, and it's still going to do an fputs(), so I'm pessimistic about the chances of that being helpful.

    Cheers,
    Rob
        Hi BrowserUK,

        I had missed that final post of yours to the thread Inline C: using stderr segfaults?. I think you've got down to a level that I'd like to stay well clear of :-)

        Incidentally, as regards *your* thread, did it make any difference if you rewrote test2() to use the perl abstraction layer ?
        void test2 ( char* text ) { PerlIO_printf( PerlIO_stderr(), "Got:'%s'\n", text ); }
        As you say, the problems that you faced there may well be related to the problems I've been looking at - though I still have this notion that (at least part of) your problem might arise from the involvement of *2* C runtime libraries.

        As for my particular issue, the following (somewhat kludgy) workaround seems to work reliably without any need to turn on $| ... though I haven't yet tried it on anything other than Win32:
        use warnings; use strict; use Inline C => Config => INC => '-IC:/_32/C', LIBS => '-LC:/_32/C -lmylib', BUILD_NOISY => 1; use Inline C => <<'EOC'; #include <mylib.h> void _foo(PerlIO * stream) { FILE * stdio_stream = PerlIO_exportFILE(stream, NULL); my_puts(stdio_stream); fflush(stdio_stream); PerlIO_releaseFILE(stream, stdio_stream); } void _foo2(PerlIO * stream, SV * suffix) { FILE * stdio_stream = PerlIO_exportFILE(stream, NULL); my_puts(stdio_stream); fflush(stdio_stream); PerlIO_releaseFILE(stream, stdio_stream); PerlIO_printf(stream, "%s", SvPV_nolen(suffix)); PerlIO_flush(stream); } EOC for(1 .. 2) { foo(*stdout, "\nhello from perl\n"); } for(1 .. 2) { foo(*stderr); print "\nhello from perl\n"; } sub foo { if(@_ == 1) { _foo($_[0]) } elsif(@_ == 2) { _foo2($_[0], $_[1]) } else {die "Wrong no. of args to foo" } }
        Cheers,
        Rob