Yu Hao
Yu Hao

Reputation: 122493

Is there a way to close output of stderr in one thread but not others?

Say my program has some threads, since the file descriptors are shared among the threads, if I call close(stderr), all the threads won't output to stderr. my question: is there a way to shut down the output of stderr in one thread, but not the others?

To be more specific, one thread of my program calls a third party library function, and it keeps output warning messages which I know are useless. But I have no access to this third party library source.

Upvotes: 1

Views: 237

Answers (3)

Jonathan Leffler
Jonathan Leffler

Reputation: 754820

No. File descriptors are global resources available to all threads in a process. Standard error is file descriptor number 2, of course, so it is a global resource and you can't stop the third party code from writing to it.

If the problem is serious enough to warrant the treatment, you can do:

int fd2_copy = dup(2);
int fd2_null = open("/dev/null", O_WRONLY);

Before calling your third-party library function:

dup2(fd2_null, 2);
third_party_library_function();
dup2(fd2_copy, 2);

Basically, for the duration of the third-party library, switch standard error to /dev/null, reinstating the normal output after the function.

You should, of course, error check the system calls.

The downside of this is that while this thread is executing the third party function, any other thread that needs to write to standard error will also write to /dev/null.

You'd probably have to think in terms of adding an 'error writing thread' (EWT) which can be synchronized with the 'third-party library executing thread' (TPLET). Other threads would write a message to the EWT. If the TPLET was executing the third-party library, the EWT would wait until it was done, and only then write any queued messages. (While that would 'work', it is hard work.)

One way around this would be to have the error reporting functions used by the general code (other than the third-party library code) write to fd2_copy rather than standard error per se. This would require a disciplined use of error reporting functions, but is a whole heap easier than an extra thread.

Upvotes: 3

caf
caf

Reputation: 239321

On Linux it is possible to give the current thread its own private file descriptor table, using the unshare() function declared in <sched.h>:

unshare(CLONE_FILES);

After that call, you can call close(2); and it will affect only the current thread.

Note however that once the file descriptor table is unshared, you can't go back to sharing it again - it's a one-way operation. This is also Linux-specific, so it's not portable.

Upvotes: 2

Rohan
Rohan

Reputation: 53386

stderr is per process not per thread, so closing it will close for all threads.

If you want to skip particular messages, may be you can use grep -v.

Upvotes: 2

Related Questions