Hi all, I’ve having a bit of trouble with setting up a pseudo-TTY to communicate with another process. What I’m doing is setting up an incredibly basic terminal (NSTextView + delegate) which will be used to give commands to another process. It pretty much works, except that the input is echoed back along with output. If I disable echoing, then this does not happen, but then strangely enough certain aspects of the terminal stop working.
Here’s how I setup the TTY, done as a category on top of NSTask:
- (NSFileHandle *)masterSideOfPTYOrError:(NSError *__autoreleasing *)error {
int fdMaster, fdSlave;
int rc = openpty(&fdMaster, &fdSlave, NULL, NULL, NULL);
if (rc != 0) {
if (error) {
*error = [NSError errorWithDomain:NSPOSIXErrorDomain
code:errno userInfo:nil];
}
return nil;
}
// Disable echoing and CR conversion
struct termios buf = {};
if (tcgetattr(fdMaster, &buf) < 0) {
perror("ERROR: Cannot get terminal attributes");
return nil;
}
buf.c_oflag &= ~(ONLCR);
buf.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
if (tcsetattr(fdMaster, TCSANOW, &buf) < 0) {
perror("ERROR: Cannot disable terminal echo");
return nil;
}
// Set the master and slave to automatically close
fcntl(fdMaster, F_SETFD, FD_CLOEXEC);
fcntl(fdSlave, F_SETFD, FD_CLOEXEC);
NSFileHandle *masterHandle = [[NSFileHandle alloc]
initWithFileDescriptor:fdMaster closeOnDealloc:YES];
NSFileHandle *slaveHandle = [[NSFileHandle alloc]
initWithFileDescriptor:fdSlave closeOnDealloc:YES];
self.standardInput = slaveHandle;
self.standardOutput = slaveHandle;
return masterHandle;
}
This is how input is “written” to the process:
- (BOOL)textView:(NSTextView *)textView
doCommandBySelector:(SEL)commandSelector {
BOOL retval = NO;
// When return is entered, record and color the newly committed text
if (@selector(insertNewline:) == commandSelector) {
NSUInteger textLength = [[textView string] length];
if (textLength > committedLength) {
NSString *textToSubmit = [[textView string]
substringFromIndex:committedLength];
[textView setSelectedRange:NSMakeRange(textLength, 0)];
[textView insertText:@"\n"];
//[textView setTextColor:[NSColor redColor]
range:NSMakeRange(committedLength, textLength - committedLength)];
//[self.textView setFont:[NSFont fontWithName:@"Menlo"
size:11]];
//textLength++;
committedLength = textLength;
const char *convertedInput = [textToSubmit UTF8String];
[self.masterHandle writeData:[NSData
dataWithBytes:convertedInput length:strlen(convertedInput)]];
[self.masterHandle writeData:[NSData dataWithBytes:"\n"
length:strlen("\n")]];
[self.masterHandle synchronizeFile];
}
retval = YES;
}
return retval;
}
And here’s the relevant code for reading:
text = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSAttributedString *astr = [[NSAttributedString alloc] initWithString:text];
[[self.textView textStorage] appendAttributedString:astr];
[self.textView setTextColor:[NSColor whiteColor]];
[self.textView setFont:[NSFont fontWithName:@"Menlo" size:11]];
NSUInteger textLength = [[self.textView string] length];
if (textLength > committedLength) {
if (textLength > 0) --textLength; else textLength = 0;
textLength++;
[self.textView setSelectedRange:NSMakeRange(textLength, 0)];
committedLength = textLength;
[self.textView scrollRangeToVisible:NSMakeRange([[self.textView string]
length], 0)];
}
Here’s an example of the session when output is printed (notice the echoing):
Insane BF Interactive Console 1.0 (Dec 18 2014, 16:22:05)
Current memory size: 30000 cells, each 4 bytes
: ,
,
A
A
:
: .
.
A
:
And here’s what it shows when I disable echoing using the code above. Nothing
else has been changed:
Insane BF Interactive Console 1.0 (Dec 18 2014, 16:22:05)
Current memory size: 30000 cells, each 4 bytes
: ,
A
:
: .
:
Any ideas?
— SevenBits
signature.asc
Description: Message signed with OpenPGP using GPGMail
_______________________________________________ Cocoa-dev mailing list ([email protected]) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [email protected]
