mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 00:41:02 +00:00
Merge pull request #251 from gnustep/nstask_updates
This commit is contained in:
commit
e835725b86
2 changed files with 116 additions and 15 deletions
|
@ -36,6 +36,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
DEFINE_BLOCK_TYPE_NO_ARGS(GSTaskTerminationHandler, void);
|
||||
|
||||
@class NSThread;
|
||||
|
||||
#if OS_API_VERSION(MAC_OS_X_VERSION_10_5,GS_API_LATEST)
|
||||
|
@ -66,6 +68,7 @@ GS_EXPORT_CLASS
|
|||
BOOL _hasNotified;
|
||||
NSThread *_launchingThread;
|
||||
NSTaskTerminationReason _terminationReason;
|
||||
GSTaskTerminationHandler _handler;
|
||||
#endif
|
||||
#if GS_NONFRAGILE
|
||||
#else
|
||||
|
@ -131,6 +134,19 @@ GS_EXPORT_CLASS
|
|||
- (BOOL) usePseudoTerminal;
|
||||
- (NSString*) validatedLaunchPath;
|
||||
#endif
|
||||
|
||||
#if OS_API_VERSION(MAC_OS_X_VERSION_10_13, GS_API_LATEST)
|
||||
+ (NSTask *) launchedTaskWithExecutableURL: (NSURL *)url
|
||||
arguments: (NSArray *)arguments
|
||||
error: (NSError **)error
|
||||
terminationHandler: (GSTaskTerminationHandler)terminationHandler;
|
||||
|
||||
- (BOOL) launchAndReturnError: (NSError **)error;
|
||||
|
||||
- (NSURL *) executableURL;
|
||||
|
||||
- (NSURL *) currentDirectoryURL;
|
||||
#endif
|
||||
@end
|
||||
|
||||
/**
|
||||
|
|
115
Source/NSTask.m
115
Source/NSTask.m
|
@ -38,12 +38,13 @@
|
|||
#import "Foundation/NSMapTable.h"
|
||||
#import "Foundation/NSProcessInfo.h"
|
||||
#import "Foundation/NSRunLoop.h"
|
||||
#import "Foundation/NSLock.h"
|
||||
#import "Foundation/NSNotification.h"
|
||||
#import "Foundation/NSNotificationQueue.h"
|
||||
#import "Foundation/NSTask.h"
|
||||
#import "Foundation/NSThread.h"
|
||||
#import "Foundation/NSTimer.h"
|
||||
#import "Foundation/NSLock.h"
|
||||
#import "Foundation/NSURL.h"
|
||||
#import "GNUstepBase/NSString+GNUstepBase.h"
|
||||
#import "GNUstepBase/NSTask+GNUstepBase.h"
|
||||
#import "GSPrivate.h"
|
||||
|
@ -414,7 +415,13 @@ pty_slave(const char* name)
|
|||
*/
|
||||
- (void) launch
|
||||
{
|
||||
ASSIGN(_launchingThread, [NSThread currentThread]);
|
||||
NSError *e;
|
||||
|
||||
if (NO == [self launchAndReturnError: &e])
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"%@", e ? e : @"Unable to launch"];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -876,6 +883,49 @@ pty_slave(const char* name)
|
|||
[loop runMode: NSDefaultRunLoopMode beforeDate: limit];
|
||||
LEAVE_POOL
|
||||
}
|
||||
|
||||
// macOS 10.13 methods...
|
||||
|
||||
+ (NSTask *) launchedTaskWithExecutableURL: (NSURL *)url
|
||||
arguments: (NSArray *)arguments
|
||||
error: (NSError **)error
|
||||
terminationHandler: (GSTaskTerminationHandler)terminationHandler
|
||||
{
|
||||
NSTask *task = [self launchedTaskWithLaunchPath: [url path]
|
||||
arguments: arguments];
|
||||
task->_handler = terminationHandler;
|
||||
if (error)
|
||||
{
|
||||
*error = nil;
|
||||
}
|
||||
return task;
|
||||
}
|
||||
|
||||
- (BOOL) launchAndReturnError: (NSError **)error
|
||||
{
|
||||
ASSIGN(_launchingThread, [NSThread currentThread]);
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSURL *) executableURL
|
||||
{
|
||||
return [NSURL URLWithString: [self launchPath]];;
|
||||
}
|
||||
|
||||
- (void) setExecutableURL: (NSURL *)url
|
||||
{
|
||||
[self setLaunchPath: [url path]];
|
||||
}
|
||||
|
||||
- (NSURL *) currentDirectoryURL
|
||||
{
|
||||
return [NSURL URLWithString: [self currentDirectoryPath]];
|
||||
}
|
||||
|
||||
- (void) setCurrentDirectoryURL: (NSURL *)url
|
||||
{
|
||||
[self setCurrentDirectoryPath: [url path]];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSTask (Private)
|
||||
|
@ -918,6 +968,11 @@ pty_slave(const char* name)
|
|||
postingStyle: NSPostASAP
|
||||
coalesceMask: NSNotificationNoCoalescing
|
||||
forModes: nil];
|
||||
|
||||
if (_handler != nil)
|
||||
{
|
||||
CALL_BLOCK_NO_ARGS(_handler);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _terminatedChild: (int)status reason: (NSTaskTerminationReason)reason
|
||||
|
@ -1125,7 +1180,8 @@ quotedFromString(NSString *aString)
|
|||
}
|
||||
}
|
||||
|
||||
- (void) launch
|
||||
// 10.13 method...
|
||||
- (BOOL) launchAndReturnError: (NSError **)error
|
||||
{
|
||||
STARTUPINFOW start_info;
|
||||
NSString *lpath;
|
||||
|
@ -1146,11 +1202,20 @@ quotedFromString(NSString *aString)
|
|||
|
||||
if (_hasLaunched)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has already been launched"];
|
||||
if (error)
|
||||
{
|
||||
NSDictionary *info;
|
||||
|
||||
info = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"task has already been launched", NSLocalizedDescriptionKey, nil];
|
||||
*error = [NSError errorWithDomain: NSCocoaErrorDomain
|
||||
code: 0
|
||||
userInfo: info];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
[super launch];
|
||||
[super launchAndReturnError: error];
|
||||
|
||||
lpath = [self _fullLaunchPath];
|
||||
wexecutable = (const unichar*)[lpath fileSystemRepresentation];
|
||||
|
@ -1307,7 +1372,7 @@ quotedFromString(NSString *aString)
|
|||
(const unichar*)[[self currentDirectoryPath] fileSystemRepresentation],
|
||||
&start_info,
|
||||
&procInfo);
|
||||
if (result == 0)
|
||||
if (0 == result)
|
||||
{
|
||||
last = [NSError _last];
|
||||
}
|
||||
|
@ -1319,8 +1384,11 @@ quotedFromString(NSString *aString)
|
|||
|
||||
if (0 == result)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - Error launching task: %@ ... %@", lpath, last];
|
||||
if (error)
|
||||
{
|
||||
*error = last;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
_taskId = procInfo.dwProcessId;
|
||||
|
@ -1347,6 +1415,8 @@ quotedFromString(NSString *aString)
|
|||
[hdl closeFile];
|
||||
[toClose removeObjectAtIndex: 0];
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) _collectChild
|
||||
|
@ -1453,7 +1523,8 @@ GSPrivateCheckTasks()
|
|||
return found;
|
||||
}
|
||||
|
||||
- (void) launch
|
||||
// 10.13 method...
|
||||
- (BOOL) launchAndReturnError: (NSError **)error
|
||||
{
|
||||
NSMutableArray *toClose;
|
||||
NSString *lpath;
|
||||
|
@ -1475,11 +1546,20 @@ GSPrivateCheckTasks()
|
|||
|
||||
if (_hasLaunched)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has already been launched"];
|
||||
if (error)
|
||||
{
|
||||
NSDictionary *info;
|
||||
|
||||
info = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"task has already been launched", NSLocalizedDescriptionKey, nil];
|
||||
*error = [NSError errorWithDomain: NSCocoaErrorDomain
|
||||
code: 0
|
||||
userInfo: info];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
[super launch];
|
||||
[super launchAndReturnError: error];
|
||||
|
||||
lpath = [self _fullLaunchPath];
|
||||
executable = [lpath fileSystemRepresentation];
|
||||
|
@ -1551,8 +1631,11 @@ GSPrivateCheckTasks()
|
|||
pid = vfork();
|
||||
if (pid < 0)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - failed to create child process"];
|
||||
if (error)
|
||||
{
|
||||
*error = [NSError _last];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (pid == 0)
|
||||
{
|
||||
|
@ -1674,6 +1757,8 @@ GSPrivateCheckTasks()
|
|||
[toClose removeObjectAtIndex: 0];
|
||||
}
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) setStandardError: (id)hdl
|
||||
|
|
Loading…
Reference in a new issue