diff --git a/ChangeLog b/ChangeLog index c314a6c74..4226f2e39 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2001-04-19 Richard Frith-Macdonald + + * Source/NSTask.m: Tidied code a little, added safety checks for + usePseudoTerminal method. + * Documentation/gsdoc/NSTask.gsdoc: documentation fleshed out. + 2001-04-16 Adam Fedor * aclocal.m4: Detect the xm2-config script. diff --git a/Documentation/gsdoc/NSTask.html b/Documentation/gsdoc/NSTask.html index 1cb3b66a5..74d6a17fc 100644 --- a/Documentation/gsdoc/NSTask.html +++ b/Documentation/gsdoc/NSTask.html @@ -21,6 +21,8 @@


+ The NSTask class provides a mechanism to run separate tasks + under (limited) control of your program.

Instance Variables


Class Methods

launchedTaskWithLaunchPath:arguments:

+ (NSTask*) launchedTaskWithLaunchPath: (NSString*)path arguments: (NSArray*)arguments;
+ 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.

Instances Methods

arguments

- (NSArray*) arguments;
+ Returns the arguments set for the task.

currentDirectoryPath

- (NSString*) currentDirectoryPath;
+ Returns the working directory set for the task.

environment

- (NSDictionary*) environment;
+ Returns the environment set for the task.
-

init

-- (id) init;
- - -
-

interrupt

+

interrupt

- (void) interrupt;
+ Sends an interrupt signal to the receiver and any subtasks.
+ If the task has not been launched, raises an + NSInvalidArgumentException.
+ Has no effect on a task that has already terminated.
+ This is rather like the terminate method, but the child + process may not choose to terminate in response to an interrupt.
-

isRunning

+

isRunning

- (BOOL) isRunning;
+ Checks to see if the task is currently running.
-

launch

+

launch

- (void) launch;
+ Launches the task.
+ 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).
-

launchPath

+

launchPath

- (NSString*) launchPath;
+ Returns the launch path set for the task.
-

setArguments:

+

setArguments:

- (void) setArguments: (NSArray*)arguments;
+ 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.
-

setCurrentDirectoryPath:

+

setCurrentDirectoryPath:

- (void) setCurrentDirectoryPath: (NSString*)path;
+ 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.
-

setEnvironment:

+

setEnvironment:

- (void) setEnvironment: (NSDictionary*)environmentDictionary;
+ 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.
-

setLaunchPath:

+

setLaunchPath:

- (void) setLaunchPath: (NSString*)path;
+ 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.
-

setStandardError:

+

setStandardError:

- (void) setStandardError: (id)file;
+ Sets the standard error stream for the task.
+ This is normally a writable NSFileHandle object. + If this is an NSPipe, the write end of the pipe is + automatically closed on launching.
+ The default behavior is to inherit the parent processes + stderr output.
+ This method cannot be used after a task is launched ... + it raises an NSInvalidArgumentException.
-

setStandardInput:

+

setStandardInput:

- (void) setStandardInput: (id)file;
+ Sets the standard input stream for the task.
+ This is normally a readable NSFileHandle object. + If this is an NSPipe, the read end of the pipe is + automatically closed on launching.
+ The default behavior is to inherit the parent processes + stdin stream.
+ This method cannot be used after a task is launched ... + it raises an NSInvalidArgumentException.
-

setStandardOutput:

+

setStandardOutput:

- (void) setStandardOutput: (id)file;
+ Sets the standard output stream for the task.
+ This is normally a writable NSFileHandle object. + If this is an NSPipe, the write end of the pipe is + automatically closed on launching.
+ The default behavior is to inherit the parent processes + stdout stream.
+ This method cannot be used after a task is launched ... + it raises an NSInvalidArgumentException.
-

standardError

+

standardError

- (id) standardError;
+ Returns the standard error stream for the task - an NSFileHandle + unless an NSPipe was passed to setStandardError:
-

standardInput

+

standardInput

- (id) standardInput;
+ Returns the standard input stream for the task - an NSFileHandle + unless an NSPipe was passed to setStandardInput:
-

standardOutput

+

standardOutput

- (id) standardOutput;
+ Returns the standard output stream for the task - an NSFileHandle + unless an NSPipe was passed to setStandardOutput:
-

terminate

+

terminate

