Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Re: How to capture (intercept) output (warnings) of a module

by LanX (Saint)
on Sep 05, 2020 at 07:35 UTC ( [id://11121364]=note: print w/replies, xml ) Need Help??


in reply to How to capture (intercept) output (warnings) of a module

Normally I'd recommend manipulating __WARN__ and __DIE__ in %SIG

But since this is a wrapper around a C lib you might really need to temporarily redirect STDERR and STDOUT to a variable.

See description in https://perldoc.pl/functions/open.html#Duping-filehandles if wanna do it without extra capture module.

Furthermore does the module https://metacpan.org/pod/Graphics::TIFF claim that

The Perl bindings follow the C API very closely, and the C reference documentation should be considered the canonical source.

And http://www.libtiff.org/libtiff.html#Errors offers hooks to handle errors. So you should check if it's an undocumented feature of the Perl wrapper.

HTH

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re^2: How to capture (intercept) output (warnings) of a module
by salva (Canon) on Sep 05, 2020 at 09:49 UTC
    But since this is a wrapper around a C lib you might really need to temporarily redirect STDERR and STDOUT to a variable

    That would not work unless the C lib performs IO through the PerlIO layer (instead of the usual stdio C layer), something very unlikely.

    On the other hand, libtiff provides a TIFFSetWarningHandler function just for customizing error reporting. It is not exposed by the Perl wrapper, but adding that feature shouldn't be too difficult.

      Looks like not the OP's (i.e. davidfilmer) case, but, sadly, libtiff shipped with Strawberry Perl generates warnings as ugly pop-up GUI modal boxes, requiring user interaction to dispose. Therefore, without recompilation, the solution with Capture::Tiny won't work.

      On the other hand, libtiff provides a TIFFSetWarningHandler function just for customizing error reporting. It is not exposed by the Perl wrapper, but adding that feature shouldn't be too difficult.

      Ah, then I can do it:

      use strict; use warnings; use Graphics::TIFF; my $fn = 'TIFF01.TIF'; # a file known to generate # a warning (as shown below) DummyTiffLogger::init(); Graphics::TIFF-> Open( $fn, 'r' ) for 1..5; package DummyTiffLogger { sub logMessage { my $s = shift; printf "message logged: <%s>\n", $s } use Inline C => Config => LIBS => '-ltiff'; use Inline C => <<'END_OF_C'; #define BUFSIZE 1024 void _log(char* m, char* fmt, va_list ap) { char* buf; int len; SV* sv; Newxz(buf, BUFSIZE, char); len = vsprintf(buf, fmt, ap); Renew(buf, len + 1, char); sv = newSV(0); sv_usepvn_flags(sv, buf, len, SV_SMAGIC | SV_HAS_TRAILING_NUL); dSP; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(sv)); PUTBACK; call_pv("DummyTiffLogger::logMessage", G_DISCARD); FREETMPS; LEAVE; } void init() { TIFFSetWarningHandler(&_log); } END_OF_C } # package __END__ message logged: <Unknown field with tag 32781 (0x800d) encountered> message logged: <Unknown field with tag 32781 (0x800d) encountered> message logged: <Unknown field with tag 32781 (0x800d) encountered> message logged: <Unknown field with tag 32781 (0x800d) encountered> message logged: <Unknown field with tag 32781 (0x800d) encountered>
        > Perl generates warnings as ugly pop-up GUI modal boxes,

        Isn't this dependent of the way Perl is started?

        IOW did you have an associated DOS window or did you use wperl?

        Your solution looks nice you might consider sending a patch request to the module's maintainer, such that users avoid using C.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

      I've always been under the impression that redirections are inherited to° a child process.

      But you should know better.

      > libtiff provides a TIFFSetWarningHandler function just for customizing error reporting.

      I've recommended this myself, but I'm not sure if this interface allows a Perl sub as call back.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

      °) Correction: to "bequeath", to "pass on" in correct English, "inherit" can't be used that way

        I've always been under the impression that redirections are inherited to a child process.

        Well, redirections are inherited by child processes... sometimes!

        It depends on whether the redirection target exists at the OS level or not. In practice, that means whether a OS file descriptor is associated to the Perl file handle or not.

        When you open a perl scalar as a file (as in, open my $fh, '>', \$data), no file is opened at the OS level, and no file descriptor becomes associated to the file handler. So, forked processes or just C libraries calling C stdio functions (or the OS syscalls in any other way) are not going to see it and may fail, or in the case of stderr, stdin or stdout, just use the default streams.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11121364]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (3)
As of 2024-04-18 18:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found