libs-base/Tests/base/NSURL/Helpers/Launch.h
Richard Frith-Macdonald 5fd4dd1f16 Add interface for category ... needed on sme architectures in order to
get argumentds passed correctly.
2023-07-10 21:39:49 +01:00

90 lines
2.1 KiB
Objective-C

/* Code to start up a helper and wait for it to confirm it's ready to proceed
* The helper must write someting to stdout to indicate its readiness.
*/
#if GNUSTEP
@interface HelperListener : NSObject
{
@public
BOOL done;
BOOL active;
}
- (void) helperRead: (NSNotification*)n;
@end
@implementation HelperListener
- (void) helperRead: (NSNotification*)n
{
NSDictionary *u = [n userInfo];
NSData *d;
d = [u objectForKey: NSFileHandleNotificationDataItem];
if ([d length] > 0)
{
active = YES;
}
done = YES;
}
@end
@interface NSTask (TestHelper)
+ (NSTask*) launchedHelperWithLaunchPath: (NSString*)_path
arguments: (NSArray*)_args
timeout: (NSTimeInterval)_wait;
@end
@implementation NSTask (TestHelper)
+ (NSTask*) launchedHelperWithLaunchPath: (NSString*)_path
arguments: (NSArray*)_args
timeout: (NSTimeInterval)_wait
{
NSTask *t = [NSTask new];
ENTER_POOL
NSNotificationCenter *c = [NSNotificationCenter defaultCenter];
NSPipe *p = [NSPipe pipe];
NSFileHandle *h = [p fileHandleForReading];
HelperListener *l = AUTORELEASE([HelperListener new]);
NSDate *d;
if (_wait <= 0.0)
{
_wait = 5.0;
}
d = [NSDate dateWithTimeIntervalSinceNow: _wait];
[t setLaunchPath: _path];
[t setArguments: _args];
[t setStandardOutput: p];
[t launch];
[c addObserver: l
selector: @selector(helperRead:)
name: NSFileHandleReadCompletionNotification
object: h];
[h readInBackgroundAndNotify];
while (NO == l->done && [d timeIntervalSinceNow] > 0.0)
{
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode
beforeDate: d];
}
[c removeObserver: l
name: NSFileHandleReadCompletionNotification
object: h];
[h closeFile];
if (NO == l->done)
{
NSLog(@"Helper task %@ failed to start up in time.", _path);
[t terminate];
[t waitUntilExit];
t = nil;
}
else if (NO == l->active)
{
NSLog(@"Helper task %@ failed to start (and ended).", _path);
[t terminate];
[t waitUntilExit];
t = nil;
}
LEAVE_POOL
return AUTORELEASE(t);
}
@end
#endif /* GNUSTEP */