Merge pull request #251 from gnustep/nstask_updates

This commit is contained in:
Gregory Casamento 2022-06-17 02:21:22 -04:00 committed by GitHub
commit e835725b86
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 116 additions and 15 deletions

View file

@ -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
/**

View file

@ -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