home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * 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 "protos.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;
-
- 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;
-
- 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;
- }
- }
-
-