How to silence printf called from within a Ruby C extension? - c

I am running a Ruby gem which relies on a C extension (not a call to system).
The C code makes several calls to printf.
I want to silence the output of these calls.
Changing Ruby's STDOUT (example) or STDERR does not prevent the text from being output.
Is it possible to do this without modifying the C code? If so, how?

Someone originally commented on my post suggesting to use IO.reopen. This worked for me. The person has unfortunately since deleted his/her comment, so I'm posting the more detailed function I used in the end:
def silence_stdout(log = '/dev/null')
old = $stdout.dup
$stdout.reopen(File.new(log, 'w'))
yield
$stdout = old
end
Usage:
silence_stdout { foo } # Won't be displayed, won't be logged.
silence_stdout('log.txt') { barĀ } # Won't be displayed, logged in log.txt.

It is possible that Ruby is printing to stderr instead of stdout, which is why changing Ruby's stdout doesn't fix your problem.
(Both stderr and stdout typically go to the console.)
Try redirecting stderr. As I recall it'd be: myprogram 2> /dev/null

If you have access to the C source code:
#define printf(...)
This macro form is a C99 variadic macro.

Related

Perl CGI with C Wrapper

Basis of the problem. I have a university assignment requiring me to write a Perl/CGI based website for a phonebook. This part is fine and I'm happy with it, however, I have issues with wrapping the cgi files. I've done it once before no issues but been unable to replicate that success this time doing the same thing.
Basic Perl file to show user ID's:
#!/usr/bin/perl -w
use English;
print "Content-type: text/html";
print "\n";
print "\n";
print "\n";
print "<html>\n";
print "<head><title>IDS.CGI</title></head>\n";
print "<body>\n";
print "<p>\nMy User ID is $UID\n</p>";
print "<p>\nMy effective User ID is $EUID\n</p>";
print "<p>\nMy Group ID is $GID\n</p>";
print "<p>\nMy effective Group ID is $EGID\n</p>";
print "\n</body>\n";
print "</html>\n";
Wrapper.C:
#include <stdio.h>
#include <unistd.h>
#define REAL_PATH "ids.pl"
int
main()
{
execl( REAL_PATH, REAL_PATH, 0 );
printf( "You should never see this message!\n" );
}
This is throwing an internal server error 500. I've tried my best to debug it including spacing for the headers etc. It runs fine in terminal but not in the web browsers. The servers httpd error log shows that the error of "Premature end of headers". I cannot see how there is a premature end however.
Any help anyone can offer would be greatly appreciated.
Like any system call, you should always be checking for an error from execl(). Normally you'd look at the return value, but it's not necessary because success will terminate the program.
execl( REAL_PATH, REAL_PATH, 0 );
perror("exec of '"REAL_PATH"' failed");
This uses perror to handle turning errno into a human readable error string and printing it to stderr.
I'd also avoid using #define for string constants, they're awkward to work with. Instead use static const char REAL_PATH[] = "ids.pl" as suggested in this answer.
And I don't understand why you need a C wrapper. Some sort of weird restriction on your web server running interpreted code?
I wasn't compiling the C Wrapper on the actual server therefore getting different machine codes which weren't compatible. Unfortunately, the server denied to compile it originally and I forgot when it did that it had to be compiled on that machine. Doh me!

Difference between error function and printf function

First of all, sorry if someone already asked about this question.
I did search about this first, but couldn't find one.
I used to see some people doing something like this:
if ( // a certain conditions here ) {
error("ERROR: not bla bla bla")
}
what is error(....)? What is the difference with printf()?
Why they aren't using printf("ERROR: not bla bla bla") instead?
Thank you.
As i know, c language has no function name "error". I think that is a function or a macro is coded or defined by user.
To handle error in c, you can read this link. It has some different points with printf function.
http://www.tutorialspoint.com/cprogramming/c_error_handling.htm
Take a look of standard streams, which includes stdin (for input), stdout for output, and stderr for error messages. Usually stdout and stderr are just terminal output, so there are no differences. However, the output can be redirected to a text file while all error messages are still available output.
Also have look at this question perror vs frintf(stderr..), which gives you a better idea as to why perror should be used.

