Temporarily close stdout?

J

Joakim Hove

[ This question is about closing/reopening/... of stdout - I hope that
is on topic?]

Hello,

I have written a program in C; this programs uses an external
proprietary library. When calling a certain function in the external
library, the particular function writes a message to stdout. I am not
particularly interested in this message, and would like to silence it
- however I do not know how to do it. (I stdout and stderr my self, so
just redirecting into oblivion is not an option).

An excerpt of the code looks like this:


....
/* Offending call in external library. */
job_nr = lsb_submit( &request , &reply);


When this code is run - the offending function (or some function it
calls), writes
"Job <123456> is submitted to queue <common>"

An information I am completely uninterested in sending stdout. So I
wondered if it would be possible to do something like this:


....
/* Temporarily close stdout: */
fclose(stdout);
job_nr = lsb_submit( &request , &reply );
/* Reopen stdout */
stdout = fdopen(1 , "a");

I have tried the code listed above - but the fdopen() failed with "Bad
file descriptor" (I had not expected it to succeed ...). Anyway - any
suggestions would be highly appreciated.


Joakim
 
W

Willem

Joakim wrote:
) [ This question is about closing/reopening/... of stdout - I hope that
) is on topic?]
)
) Hello,
)
) I have written a program in C; this programs uses an external
) proprietary library. When calling a certain function in the external
) library, the particular function writes a message to stdout. I am not
) particularly interested in this message, and would like to silence it
) - however I do not know how to do it. (I stdout and stderr my self, so
) just redirecting into oblivion is not an option).
) ....
) /* Temporarily close stdout: */
) fclose(stdout);
) job_nr = lsb_submit( &request , &reply );
) /* Reopen stdout */
) stdout = fdopen(1 , "a");
)
) I have tried the code listed above - but the fdopen() failed with "Bad
) file descriptor" (I had not expected it to succeed ...). Anyway - any
) suggestions would be highly appreciated.

Given that you're using fdopen(), the dup() function is probably
available to you, and I think it could be of use.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
R

Richard Tobin

Joakim Hove said:
/* Temporarily close stdout: */
fclose(stdout);
job_nr = lsb_submit( &request , &reply );
/* Reopen stdout */
stdout = fdopen(1 , "a");

I don't think there's any standard C way to to what you want.

It looks as if you're using something Posix-like. The fclose(stdout)
will have closed the underlying file descriptor (1), so your fdopen()
doesn't work. As someone else said, you could use dup() to keep a
copy of it. But standard C doesn't let you assign to stdout; I'm not
sure whether Posix does. I have a vague recollection of some systems
providing fdreopen(), but it doesn't seem to be standard. You could
fdopen() a new FILE *, and use that instead of stdout in your code,
or if you have /dev/fd you could use freopen() on /dev/fd/N, where N
is what you got back from dup().

But closing stdout is dubious in the first place. Are you sure the
library won't complain about stdout being closed? It would be better
to freopen() stdout to /dev/null.

-- Richard
 
J

Joakim Hove

Thank you for answering.

[I have looked at the dup/dup2 calls, I agree that these seem to be
useful for me, but those man-pages are just above my limit I am
afraid.]
It looks as if you're using something Posix-like.  

That is right.
But closing stdout is dubious in the first place.  Are you sure the
library won't complain about stdout being closed?

Yes - I was also uncomfortable with that. I had no strong will to
close() stdout, it was merely a suggestion on my behalf.
It would be better to freopen() stdout to /dev/null.

I have tried:

....
/* Temporarily redirect stdout -> /dev/null */
stdout = freopen("/dev/null" , "w" , stdout);

/* Offending call */
lsb_submit( &request , &reply );

/* restore stdout */
stdout = freopen("/dev/stdout" , "w" , stdout);

But - the last freopen() fails with 2:No such file or directory.

Suggestions?

Joakim
 
R

Richard Tobin

Joakim Hove said:
/* Temporarily redirect stdout -> /dev/null */
stdout = freopen("/dev/null" , "w" , stdout);

Don't assign the result to stdout. freopen() changes stdout itself.
/* restore stdout */
stdout = freopen("/dev/stdout" , "w" , stdout);
But - the last freopen() fails with 2:No such file or directory.

Probably it closes stdout before trying to open /dev/stdout.

The dup() approach with /dev/fd would be something like (not tested):

char buf[20];
int saved_stdout = dup(1);

freopen("/dev/null", "w", stdout);
lsb_submit( &request , &reply );
sprintf(buf, "/dev/fd/%d", saved_stdout);
freopen(buf, "w", stdout);

To avoid dup(), but still relying on /dev/stdout, do

FILE *mystdout = fopen("/dev/stdout", w);
freopen("/dev/null", "w", stdout);

and change your code to write to write to mystdout instead of stdout.

You'd be wise to ask in a unix, linux or posix newsgroup, because
there may be subtleties to the workings of /dev/stdout and /dev/fd/.

-- Richard
 
J

Joakim Hove

Thanks a lot:
The dup() approach with /dev/fd would be something like (not tested):

    char buf[20];
    int saved_stdout = dup(1);

    freopen("/dev/null", "w", stdout);
    lsb_submit( &request , &reply );
    sprintf(buf, "/dev/fd/%d", saved_stdout);
    freopen(buf, "w", stdout);

Worked like charm :)

Joakim
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top