1: #include "ft.h"
   2: #if NFT > 0
   3: /*
   4:  *	Fast Timer -- a pseudo-device that behaves like an interval timer.
   5:  *
   6:  *	Note:  because of exclusive open it can also be used as a lock file.
   7:  */
   8: 
   9: #include "param.h"
  10: #include <sys/systm.h>
  11: #include <sys/tty.h>
  12: #include <sys/dir.h>
  13: #include <sys/user.h>
  14: #include <sys/proc.h>
  15: #include <sys/map.h>
  16: #include <sys/conf.h>
  17: 
  18: /*
  19:  * Per-minor-device state table
  20:  *
  21:  * Invariants:
  22:  *	- device is open iff ftt_procp != 0
  23:  *	- timeout in progress iff ftt_state != AVAILABLE
  24:  */
  25: 
  26: struct  fttab   {
  27:     struct  proc    *ftt_procp; /* proctab entry and pid of	*/
  28:     short   ftt_pid;        /* controlling process.		*/
  29:     short   ftt_state;      /* AVAILABLE, CANCELLED, sig #	*/
  30: } fttab[NFT];
  31: 
  32: #define AVAILABLE   (0)
  33: #define CANCELLED   (-1)
  34: 
  35: #define MAXTIMEREQ  (60 * hz)   /* 1 minute */
  36: 
  37: /*
  38:  *	Open
  39:  *
  40:  *	Exclusive use only
  41:  */
  42: /*ARGSUSED*/
  43: ftopen(d, flag)
  44: {
  45:     register u_short    dminor;
  46:     register struct fttab   *ftp;
  47: 
  48:     dminor  = minor(d);
  49:     if (dminor >= NFT)  {
  50:         u.u_error   = ENXIO;
  51:         return;
  52:     }
  53:     ftp = &fttab[dminor];
  54:     if ((ftp->ftt_procp != (struct proc *) NULL)
  55:       || (ftp->ftt_state != AVAILABLE)) {
  56:         u.u_error   = EBUSY;
  57:         return;
  58:     }
  59:     ftp->ftt_procp  = u.u_procp;
  60:     ftp->ftt_pid    = u.u_procp->p_pid;
  61: }
  62: 
  63: /*
  64:  *	Close
  65:  */
  66: ftclose(d)
  67: {
  68:     register u_short    dminor;
  69:     register struct fttab   *ftp;
  70: 
  71:     dminor  = minor(d);
  72: #ifdef  PARANOIA
  73:         if (dminor >= NFT)  {
  74:             printf("ERR: ftclose\n");
  75:             u.u_error   = ENXIO;
  76:             return;
  77:         }
  78: #endif
  79:     ftp = &fttab[dminor];
  80:     ftp->ftt_procp  = (struct proc *) NULL;
  81:     ftp->ftt_pid    = 0;
  82: }
  83: 
  84: /*
  85:  *	Ioctl
  86:  *
  87:  *	All real work is done here using
  88:  *
  89:  *	 	FTIOCSET	request a software interrupt after specified
  90:  *				number of clock ticks
  91:  *		FTIOCCANCEL	cancel an outstanding request
  92:  */
  93: /*ARGSUSED*/
  94: ftioctl(dev, cmd, addr, flag)
  95: caddr_t addr;
  96: dev_t   dev;
  97: {
  98:     void    fttimeout();
  99:     register u_short    dminor;
 100:     register struct fttab   *ftp;
 101: 
 102:     dminor  = minor(dev);
 103:     if (dminor >= NFT)  {
 104:         printf("ERR: ftioctl!\n");
 105:         u.u_error   = EINVAL;
 106:     }
 107: 
 108:     ftp = &fttab[dminor];
 109: 
 110:     /*
 111: 	 *	Make sure invoking process owns the device.
 112: 	 *	This can only fail if call is from a child
 113: 	 *	forked off after opening the ft device.
 114: 	 */
 115:     if ((u.u_procp != ftp->ftt_procp)
 116:       || (u.u_procp->p_pid != ftp->ftt_pid))    {
 117:         u.u_error   = EBUSY;
 118:         return;
 119:     }
 120: 
 121:     /*
 122: 	 *	Interpret command
 123: 	 */
 124:     switch(cmd) {
 125: 
 126:         case FTIOCSET:
 127:             {
 128:             struct  {
 129:                 u_short timereq;
 130:                 short   sigreq;
 131:             } request;
 132: 
 133:             /*
 134: 			 *	Get request, make sure it's reasonable
 135: 			 */
 136:             if (copyin(addr, (caddr_t) &request, sizeof request))   {
 137:                 u.u_error   = EFAULT;
 138:                 return;
 139:             }
 140:             if ((request.sigreq <= 0) || (request.sigreq > NSIG)
 141:               || (request.timereq > MAXTIMEREQ))    {
 142:                 u.u_error   = EINVAL;
 143:                 return;
 144:             }
 145:             /*
 146: 			 *	Schedule the interrupt
 147: 			 */
 148:             if (ftp->ftt_state != AVAILABLE)    {
 149:                 u.u_error   = EBUSY;
 150:                 return;
 151:             }
 152:             ftp->ftt_state  = request.sigreq;
 153:             timeout(fttimeout, (caddr_t) ftp, request.timereq);
 154:             }
 155:             break;
 156: 
 157:         case FTIOCCANCEL:
 158:             (void) spl5();
 159:             if (ftp->ftt_state != AVAILABLE)
 160:                 ftp->ftt_state  = CANCELLED;
 161:             (void) spl0();
 162:             break;
 163: 
 164:         default:
 165:             u.u_error   = ENOTTY;
 166:             break;
 167:     }
 168: }
 169: 
 170: /*
 171:  *	Fttimeout
 172:  *
 173:  *	Called by system timeout
 174:  *
 175:  *	Verify that requesting process is still around
 176:  *	Verify that request hasn't been cancelled
 177:  *	Send the signal
 178:  */
 179: void
 180: fttimeout(ftp)
 181: register struct fttab   *ftp;
 182: {
 183:     register struct proc    *pp;
 184:     register prevstate;
 185: 
 186:     prevstate   = ftp->ftt_state;
 187:     ftp->ftt_state  = AVAILABLE;
 188: 
 189:     if ((prevstate == CANCELLED)
 190:       || ((pp = ftp->ftt_procp) == ((struct proc *) NULL))
 191:       || (pp->p_pid != ftp->ftt_pid))
 192:         return;
 193: 
 194: #ifdef  PARANOIA
 195:     if ((prevstate < 1) || (prevstate >= NSIG)) {
 196:         printf("ERR: fttimeout %d\n",prevstate);
 197:         return;
 198:     }
 199: #endif
 200:     psignal(pp, prevstate);
 201: }
 202: #endif

Defined functions

ftclose defined in line 66; never used
ftioctl defined in line 94; never used
ftopen defined in line 43; never used
fttimeout defined in line 179; used 2 times

Defined variables

fttab defined in line 30; used 3 times

Defined struct's

fttab defined in line 26; used 8 times

Defined macros

AVAILABLE defined in line 32; used 4 times
CANCELLED defined in line 33; used 2 times
MAXTIMEREQ defined in line 35; used 1 times
Last modified: 1983-08-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1071
Valid CSS Valid XHTML 1.0 Strict