using STDOUT from within gdb

I have a function that pretty prints a data structure, its function prototype is:
void print_mode(FILE *fp, Mode *mode);
the FILE* allows you to redirect the output to anywhere you want, e.g. stdout, stderr, a file etc. Mode is the data structure
I am trying to call this function from within gdb and want the output to be directed to the gdb console window, stdout?
I have tried:
(gdb) p print_mode(STDOUT,fragment_mode)
No symbol "STDOUT" in current context.
(gdb) p print_mode(stdout,fragment_mode)
$17 = void
neither of which work
any ideas how i can get the output of the function to display in the gdb console?
should add - I am using gdb within emacs 24.2.1 under linux
STDOUT seems to be macro, which is not know to GDB, as handled prior to compilation by the pre-preprocessor.
Using stdout should do the job.
However the function print_mode() simply does not seem to print out anything.
In terms what's being printed to the console by the program being debugged, GDB's commands printand call should not make a difference.
For details on this you might like to read here: https://sourceware.org/gdb/onlinedocs/gdb/Calling.html
An issue might be that stdout by default is line buffered, so output would not occur before detecting a linefeed and print_mode() perhaps does not send a linefeed (\n).
To test this just use stderr as output file, as the latter isn't buffered:
p print_mode(stderr, fragment_mode)
Oh dear - silly mistake. You're right, stdout does do the job.
I forgot that having upgraded from emacs 23 to 24, the way gdb works has changed in as much as it now opens a separate buffer *input/output of program-name* to which it redirects the output of the program being debugged. In the prior version of emacs it was all displayed in the same, single gdb buffer.
So my second attempt was actually working, I was just looking in the wrong place so didn't see the output

Suppress C warning messages in R

I am calling an R function from the R package e1071 which is interfaced with libsvm (a C program). This function is passing C (printf) warning messages to the R console. I know this because the warning messages are of the form (warning:...) whereas R warning messages are capitalized (i.e. Warning:...).
I've tried everything to get rid of these messages in R (sink, suppressWarnings, invisible) but nothing seems to work.
Any ideas?
Thanks!
The function uses stdio instead of Rprintf/REprintf or warning which is why re-direction of the R output won't work. The proper solution is to fix the calls in libsvm to use R output instead.
Hacking the stdio output is possible - you can re-direct the output to your own pipe and do what you want with it, but a) it's a bit of work in C and b) it's dangerous because you need to restore the standard behavior after you're done with the function - even if it errors out and c) in may interact with R output if used on a shell.
If you want a really whacky, dirty yet quick solution, run your function in collect(parallel(..., silent=TRUE))[[1]] from multicore - it suppresses stdout (you can add multicore:::closeStderr() if you want to suppress stderr as well).

How to redirect linker errors without using redirection operator?

[This question is not about fixing the error. But about redirecting it]
I have a program (C/linux) which displays error on the console due to missing shared library. It says "can't load library ...." . How can I redirect this output into a file ?
I tried this inside my program:
close(2);
open("/home/user/test.txt", O_CREAT|O_RDWR);
It correctly redirects the output generated from the program printfs. But the "can't load library ...." still comes on console!
I don't want to use the > operator for this purpose. I want to do it from inside my program. Any suggestions?
Thanks
The error message is generated by the loader, which happens before the program even starts. So there's nothing you can do from within a program that doesn't even get to run to influence the behaviour of the loader.
If you really need to fiddle with the file descriptors used by the shell, check out the exec shell command to close and redirect file descriptors permanently. That way you can get around using the redirection operator >, although that's arguably a far less tidy approach.
You will need a wrapper program. It could be a shell script. Do the redirection then try to run the original program.
A program cannot catch errors that happen to it before it even starts running. Library link happens before any other code runs.
Seems like the message is generated before your program starts - so to redirect it, you'll have to use the 2> operator. Otherwise you'll have to use the dlopen... etc. calls to do the linking on runtime.
try making sure that the environment variable LD_LIBRARY_PATH is correct.
that warnings & error mesages comes befor your program starts to work so only option is > operator
use this way
./a.out >& filename

Resources