mirror of
https://github.com/ksherlock/TwoTerm.git
synced 2025-01-09 15:32:56 +00:00
Thread to monitor child.
git-svn-id: svn://qnap.local/TwoTerm/trunk@1998 5590a31f-7b70-45f8-8c82-aa3a8e5f4507
This commit is contained in:
parent
c253bec21c
commit
91878398b4
44
ChildMonitor.h
Normal file
44
ChildMonitor.h
Normal file
@ -0,0 +1,44 @@
|
||||
//
|
||||
// ChildMonitor.h
|
||||
// 2Term
|
||||
//
|
||||
// Created by Kelvin Sherlock on 1/16/2011.
|
||||
// Copyright 2011 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
/*
|
||||
* An NSThread to monitor a pid and fd.
|
||||
* requires 10.5+
|
||||
*
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class ChildMonitor;
|
||||
|
||||
@protocol ChildMonitorDelegate
|
||||
|
||||
-(void)childDataAvailable: (ChildMonitor *)monitor;
|
||||
-(void)childFinished: (ChildMonitor *)monitor;
|
||||
|
||||
@end
|
||||
|
||||
@interface ChildMonitor : NSThread {
|
||||
|
||||
pid_t _childPID;
|
||||
int _fd;
|
||||
int _childStatus;
|
||||
BOOL _childFinished;
|
||||
|
||||
id<ChildMonitorDelegate> _delegate;
|
||||
|
||||
}
|
||||
|
||||
@property (assign) BOOL childFinished;
|
||||
@property (assign) int childStatus;
|
||||
@property (nonatomic, assign) pid_t childPID;
|
||||
@property (nonatomic, assign) int fd;
|
||||
|
||||
@property (nonatomic, assign) id<ChildMonitorDelegate> delegate;
|
||||
|
||||
@end
|
98
ChildMonitor.m
Normal file
98
ChildMonitor.m
Normal file
@ -0,0 +1,98 @@
|
||||
//
|
||||
// ChildMonitor.m
|
||||
// 2Term
|
||||
//
|
||||
// Created by Kelvin Sherlock on 1/16/2011.
|
||||
// Copyright 2011 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ChildMonitor.h"
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <sys/select.h>
|
||||
#include <signal.h>
|
||||
|
||||
@implementation ChildMonitor
|
||||
|
||||
@synthesize childFinished = _childFinished;
|
||||
@synthesize childStatus = _childStatus;
|
||||
@synthesize childPID = _childPID;
|
||||
@synthesize fd = _fd;
|
||||
@synthesize delegate = _delegate;
|
||||
|
||||
-(BOOL)wait
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
if (waitpid(_childPID, &status, WNOHANG) == _childPID)
|
||||
{
|
||||
[self setChildStatus: status];
|
||||
[self setChildFinished: YES];
|
||||
|
||||
[(NSObject *)_delegate performSelectorOnMainThread: @selector(childFinished:)
|
||||
withObject: self
|
||||
waitUntilDone: NO];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(void)main
|
||||
{
|
||||
int fd = _fd;
|
||||
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int n;
|
||||
|
||||
struct timeval tm;
|
||||
|
||||
fd_set read_set;
|
||||
fd_set error_set;
|
||||
|
||||
|
||||
if ([self isCancelled]) break;
|
||||
|
||||
|
||||
FD_ZERO(&read_set);
|
||||
FD_SET(fd, &read_set);
|
||||
FD_ZERO(&error_set);
|
||||
FD_SET(fd, &error_set);
|
||||
|
||||
// 10 second timeout...
|
||||
tm.tv_sec = 10;
|
||||
tm.tv_usec = 0;
|
||||
|
||||
n = select(fd + 1, &read_set, NULL, &error_set, &tm);
|
||||
|
||||
if (n == 0) continue;
|
||||
if (n < 0) break;
|
||||
|
||||
if (FD_ISSET(fd, &error_set)) break;
|
||||
// ?
|
||||
|
||||
if (FD_ISSET(fd, &read_set))
|
||||
{
|
||||
[_delegate childDataAvailable: self];
|
||||
}
|
||||
|
||||
if ([self wait]) break;
|
||||
|
||||
}
|
||||
|
||||
if (!_childFinished) [self wait];
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc {
|
||||
|
||||
if (!_childFinished) kill(_childPID, 9);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
Loading…
x
Reference in New Issue
Block a user