home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
telecom
/
uucp_442
/
src
/
lib
/
serialport.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-08
|
3KB
|
121 lines
/*
* SERIALPORT.C
*
* $Header: Beta:src/uucp/src/lib/RCS/serialport.c,v 1.1 90/02/02 12:08:21 dillon Exp Locker: dillon $
*
* (C) Copyright 1989-1990 by Matthew Dillon, All Rights Reserved.
*
* Serial Port locking to prevent collisions between, say, a Getty
* accepting a login sequence and a uucico calling up another machine.
*
* The existance of the public port indicates a lock. People waiting
* for the lock PutMsg() EXEC messages to the port. Upon unlocking,
* the unlocker will deallocate the port only if no messages are
* pending, else it will ReplyMsg() the first message in the queue
* and NOT deallocate the port.
*
* On receiving a message back you own the port and its memory
*/
#include <exec/types.h>
#include <exec/ports.h>
#include <exec/memory.h>
#include <stdio.h>
#include "config.h"
typedef struct MsgPort PORT;
typedef struct Message MSG;
struct SMsgPort {
PORT Port;
short NameLen;
short Reserved;
};
typedef struct SMsgPort SPORT;
Prototype void LockSerialPort(const char *, long);
Prototype void UnLockSerialPort(const char *, long);
static SPORT *SPLock;
int IAmGetty = 0;
void
LockSerialPort(name, unit)
const char *name;
long unit;
{
short namelen = strlen(name) + 32;
char *portname;
SPORT *sport;
PORT *rport = NULL;
MSG msg;
ulog(2, "LOCK SERIAL PORT");
if (SPLock)
return;
portname = AllocMem(namelen, MEMF_PUBLIC | MEMF_CLEAR);
sprintf(portname, "SPLock-%d-%s", unit, name);
Forbid();
if (sport = (SPORT *)FindPort(portname)) {
rport = CreatePort(NULL, 0);
msg.mn_ReplyPort = rport;
msg.mn_Length = 0;
if (IAmGetty)
AddHead(&sport->Port.mp_MsgList, &msg);
else
AddTail(&sport->Port.mp_MsgList, &msg);
FreeMem(portname, namelen);
} else {
sport = AllocMem(sizeof(SPORT), MEMF_PUBLIC | MEMF_CLEAR);
sport->Port.mp_Node.ln_Name = portname;
sport->Port.mp_Node.ln_Type = NT_MSGPORT;
sport->Port.mp_Flags = PA_IGNORE;
sport->NameLen = namelen;
AddPort(&sport->Port);
}
Permit();
SPLock = sport;
if (rport) { /* wait for message to be returned */
WaitPort(rport);
DeletePort(rport);
}
}
/*
* Unlock the serial port. If I am NOT the Getty then delay before
* unlocking to give the Getty a chance to take the next lock (it takes
* about a second for the Getty to realize the serial.device has been
* closed and try to take the lock.
*/
void
UnLockSerialPort(name, unit)
const char *name;
long unit;
{
MSG *msg;
ulog(2, "UNLOCK SERIAL PORT");
if (SPLock) {
if (IAmGetty == 0)
sleep(2);
Forbid();
if (msg = GetMsg(&SPLock->Port)) { /* somebody else wants it */
ReplyMsg(msg);
} else { /* nobody else wants it */
RemPort(&SPLock->Port);
FreeMem(SPLock->Port.mp_Node.ln_Name, SPLock->NameLen);
FreeMem(SPLock, sizeof(SPORT));
}
Permit();
SPLock = NULL;
}
}