This is connect.m in view mode; [Download] [Up]
// // connect.m // LGDCommunicationKit Examples, Release 1.0 (prerelease) // // Copyright (c) 1993, Looking Glass Design, Inc. // All rights reserved. // // Project Manager: Paul Girone // Original Author: Mike Gobbi // Creation Date: June 16, 1993 // $Revision: 1.3 $ // #import "connect.h" #import <assert.h> #import <errno.h> #import <lgd/commkit/LGDSerialPort.h> #import <libc.h> #import <sgtty.h> #import <stdio.h> static LGDSerialPort *port; // the object used to connect to the port static int tty; // the file descriptor of the terminal int orig_fcntl; // original settings struct sgttyb orig_sgttyb; // original settings void configure(const char *device) { int signals[] = { SIGINT, SIGQUIT, SIGBUS, SIGSEGV, SIGTERM, 0 }; int i; struct sgttyb sgttyb; // set ourself up to die nicely no matter what happens for (i=0; signals[i]; i++) { signal(signals[i], (void *)cleanup); } // open tty tty = open("/dev/tty", O_RDWR, 0644); assert(tty>=0); // configure tty errno = 0; orig_fcntl = fcntl(tty, F_GETFL, 0); fcntl(tty, F_SETFL, orig_fcntl | FNDELAY); ioctl(tty, TIOCGETP, &sgttyb); orig_sgttyb = sgttyb; sgttyb.sg_flags |= RAW; ioctl(tty, TIOCSETP, &sgttyb); assert(errno==0); // open port port = [[LGDSerialPort alloc] init]; if (![port openAndLockDevice:device mode:LGD_SP_COOKED timeout:0]) { deconfigure(); printf("unable to open device %s\n", device); exit(1); } [port setDuplex:LGD_SP_HALFDUPLEX]; } void deconfigure(void) { // shut down serial port if ([port isOpen]) { [port flush]; [port unlockAndClose]; } [port free]; // deconfigure tty errno = 0; ioctl(tty, TIOCSETP, &orig_sgttyb); fcntl(tty, F_SETFL, orig_fcntl); assert(errno==0); // close tty if (tty>=0) { close(tty); } } void cleanup(void) { if ([port isOpen]) { [port unlockAndClose]; } exit(2); } int keyboard_ready(int tty) { fd_set set; struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; FD_ZERO(&set); FD_SET(tty, &set); select(tty+1, &set, NULL, NULL, &tv); return 0!=FD_ISSET(tty, &set); } void loop(void) { while (1) { // send characters to port if (keyboard_ready(tty)) { char out; errno = 0; while (1==read(tty, &out, 1)) { if (out==3) { return; } if (out=='\n') out = '\r'; if (out=='z') kill(0, SIGIO); if (1!=[port sendCharacter:out]) { return; } } if (errno && errno!=EWOULDBLOCK) { return; } } // get characters from port if ([port dataAvailable]) { int in; while (1==[port getCharacter:&in]) { char c = in; if (1!=write(tty, &c, 1)) { return; } } if ([port status]) { return; } } } } int main(int argc, char *argv[]) { // display instructions printf("Press ^C to exit\n"); // configure things configure(argv[1] ? argv[1] : "cufa"); // run the loop loop(); // display error messages if ([port status]) { printf("%s", [port statusString]); } // tidy up deconfigure(); // display message printf("clean exit\n"); return 0; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.