blob: 562f094099b6848c41c9ea0b6d01ffb074c87866 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
/**
* @file
* @date 17.5.2007
*
* Interface of class HBOutputRedirect.
*/
#import <Cocoa/Cocoa.h>
/**
* This class is used to redirect @c stdout and @c stderr outputs. It is never
* created directly; @c stdoutRedirect and @c stderrRedirect class methods
* should be use instead.
*
* @note Redirection is done by replacing @c _write functions for @c stdout and
* @c stderr streams. Because of this messages written by NSLog(), for
* example are not redirected. I consider this a good thing, but if more
* universal redirecting is needed, it can be done at file descriptor
* level.
*/
@interface HBOutputRedirect : NSObject
{
/// Set that contains all registered listeners for this output.
NSMutableSet *listeners;
/// Selector that is called on listeners to forward the output.
SEL forwardingSelector;
/// Output stream (@c stdout or @c stderr) redirected by this object.
FILE *stream;
/// Pointer to old write function for the stream.
int (*oldWriteFunc)(void *, const char *, int);
NSLock *lock;
}
+ (id)stdoutRedirect;
+ (id)stderrRedirect;
- (void)addListener:(id)aListener;
- (void)removeListener:(id)aListener;
@end
/* Here is another technique to redirect stderr, but it is done at lower level
which also redirects NSLog() and other writes that are done directly to the
file descriptor. This method is not used by HBOutputRedirect, but should
be easy to implement if needed. Code is untested, but this is shows basic
idea for future reference.
// Create a pipe
NSPipe *pipe = [[NSPipe alloc] init];
// Connect stderr to the writing end of the pipe
dup2([[pipe fileHandleForWriting] fileDescriptor], STDERR_FILENO);
// Get reading end of the pipe, we can use this to read stderr
NSFileHandle *fh = [pipe fileHandleForReading];
*/
|