home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / auucp+-1.02 / fuucp_plus_src.lzh / lib / serialport.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-21  |  2.8 KB  |  120 lines

  1.  
  2. /*
  3.  *  SERIALPORT.C
  4.  *
  5.  *  $Header: Beta:src/uucp/src/lib/RCS/serialport.c,v 1.1 90/02/02 12:08:21 dillon Exp Locker: dillon $
  6.  *
  7.  *  (C) Copyright 1989-1990 by Matthew Dillon,  All Rights Reserved.
  8.  *
  9.  *  Serial Port locking to prevent collisions between, say, a Getty
  10.  *  accepting a login sequence and a uucico calling up another machine.
  11.  *
  12.  *  The existance of the public port indicates a lock.    People waiting
  13.  *  for the lock PutMsg() EXEC messages to the port.  Upon unlocking,
  14.  *  the unlocker will deallocate the port only if no messages are
  15.  *  pending, else it will ReplyMsg() the first message in the queue
  16.  *  and NOT deallocate the port.
  17.  *
  18.  *  On receiving a message back you own the port and its memory
  19.  */
  20.  
  21. #include <exec/types.h>
  22. #include <exec/ports.h>
  23. #include <exec/memory.h>
  24. #include "protos.h"
  25. #include <stdio.h>
  26. #include "config.h"
  27.  
  28. typedef struct MsgPort    PORT;
  29. typedef struct Message    MSG;
  30.  
  31. struct SMsgPort {
  32.     PORT    Port;
  33.     short   NameLen;
  34.     short   Reserved;
  35. };
  36.  
  37. typedef struct SMsgPort SPORT;
  38.  
  39. Prototype void LockSerialPort(const char *, long);
  40. Prototype void UnLockSerialPort(const char *, long);
  41.  
  42. static SPORT    *SPLock;
  43.  
  44. int IAmGetty = 0;
  45.  
  46. void
  47. LockSerialPort(name, unit)
  48. const char *name;
  49. long unit;
  50. {
  51.     short namelen = strlen(name) + 32;
  52.     char *portname;
  53.     SPORT *sport;
  54.     PORT  *rport = NULL;
  55.     MSG   msg;
  56.  
  57.     if (SPLock)
  58.     return;
  59.  
  60.     portname = AllocMem(namelen, MEMF_PUBLIC | MEMF_CLEAR);
  61.  
  62.     sprintf(portname, "SPLock-%d-%s", unit, name);
  63.  
  64.     Forbid();
  65.     if (sport = (SPORT *)FindPort(portname)) {
  66.     rport = CreatePort(NULL, 0);
  67.     msg.mn_ReplyPort = rport;
  68.     msg.mn_Length = 0;
  69.     if (IAmGetty)
  70.         AddHead(&sport->Port.mp_MsgList, &msg);
  71.     else
  72.         AddTail(&sport->Port.mp_MsgList, &msg);
  73.     FreeMem(portname, namelen);
  74.     } else {
  75.     sport = AllocMem(sizeof(SPORT), MEMF_PUBLIC | MEMF_CLEAR);
  76.     sport->Port.mp_Node.ln_Name = portname;
  77.     sport->Port.mp_Node.ln_Type = NT_MSGPORT;
  78.     sport->Port.mp_Flags = PA_IGNORE;
  79.     sport->NameLen = namelen;
  80.     AddPort(&sport->Port);
  81.     }
  82.     Permit();
  83.     SPLock = sport;
  84.     if (rport) {            /*  wait for message to be returned */
  85.     WaitPort(rport);
  86.     DeletePort(rport);
  87.     }
  88. }
  89.  
  90. /*
  91.  *  Unlock the serial port.  If I am NOT the Getty then delay before
  92.  *  unlocking to give the Getty a chance to take the next lock (it takes
  93.  *  about a second for the Getty to realize the serial.device has been
  94.  *  closed and try to take the lock.
  95.  */
  96.  
  97. void
  98. UnLockSerialPort(name, unit)
  99. const char *name;
  100. long unit;
  101. {
  102.     MSG *msg;
  103.  
  104.     if (SPLock) {
  105.     if (IAmGetty == 0)
  106.         sleep(2);
  107.     Forbid();
  108.     if (msg = GetMsg(&SPLock->Port)) {  /*  somebody else wants it */
  109.         ReplyMsg(msg);
  110.     } else {            /*  nobody else wants it   */
  111.         RemPort(&SPLock->Port);
  112.         FreeMem(SPLock->Port.mp_Node.ln_Name, SPLock->NameLen);
  113.         FreeMem(SPLock, sizeof(SPORT));
  114.     }
  115.     Permit();
  116.     SPLock = NULL;
  117.     }
  118. }
  119.  
  120.