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 >
C/C++ Source or Header  |  1990-12-08  |  3KB  |  121 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 <stdio.h>
  25. #include "config.h"
  26.  
  27. typedef struct MsgPort    PORT;
  28. typedef struct Message    MSG;
  29.  
  30. struct SMsgPort {
  31.     PORT    Port;
  32.     short   NameLen;
  33.     short   Reserved;
  34. };
  35.  
  36. typedef struct SMsgPort SPORT;
  37.  
  38. Prototype void LockSerialPort(const char *, long);
  39. Prototype void UnLockSerialPort(const char *, long);
  40.  
  41. static SPORT    *SPLock;
  42.  
  43. int IAmGetty = 0;
  44.  
  45. void
  46. LockSerialPort(name, unit)
  47. const char *name;
  48. long unit;
  49. {
  50.     short namelen = strlen(name) + 32;
  51.     char *portname;
  52.     SPORT *sport;
  53.     PORT  *rport = NULL;
  54.     MSG   msg;
  55.  
  56.     ulog(2, "LOCK SERIAL PORT");
  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.     ulog(2, "UNLOCK SERIAL PORT");
  105.     if (SPLock) {
  106.     if (IAmGetty == 0)
  107.         sleep(2);
  108.     Forbid();
  109.     if (msg = GetMsg(&SPLock->Port)) {  /*  somebody else wants it */
  110.         ReplyMsg(msg);
  111.     } else {            /*  nobody else wants it   */
  112.         RemPort(&SPLock->Port);
  113.         FreeMem(SPLock->Port.mp_Node.ln_Name, SPLock->NameLen);
  114.         FreeMem(SPLock, sizeof(SPORT));
  115.     }
  116.     Permit();
  117.     SPLock = NULL;
  118.     }
  119. }
  120.  
  121.