I've had a report from the field of a crash at -launch
on NSTask.
The code in question is:
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/bin/zsh"];
if(ignore)
{
[task setArguments:@[scriptPath, recordingFolder, Argument]];
}
else
{
[task setArguments:@[scriptPath, recordingFolder]];
}
NSPipe *outPipe = [NSPipe pipe];
[task setStandardOutput:outPipe];
NSPipe *errorPipe = [NSPipe pipe];
[task setStandardError:errorPipe];
[task launch];
The scriptPath is a script that is included in the app bundle. The crash says:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Failed to set posix_spawn_file_actions for fd -1 at index 0 with errno 9'
What could be the cause of this? What file descriptor do the posix_spawn_file_actions refer to? Does it mean that the executable script is wrong or that the outPipe or errPipe are not well formed?
I believe it is referring to the posix_spawn function: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/posix_spawn.2.html
And errno 9 is EBADF (bad file number).
I've got a similar error , after I use below command, it's OK, you can try it.
NSFileHandle *file=[outPipe fileHandleForReading];
[task launch];
....//read file.
//this is the most important.
[file closeFile];
If you are calling this code many different times sequentially, you are running out of file descriptors -- you need to close the pipes after you are done. The correct way to do it is to deallocate NSTask and it will close the file channels. Put the NSTask-related code in an autoreleasepool statement:
@autoreleasepool {
NSTask* task = [NSTask new];
...
[task launch];
...
[task waitUntilDone];
}
For the issue in the question, I suggest that we should put the code of CreateProcess() in an @autoreleasepool block as Apple's doc shows that we should not send -[closeFile] to fileHandleForReading explicitly.
https://developer.apple.com/reference/foundation/nspipe/1414352-filehandleforreading?language=objc
Declaration
@property(readonly, retain) NSFileHandle *fileHandleForReading;
Discussion
The descriptor represented by this object is deleted, and the object itself is automatically deallocated when the receiver is deallocated.
You use the returned file handle to read from the pipe using NSFileHandle's read methods—availableData, readDataToEndOfFile, and readDataOfLength:.
You don’t need to send closeFile to this object or explicitly release the object after you have finished using it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With