我通过编写一个实用程序类来解决这个问题,该实用程序类将文件描述符重定向到文件并能够重置此重定向:
@interface IORedirector : NSObject
- (instancetype)initWithFileDescriptor:(int)fileDescriptor targetPath:(NSURL *)fileURL flags:(int)oflags mode:(mode_t)mode;
- (void)reset;
@end
@implementation IORedirector
{
int _fileDescriptor;
int _savedFileDescriptor;
}
- (instancetype)initWithFileDescriptor:(int)fileDescriptor targetPath:(NSURL *)fileURL flags:(int)oflags mode:(mode_t)mode
{
_savedFileDescriptor = dup(fileDescriptor);
if (_savedFileDescriptor == -1) {
NSLog(@"Could not save file descriptor %d: %s", fileDescriptor, strerror(errno));
return nil;
}
int tempFD = open(fileURL.path.fileSystemRepresentation, oflags, mode);
if (tempFD == -1) {
NSLog(@"Could not open %@: %s", fileURL.path, strerror(errno));
close(_savedFileDescriptor);
return nil;
}
if (close(fileDescriptor) == -1) {
NSLog(@"Closing file descriptor %d failed: %s", fileDescriptor, strerror(errno));
close(_savedFileDescriptor);
close(tempFD);
return nil;
}
if (dup2(tempFD, fileDescriptor) == -1) {
NSLog(@"Could not replace file descriptor %d with new one for %@: %s", fileDescriptor, fileURL.path, strerror(errno));
close(_savedFileDescriptor);
close(tempFD);
return nil;
}
_fileDescriptor = fileDescriptor;
close(tempFD);
return self;
}
- (void)dealloc
{
[self reset];
}
- (void)reset
{
if (_savedFileDescriptor == -1) return;
if (close(_fileDescriptor) == -1) {
NSLog(@"Closing file descriptor %d failed: %s", _fileDescriptor, strerror(errno));
return;
}
if (dup2(_savedFileDescriptor, _fileDescriptor) == -1) {
NSLog(@"Could not restore file descriptor %d: %s", _fileDescriptor, strerror(errno));
return;
}
close(_savedFileDescriptor);
_savedFileDescriptor = -1;
}
@end
Run Code Online (Sandbox Code Playgroud)
初始化程序要么返回一个有效的实例(已建立重定向),要么返回nil。立即致电reset恢复重定向。
初始化程序 和 都reset可能失败并“丢失”原始文件描述符,但窗口很小且不太可能。这可能仅在多线程应用程序中使用此类时相关(我不这样做),因此如果您打算在多线程环境中使用它,您需要确保一次只有一个初始化程序或reset可以使用全局变量运行互斥锁什么的。
使用这个类(当然,我有一个单独的测试用例),我可以重定向STDERR_FILENO到一个文件,从而捕获NSLog. 这样我就可以测试未修改的日志记录类。
创建临时文件的合适路径留给读者作为练习。
| 归档时间: |
|
| 查看次数: |
1525 次 |
| 最近记录: |