Reputation: 122493
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
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
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
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