Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
kccdist/lib/usys/uiodat.c
There are 6 other files named uiodat.c in the archive. Click here to see a list.
/* UIODAT - USYS I/O data definitions
**
** Copyright (c) 1987 by Ken Harrenstien & Ian Macky, SRI International
**
** This module contains declarations for various data structures needed by
** the USYS routines, particularly the I/O functions, which must be global.
** They are still "internal" from the viewpoint of the user and must not
** be referenced by anything but USYS calls.
*/
#include "c-env.h"
#include "sys/usysio.h"
#include "sys/usytty.h" /* Includes <sgtty.h> and <sys/ioctl.h> */
/*
* UFX (Unix File indeX) storage.
* We maintain a single active UFX for each operating-system
* channel/JFN. A UFX is separate from a FD so that we can have
* several FDs referencing the same UFX, as happens inside the UNIX
* kernel.
*
* FDs can be numbered from 0 to OPEN_MAX-1 inclusive, as on UNIX.
* UFXs are from 1 to OPEN_MAX inclusive, as it is easier to maintain
* the FD-to-UFX mapping table this way (a UFX value of 0 means the
* FD is unassigned).
*
* Ordinarily these arrays would be combined into
* a nice structure, but for better code generation (directly indexed
* arrays instead of computation+index) we are keeping them apart.
*
* The _uioufx table determines whether a FD is open or not.
* The _uionopen table determines whether a UFX is open or not.
* If not open ( >0), all other tables for that UFX are invalid.
*/
/* Per-FD storage. Only one such table, for mapping FD into UFX. */
int _uioufx[OPEN_MAX]; /* Indexed by FD, gets UFX! */
/* Per-UFX storage. */
int _uionopen [OPEN_MAX+1]; /* # of FDs which have this UFX open */
int _uioch [OPEN_MAX+1]; /* JFN for channel */
int _uiotype [OPEN_MAX+1]; /* OS device type (== major device #) */
int _uiodnum [OPEN_MAX+1]; /* USYS device number (== minor device #) */
int _uiobsize [OPEN_MAX+1]; /* byte-size file was opened in */
int _uioflgs [OPEN_MAX+1]; /* flag bits; can read with fcntl's F_GETFL */
int _uiocnt [OPEN_MAX+1]; /* count of chars left in buffer */
char *_uiocp [OPEN_MAX+1]; /* current pointer into buffer */
char *_uiopbuf[OPEN_MAX+1]; /* pointer to start of buffer */
long _uiopos [OPEN_MAX+1]; /* current position within file */
int _uioeof [OPEN_MAX+1]; /* EOF on channel */
/* See also the buffer code on following pages */
#if SYS_WAITS
struct bufhead _buffers[UIO_MAXFILE]; /* file I/O buffers */
int _uioeof; /* end of file reached on terminal */
#endif
/* Controlling TTY variables */
/* On T20/10X there can be only one controlling terminal
** (i.e. source of terminal interrupts). This is always _ttys[0].
** We only attempt full emulation for this terminal rather than for all
** TTY: devices, but up to _NTTYS-1 other random TTY devices are possible.
*/
#define ctl(a) (a&037)
struct _tty _ttys[_NTTYS]; /* Controlling TTY plus any others */
/* Default internal terminal structure, used to initialize _tty structs. */
struct _tty _deftty = {
0, 0, /* Zero UFX ensures more initialization */
#if SYS_T20+SYS_10X
0, 0, 0, 0, /* Various T20 words */
{-1,-1,'\177',ctl('U'),EVENP|ODDP|CRMOD|ECHO}, /* sgtty */
{-1, -1, ctl('Q'), ctl('S'), ctl('Z'), -1}, /* tchars */
NTTYDISC, 0, /* line disc, mode */
{ctl('C'),ctl('C'),ctl('R'),ctl('O'),ctl('W'),ctl('V')} /* ltchars */
#else /* Defaults as per BSD UNIX */
0, 0, 0, 0, /* Various words? */
{B9600, B9600, '#', '@', CRMOD|ECHO},
{'\177', ctl('\\'), ctl('Q'), ctl('S'), ctl('D'), -1},
OTTYDISC, 0,
{ctl('Z'),ctl('Y'),ctl('R'),ctl('O'),ctl('W'),ctl('V')}
#endif
};
/* I/O buffer data and routines.
** The I/O buffers are done as static data areas for
** now because the syscalls cannot invoke malloc() as needed.
*/
#ifndef NIOBUFS
#define NIOBUFS (OPEN_MAX/2)
#endif
struct iob {
int b_inuse;
char b_buf[UIO_BUFSIZ];
};
static struct iob _iob[NIOBUFS]; /* Gross! */
static struct iob *_getiob();
static void _freiob();
char *
_getbuf()
{
register struct iob *b;
if (b = _getiob())
return &b->b_buf[0];
return NULL;
}
static struct iob *
_getiob()
{
register int i;
register struct iob *b;
for (i = NIOBUFS, b = _iob; --i >= 0; ++b)
if (b->b_inuse == 0) {
b->b_inuse++;
return b;
}
return NULL; /* No more buffers */
}
void
_frebuf(bfp)
char *bfp;
{
_freiob((struct iob *)(bfp - sizeof(int)));
}
static void
_freiob(bp)
struct iob *bp;
{
bp->b_inuse = 0;
}