mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
New method to get executable paths.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@12441 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
f24a9196b0
commit
4c94e46acc
4 changed files with 393 additions and 218 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2002-02-08 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/Foundation/NSTask.h: New method -validatedLaunchPath to
|
||||
check that an executable exists at the specified path or any
|
||||
alternative version corresponding to host, OS, and library-combo
|
||||
directories. Returns the actual path to the binary.
|
||||
* Source/NSTask.m: Implemented new mathod and added autogsdoc
|
||||
comments.
|
||||
* Source/NSBundle.m: Cotrrected error in comments.
|
||||
|
||||
2002-02-06 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/Foundation/NSString.m: Additioanl method -immutableProxy
|
||||
|
|
|
@ -95,6 +95,7 @@
|
|||
|
||||
#ifndef NO_GNUSTEP
|
||||
- (BOOL) usePseudoTerminal;
|
||||
- (NSString*) validatedLaunchPath;
|
||||
#endif
|
||||
@end
|
||||
|
||||
|
|
|
@ -1243,7 +1243,7 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory)
|
|||
within the GNUstep directory structure specified by the environment
|
||||
variables. */
|
||||
|
||||
/* Return a bundle which accesses the first existing directory from the list
|
||||
/** Return a bundle which accesses the first existing directory from the list
|
||||
GNUSTEP_USER_ROOT/Libraries/Resources/libraryName/
|
||||
GNUSTEP_NETWORK_ROOT/Libraries/Resources/libraryName/
|
||||
GNUSTEP_LOCAL_ROOT/Libraries/Resources/libraryName/
|
||||
|
@ -1282,11 +1282,11 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory)
|
|||
return nil;
|
||||
}
|
||||
|
||||
/* Return a bundle which accesses the first existing directory from the list
|
||||
GNUSTEP_USER_ROOT/Tools/Resources/libraryName/
|
||||
GNUSTEP_NETWORK_ROOT/Tools/Resources/libraryName/
|
||||
GNUSTEP_LOCAL_ROOT/Tools/Resources/libraryName/
|
||||
GNUSTEP_SYSTEM_ROOT/Tools/Resources/libraryName/
|
||||
/** Return a bundle which accesses the first existing directory from the list
|
||||
GNUSTEP_USER_ROOT/Libraries/Resources/toolName/
|
||||
GNUSTEP_NETWORK_ROOT/Libraries/Resources/toolName/
|
||||
GNUSTEP_LOCAL_ROOT/Libraries/Resources/toolName/
|
||||
GNUSTEP_SYSTEM_ROOT/Libraries/Resources/toolName/
|
||||
*/
|
||||
+ (NSBundle *) bundleForTool: (NSString *)toolName
|
||||
{
|
||||
|
|
588
Source/NSTask.m
588
Source/NSTask.m
|
@ -218,6 +218,10 @@ pty_slave(const char* name)
|
|||
@end
|
||||
|
||||
|
||||
/**
|
||||
* The NSTask class provides a mechanism to run separate tasks
|
||||
* under (limited) control of your program.
|
||||
*/
|
||||
@implementation NSTask
|
||||
|
||||
+ (id) allocWithZone: (NSZone*)zone
|
||||
|
@ -250,6 +254,11 @@ pty_slave(const char* name)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and launches a task, returning an autoreleased task object.
|
||||
* Supplies the path to the executable and an array of argument.
|
||||
* The task inherits the parents environment and I/O.
|
||||
*/
|
||||
+ (NSTask*) launchedTaskWithLaunchPath: (NSString*)path
|
||||
arguments: (NSArray*)args
|
||||
{
|
||||
|
@ -281,16 +290,17 @@ pty_slave(const char* name)
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Querying task parameters.
|
||||
/**
|
||||
* Returns the arguments set for the task.
|
||||
*/
|
||||
|
||||
- (NSArray*) arguments
|
||||
{
|
||||
return _arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the working directory set for the task.
|
||||
*/
|
||||
- (NSString*) currentDirectoryPath
|
||||
{
|
||||
if (_currentDirectoryPath == nil)
|
||||
|
@ -301,6 +311,9 @@ pty_slave(const char* name)
|
|||
return _currentDirectoryPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the environment set for the task.
|
||||
*/
|
||||
- (NSDictionary*) environment
|
||||
{
|
||||
if (_environment == nil)
|
||||
|
@ -310,165 +323,13 @@ pty_slave(const char* name)
|
|||
return _environment;
|
||||
}
|
||||
|
||||
- (NSString*) launchPath
|
||||
{
|
||||
return _launchPath;
|
||||
}
|
||||
|
||||
- (id) standardError
|
||||
{
|
||||
if (_standardError == nil)
|
||||
{
|
||||
[self setStandardError: [NSFileHandle fileHandleWithStandardError]];
|
||||
}
|
||||
return _standardError;
|
||||
}
|
||||
|
||||
- (id) standardInput
|
||||
{
|
||||
if (_standardInput == nil)
|
||||
{
|
||||
[self setStandardInput: [NSFileHandle fileHandleWithStandardInput]];
|
||||
}
|
||||
return _standardInput;
|
||||
}
|
||||
|
||||
- (id) standardOutput
|
||||
{
|
||||
if (_standardOutput == nil)
|
||||
{
|
||||
[self setStandardOutput: [NSFileHandle fileHandleWithStandardOutput]];
|
||||
}
|
||||
return _standardOutput;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setting task parameters.
|
||||
*/
|
||||
|
||||
- (void) setArguments: (NSArray*)args
|
||||
{
|
||||
if (_hasLaunched)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
ASSIGN(_arguments, args);
|
||||
}
|
||||
|
||||
- (void) setCurrentDirectoryPath: (NSString*)path
|
||||
{
|
||||
if (_hasLaunched)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
ASSIGN(_currentDirectoryPath, path);
|
||||
}
|
||||
|
||||
- (void) setEnvironment: (NSDictionary*)env
|
||||
{
|
||||
if (_hasLaunched)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
ASSIGN(_environment, env);
|
||||
}
|
||||
|
||||
- (void) setLaunchPath: (NSString*)path
|
||||
{
|
||||
if (_hasLaunched)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
ASSIGN(_launchPath, path);
|
||||
}
|
||||
|
||||
- (void) setStandardError: (id)hdl
|
||||
{
|
||||
NSAssert([hdl isKindOfClass: [NSFileHandle class]] ||
|
||||
[hdl isKindOfClass: [NSPipe class]], NSInvalidArgumentException);
|
||||
if (_hasLaunched)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
ASSIGN(_standardError, hdl);
|
||||
}
|
||||
|
||||
- (void) setStandardInput: (id)hdl
|
||||
{
|
||||
NSAssert([hdl isKindOfClass: [NSFileHandle class]] ||
|
||||
[hdl isKindOfClass: [NSPipe class]], NSInvalidArgumentException);
|
||||
if (_hasLaunched)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
ASSIGN(_standardInput, hdl);
|
||||
}
|
||||
|
||||
- (void) setStandardOutput: (id)hdl
|
||||
{
|
||||
NSAssert([hdl isKindOfClass: [NSFileHandle class]] ||
|
||||
[hdl isKindOfClass: [NSPipe class]], NSInvalidArgumentException);
|
||||
if (_hasLaunched)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
ASSIGN(_standardOutput, hdl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Obtaining task state
|
||||
*/
|
||||
|
||||
- (BOOL) isRunning
|
||||
{
|
||||
if (_hasLaunched == NO)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
if (_hasCollected == NO)
|
||||
{
|
||||
[self _collectChild];
|
||||
}
|
||||
if (_hasTerminated == YES)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (int) processIdentifier
|
||||
{
|
||||
return _taskId;
|
||||
}
|
||||
|
||||
- (int) terminationStatus
|
||||
{
|
||||
if (_hasLaunched == NO)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has not yet launched"];
|
||||
}
|
||||
if (_hasCollected == NO)
|
||||
{
|
||||
[self _collectChild];
|
||||
}
|
||||
if (_hasTerminated == NO)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has not yet terminated"];
|
||||
}
|
||||
return _terminationStatus;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handling a task.
|
||||
/**
|
||||
* Sends an interrupt signal to the receiver and any subtasks.<br />
|
||||
* If the task has not been launched, raises an
|
||||
* NSInvalidArgumentException.<br />
|
||||
* Has no effect on a task that has already terminated.<br />
|
||||
* This is rather like the terminate method, but the child
|
||||
* process may not choose to terminate in response to an interrupt.
|
||||
*/
|
||||
- (void) interrupt
|
||||
{
|
||||
|
@ -491,11 +352,58 @@ pty_slave(const char* name)
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the task is currently running.
|
||||
*/
|
||||
- (BOOL) isRunning
|
||||
{
|
||||
if (_hasLaunched == NO)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
if (_hasCollected == NO)
|
||||
{
|
||||
[self _collectChild];
|
||||
}
|
||||
if (_hasTerminated == YES)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches the task.<br />
|
||||
* Raises an NSInvalidArgumentException if the launch path is not
|
||||
* set or if the subtask cannot be started for some reason
|
||||
* (eg. the executable does not exist).
|
||||
*/
|
||||
- (void) launch
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the launch path set for the task.
|
||||
*/
|
||||
- (NSString*) launchPath
|
||||
{
|
||||
return _launchPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number identifying the child process on this system.
|
||||
*/
|
||||
- (int) processIdentifier
|
||||
{
|
||||
return _taskId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a cont signal to the receiver and any subtasks.<br />
|
||||
* If the task has not been launched, raises an
|
||||
* NSInvalidArgumentException.<br />
|
||||
*/
|
||||
- (BOOL) resume
|
||||
{
|
||||
if (_hasLaunched == NO)
|
||||
|
@ -513,6 +421,180 @@ pty_slave(const char* name)
|
|||
return YES;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an array of arguments to be supplied to the task when it
|
||||
* is launched. The default is an empty array. This method cannot
|
||||
* be used after a task is launched ...
|
||||
* it raises an NSInvalidArgumentException.
|
||||
*/
|
||||
- (void) setArguments: (NSArray*)args
|
||||
{
|
||||
if (_hasLaunched)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
ASSIGN(_arguments, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the home directory in which the task is to be run.
|
||||
* The default is the parent processes directory.
|
||||
* This method cannot be used after a task is launched ...
|
||||
* it raises an NSInvalidArgumentException.
|
||||
*/
|
||||
- (void) setCurrentDirectoryPath: (NSString*)path
|
||||
{
|
||||
if (_hasLaunched)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
ASSIGN(_currentDirectoryPath, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the environment variables for the task to be run.
|
||||
* The default is the parent processes environment.
|
||||
* This method cannot be used after a task is launched ...
|
||||
* it raises an NSInvalidArgumentException.
|
||||
*/
|
||||
- (void) setEnvironment: (NSDictionary*)env
|
||||
{
|
||||
if (_hasLaunched)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
ASSIGN(_environment, env);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the path to the executable file to be run.
|
||||
* There is no default for this - you must set the launch path.
|
||||
* This method cannot be used after a task is launched ...
|
||||
* it raises an NSInvalidArgumentException.
|
||||
*/
|
||||
- (void) setLaunchPath: (NSString*)path
|
||||
{
|
||||
if (_hasLaunched)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
ASSIGN(_launchPath, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the standard error stream for the task.<br />
|
||||
* This is normally a writable NSFileHandle object.
|
||||
* If this is an NSPipe, the write end of the pipe is
|
||||
* automatically closed on launching.<br />
|
||||
* The default behavior is to inherit the parent processes
|
||||
* stderr output.<br />
|
||||
* This method cannot be used after a task is launched ...
|
||||
* it raises an NSInvalidArgumentException.
|
||||
*/
|
||||
- (void) setStandardError: (id)hdl
|
||||
{
|
||||
NSAssert([hdl isKindOfClass: [NSFileHandle class]] ||
|
||||
[hdl isKindOfClass: [NSPipe class]], NSInvalidArgumentException);
|
||||
if (_hasLaunched)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
ASSIGN(_standardError, hdl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the standard input stream for the task.<br />
|
||||
* This is normally a readable NSFileHandle object.
|
||||
* If this is an NSPipe, the read end of the pipe is
|
||||
* automatically closed on launching.<br />
|
||||
* The default behavior is to inherit the parent processes
|
||||
* stdin stream.<br />
|
||||
* This method cannot be used after a task is launched ...
|
||||
* it raises an NSInvalidArgumentException.
|
||||
*/
|
||||
- (void) setStandardInput: (id)hdl
|
||||
{
|
||||
NSAssert([hdl isKindOfClass: [NSFileHandle class]] ||
|
||||
[hdl isKindOfClass: [NSPipe class]], NSInvalidArgumentException);
|
||||
if (_hasLaunched)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
ASSIGN(_standardInput, hdl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the standard output stream for the task.<br />
|
||||
* This is normally a writable NSFileHandle object.
|
||||
* If this is an NSPipe, the write end of the pipe is
|
||||
* automatically closed on launching.<br />
|
||||
* The default behavior is to inherit the parent processes
|
||||
* stdout stream.<br />
|
||||
* This method cannot be used after a task is launched ...
|
||||
* it raises an NSInvalidArgumentException.
|
||||
*/
|
||||
- (void) setStandardOutput: (id)hdl
|
||||
{
|
||||
NSAssert([hdl isKindOfClass: [NSFileHandle class]] ||
|
||||
[hdl isKindOfClass: [NSPipe class]], NSInvalidArgumentException);
|
||||
if (_hasLaunched)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
ASSIGN(_standardOutput, hdl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the standard error stream for the task - an NSFileHandle
|
||||
* unless an NSPipe was passed to -setStandardError:
|
||||
*/
|
||||
- (id) standardError
|
||||
{
|
||||
if (_standardError == nil)
|
||||
{
|
||||
[self setStandardError: [NSFileHandle fileHandleWithStandardError]];
|
||||
}
|
||||
return _standardError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the standard input stream for the task - an NSFileHandle
|
||||
* unless an NSPipe was passed to -setStandardInput:
|
||||
*/
|
||||
- (id) standardInput
|
||||
{
|
||||
if (_standardInput == nil)
|
||||
{
|
||||
[self setStandardInput: [NSFileHandle fileHandleWithStandardInput]];
|
||||
}
|
||||
return _standardInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the standard output stream for the task - an NSFileHandle
|
||||
* unless an NSPipe was passed to -setStandardOutput:
|
||||
*/
|
||||
- (id) standardOutput
|
||||
{
|
||||
if (_standardOutput == nil)
|
||||
{
|
||||
[self setStandardOutput: [NSFileHandle fileHandleWithStandardOutput]];
|
||||
}
|
||||
return _standardOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a stop signal to the receiver and any subtasks.<br />
|
||||
* If the task has not been launched, raises an
|
||||
* NSInvalidArgumentException.<br />
|
||||
*/
|
||||
- (BOOL) suspend
|
||||
{
|
||||
if (_hasLaunched == NO)
|
||||
|
@ -530,6 +612,15 @@ pty_slave(const char* name)
|
|||
return YES;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a terminate signal to the receiver and any subtasks.<br />
|
||||
* If the task has not been launched, raises an
|
||||
* NSInvalidArgumentException.<br />
|
||||
* Has no effect on a task that has already terminated.<br />
|
||||
* When a task temrinates, either due to this method being called,
|
||||
* or normal termination, an NSTaskDidTerminateNotification is
|
||||
* posted.
|
||||
*/
|
||||
- (void) terminate
|
||||
{
|
||||
if (_hasLaunched == NO)
|
||||
|
@ -552,46 +643,61 @@ pty_slave(const char* name)
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the termination status of the task.<br />
|
||||
* If the task has not completed running, raises an
|
||||
* NSInvalidArgumentException.
|
||||
*/
|
||||
- (int) terminationStatus
|
||||
{
|
||||
if (_hasLaunched == NO)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has not yet launched"];
|
||||
}
|
||||
if (_hasCollected == NO)
|
||||
{
|
||||
[self _collectChild];
|
||||
}
|
||||
if (_hasTerminated == NO)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has not yet terminated"];
|
||||
}
|
||||
return _terminationStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the system supports it, this method sets the standard
|
||||
* input, output, and error streams to a pseudo-terminal so
|
||||
* that, when launched, the child task will act as if it was
|
||||
* running interactively on a terminal. The file handles
|
||||
* can then be used to communicate with the child.<br />
|
||||
* This method cannot be used after a task is launched ...
|
||||
* it raises an NSInvalidArgumentException.<br />
|
||||
* The standard input, output and error streams cannot be
|
||||
* changed after calling this method.<br />
|
||||
* The method returns YES on success, NO on failure.
|
||||
*/
|
||||
- (BOOL) usePseudoTerminal
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void) waitUntilExit
|
||||
/**
|
||||
* Returns a validated launch path or nil.<br />
|
||||
* Allows for the GNUstep host, operating system, and library combination
|
||||
* subdirectories in a path, appending them as necessary to try to locate
|
||||
* the actual binary to be used.<br />
|
||||
* Checks that the binary file exists and is executable.<br />
|
||||
* Even tries searching the directories in the PATH environment variable
|
||||
* to locate a binary if the original alunch path set was not absolute.
|
||||
*/
|
||||
- (NSString*) validatedLaunchPath
|
||||
{
|
||||
NSTimer *timer = nil;
|
||||
|
||||
while ([self isRunning])
|
||||
{
|
||||
NSDate *limit;
|
||||
|
||||
/*
|
||||
* Poll at 0.1 second intervals.
|
||||
*/
|
||||
limit = [[NSDate alloc] initWithTimeIntervalSinceNow: 0.1];
|
||||
if (timer == nil)
|
||||
{
|
||||
timer = [NSTimer scheduledTimerWithTimeInterval: 0.1
|
||||
target: nil
|
||||
selector: @selector(class)
|
||||
userInfo: nil
|
||||
repeats: YES];
|
||||
}
|
||||
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode
|
||||
beforeDate: limit];
|
||||
RELEASE(limit);
|
||||
}
|
||||
[timer invalidate];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSTask (Private)
|
||||
|
||||
- (NSString *) _fullLaunchPath
|
||||
{
|
||||
NSFileManager *mgr = [NSFileManager defaultManager];
|
||||
NSString *libs = [NSBundle _library_combo];
|
||||
NSString *arch = [NSBundle _gnustep_target_dir];
|
||||
NSFileManager *mgr;
|
||||
NSString *libs;
|
||||
NSString *arch;
|
||||
NSString *prog;
|
||||
NSString *lpath;
|
||||
NSString *base_path;
|
||||
|
@ -600,10 +706,13 @@ pty_slave(const char* name)
|
|||
|
||||
if (_launchPath == nil)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - no launch path set"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
mgr = [NSFileManager defaultManager];
|
||||
libs = [NSBundle _library_combo];
|
||||
arch = [NSBundle _gnustep_target_dir];
|
||||
|
||||
/*
|
||||
* Set lpath to the actual path to use for the executable.
|
||||
* First choice - base_path/architecture/library_combo/prog.
|
||||
|
@ -636,31 +745,86 @@ pty_slave(const char* name)
|
|||
*/
|
||||
if ([base_path isEqualToString: @""] == YES)
|
||||
{
|
||||
lpath = [NSBundle _absolutePathOfExecutable: prog];
|
||||
lpath = [NSBundle _absolutePathOfExecutable: prog];
|
||||
}
|
||||
if (lpath == nil)
|
||||
if (lpath != nil && [mgr isExecutableFileAtPath: lpath] == NO)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - launch path (%@) not valid",
|
||||
_launchPath];
|
||||
lpath = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Make sure we have a standardised absolute path to pass to execve()
|
||||
*/
|
||||
if ([lpath isAbsolutePath] == NO)
|
||||
if (lpath != nil)
|
||||
{
|
||||
NSString *current = [mgr currentDirectoryPath];
|
||||
/*
|
||||
* Make sure we have a standardised absolute path to pass to execve()
|
||||
*/
|
||||
if ([lpath isAbsolutePath] == NO)
|
||||
{
|
||||
NSString *current = [mgr currentDirectoryPath];
|
||||
|
||||
lpath = [current stringByAppendingPathComponent: lpath];
|
||||
lpath = [current stringByAppendingPathComponent: lpath];
|
||||
}
|
||||
lpath = [lpath stringByStandardizingPath];
|
||||
}
|
||||
lpath = [lpath stringByStandardizingPath];
|
||||
|
||||
return lpath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Suspends the current thread until the task terminates, by
|
||||
* waiting in NSRunLoop (NSDefaultRunLoopMode) for the task
|
||||
* termination.<br />
|
||||
* Returns immediately if the task is not running.
|
||||
*/
|
||||
- (void) waitUntilExit
|
||||
{
|
||||
NSTimer *timer = nil;
|
||||
|
||||
while ([self isRunning])
|
||||
{
|
||||
NSDate *limit;
|
||||
|
||||
/*
|
||||
* Poll at 0.1 second intervals.
|
||||
*/
|
||||
limit = [[NSDate alloc] initWithTimeIntervalSinceNow: 0.1];
|
||||
if (timer == nil)
|
||||
{
|
||||
timer = [NSTimer scheduledTimerWithTimeInterval: 0.1
|
||||
target: nil
|
||||
selector: @selector(class)
|
||||
userInfo: nil
|
||||
repeats: YES];
|
||||
}
|
||||
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode
|
||||
beforeDate: limit];
|
||||
RELEASE(limit);
|
||||
}
|
||||
[timer invalidate];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSTask (Private)
|
||||
|
||||
- (NSString *) _fullLaunchPath
|
||||
{
|
||||
NSString *val;
|
||||
|
||||
if (_launchPath == nil)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - no launch path set"];
|
||||
}
|
||||
val = [self validatedLaunchPath];
|
||||
if (val == nil)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - launch path (%@) not valid", _launchPath];
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
- (void) _sendNotification
|
||||
{
|
||||
if (_hasNotified == NO)
|
||||
|
|
Loading…
Reference in a new issue