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.