improve NSTask

This commit is contained in:
Glenn Ganz 2014-03-06 16:29:51 +01:00
parent 873730a27e
commit 578de96d6e
6 changed files with 51 additions and 20 deletions

View File

@ -21,8 +21,6 @@ FOUNDATION_EXPORT NSString * const NSTaskDidTerminateNotification;
id standardInput;
id standardOutput;
id standardError;
BOOL isRunning;
}
+(NSTask *)launchedTaskWithLaunchPath:(NSString *)path arguments:(NSArray *)arguments;

View File

@ -41,8 +41,7 @@ NSString * const NSTaskDidTerminateNotification=@"NSTaskDidTerminateNotification
standardInput=nil;
standardOutput=nil;
standardError=nil;
isRunning=NO;
}
}
return self;
}
@ -125,7 +124,8 @@ NSString * const NSTaskDidTerminateNotification=@"NSTaskDidTerminateNotification
}
-(BOOL)isRunning {
return isRunning;
NSInvalidAbstractInvocation();
return NO;
}
-(void)interrupt {
@ -152,10 +152,10 @@ NSString * const NSTaskDidTerminateNotification=@"NSTaskDidTerminateNotification
}
-(void)waitUntilExit {
while(isRunning) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
}
while([self isRunning]) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
}
}
-(int)processIdentifier {

View File

@ -16,6 +16,7 @@ void waitForTaskChildProcess();
}
-(void)launch;
-(BOOL)isRunning;
-(void)terminate;
-(void)setTerminationStatus:(int)terminationStatus;

View File

@ -100,7 +100,7 @@ void childSignalHandler(int sig) {
}
-(void)launch {
if (isRunning) {
if ([self isRunning]) {
[NSException raise:NSInvalidArgumentException
format:@"NSTask already launched"];
}
@ -206,9 +206,6 @@ void childSignalHandler(int sig) {
exit(-1);
}
else if (_processID != -1) {
isRunning = YES;
@synchronized(_liveTasks) {
[_liveTasks addObject:self];
}
@ -226,6 +223,21 @@ void childSignalHandler(int sig) {
format:@"fork() failed: %s", strerror(errno)];
}
-(BOOL)isRunning
{
if (_processID != 0) {
if (kill(_processID, 0) == 0) {
return YES;
}
else {
return NO;
}
}
else {
return NO;
}
}
-(void)terminate {
kill(_processID, SIGTERM);
@synchronized(_liveTasks) {
@ -237,7 +249,6 @@ void childSignalHandler(int sig) {
-(void)setTerminationStatus:(int)terminationStatus { _terminationStatus = terminationStatus; }
-(void)taskFinished {
isRunning = NO;
@synchronized(_liveTasks) {
[_liveTasks removeObject:self];
}

View File

@ -19,6 +19,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
}
-(void)launch;
-(BOOL)isRunning;
-(void)terminate;
-(int)processIdentifier;

View File

@ -29,8 +29,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
// private
-(void)finalizeProcess{
isRunning=NO;
if(_monitor!=nil){
[[NSRunLoop currentRunLoop] removeInputSource:_monitor forMode: NSDefaultRunLoopMode];
[_monitor setDelegate:nil];
@ -42,6 +40,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
}
}
-init {
self = [super init];
return self;
}
-(void)dealloc{
[self finalizeProcess];
[super dealloc];
@ -72,6 +76,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
}
-(void)launch {
if ([self isRunning]) {
[NSException raise:NSInvalidArgumentException
format:@"NSTask already launched"];
}
STARTUPINFO startupInfo;
if(launchPath==nil)
@ -108,9 +116,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
startupInfo.hStdError=[standardError fileHandle];
SetHandleInformation([(NSFileHandle_win32 *)[standardError fileHandleForReading] fileHandle], HANDLE_FLAG_INHERIT, 0);
ZeroMemory(& _processInfo,sizeof(_processInfo));
char *cenv = NULL, *cenvp = NULL;
if(environment != nil) {
@ -165,12 +170,27 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
if([standardError isKindOfClass:[NSPipe class]])
[[standardError fileHandleForWriting] closeFile];
isRunning=YES;
_monitor=[[NSHandleMonitor_win32 allocWithZone:NULL] initWithHandle:_processInfo.hProcess];
[_monitor setDelegate:self];
[[NSRunLoop currentRunLoop] addInputSource:_monitor forMode: NSDefaultRunLoopMode];
}
-(BOOL)isRunning
{
if ( _processInfo.hProcess != NULL) {
GetExitCodeProcess(_processInfo.hProcess, &_exitCode);
if (_exitCode == STILL_ACTIVE) {
return YES;
}
else {
return NO;
}
}
else {
return NO;
}
}
-(void)terminate {
TerminateProcess(_processInfo.hProcess,0);
}