- (void) terminate;
+ Sends a terminate signal to the receiver and any subtasks.
+ If the task has not been launched, raises an + NSInvalidArgumentException.
+ Has no effect on a task that has already terminated.
+ When a task temrinates, either due to this method being called, + or normal termination, an NSTaskDidTerminateNotification is + posted.
-

terminationStatus

+

terminationStatus

- (int) terminationStatus;
+ Returns the termination status of the task.
+ If the task has not completed running, raises an + NSInvalidArgumentException. + +
+

usePseudoTerminal

+- (BOOL) usePseudoTerminal;
+Standards: GNUstep NotMacOS-X NotOpenStep
+ + 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.
+ This method cannot be used after a task is launched ... + it raises an NSInvalidArgumentException.
+ The standard input, output and error streams cannot be + changed after calling this method.
+ The method returns YES on success, NO on failure.

waitUntilExit

- (void) waitUntilExit;
+ Suspends the current thread until the task terminates, by + waiting in NSRunLoop (NSDefaultRunLoopMode) for the task + termination.
+ Returns immediately if the task is not running.
diff --git a/Source/NSTask.m b/Source/NSTask.m index 82f37b689..ddf501909 100644 --- a/Source/NSTask.m +++ b/Source/NSTask.m @@ -85,7 +85,7 @@ static void handleSignal(int sig) @interface NSConcreteUnixTask : NSTask { char slave_name[32]; - BOOL usePseudoTerminal; + BOOL _usePseudoTerminal; } @end #define NSConcreteTask NSConcreteUnixTask @@ -781,7 +781,7 @@ GSCheckTasks() { BOOL found = NO; - if (hadChildSignal) + if (hadChildSignal == YES) { int result; int status; @@ -793,36 +793,28 @@ GSCheckTasks() result = waitpid(-1, &status, WNOHANG); if (result > 0) { - if (WIFEXITED(status)) - { - NSTask *t; + NSTask *t; - [tasksLock lock]; - t = (NSTask*)NSMapGet(activeTasks, (void*)result); - [tasksLock unlock]; - if (t) + [tasksLock lock]; + t = (NSTask*)NSMapGet(activeTasks, (void*)result); + [tasksLock unlock]; + if (t != nil) + { + if (WIFEXITED(status)) { [t _terminatedChild: WEXITSTATUS(status)]; found = YES; } - } - else if (WIFSIGNALED(status)) - { - NSTask *t; - - [tasksLock lock]; - t = (NSTask*)NSMapGet(activeTasks, (void*)result); - [tasksLock unlock]; - if (t) + else if (WIFSIGNALED(status)) { [t _terminatedChild: WTERMSIG(status)]; found = YES; } - } - else - { - NSLog(@"Warning ... task %d neither exited nor signalled", - result); + else + { + NSLog(@"Warning ... task %d neither exited nor signalled", + result); + } } } } @@ -955,7 +947,7 @@ GSCheckTasks() #endif #endif - if (usePseudoTerminal == YES) + if (_usePseudoTerminal == YES) { int s; @@ -1049,6 +1041,36 @@ GSCheckTasks() } } +- (void) setStandardError: (id)hdl +{ + if (_usePseudoTerminal == YES) + { + [NSException raise: NSInvalidArgumentException + format: @"NSTask - set error for task on pseudo terminal"]; + } + [super setStandardError: hdl]; +} + +- (void) setStandardInput: (id)hdl +{ + if (_usePseudoTerminal == YES) + { + [NSException raise: NSInvalidArgumentException + format: @"NSTask - set input for task on pseudo terminal"]; + } + [super setStandardInput: hdl]; +} + +- (void) setStandardOutput: (id)hdl +{ + if (_usePseudoTerminal == YES) + { + [NSException raise: NSInvalidArgumentException + format: @"NSTask - set output for task on pseudo terminal"]; + } + [super setStandardOutput: hdl]; +} + - (void) _collectChild { if (_hasCollected == NO) @@ -1100,7 +1122,7 @@ GSCheckTasks() int master; NSFileHandle *fh; - if (usePseudoTerminal == YES) + if (_usePseudoTerminal == YES) { return YES; } @@ -1123,7 +1145,7 @@ GSCheckTasks() closeOnDealloc: YES]; [self setStandardError: fh]; RELEASE(fh); - usePseudoTerminal = YES; + _usePseudoTerminal = YES; return YES; }