add part 2 of the WEGA kernel
This commit is contained in:
parent
4c0135e7e2
commit
97ed1f156c
|
|
@ -0,0 +1,362 @@
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1988
|
||||||
|
KERN 3.2 Modul: alloc.c
|
||||||
|
|
||||||
|
|
||||||
|
Bearbeiter:
|
||||||
|
Datum: $D$
|
||||||
|
Version: $R$
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#include <sys/filsys.h>
|
||||||
|
#include <sys/fblk.h>
|
||||||
|
#include <sys/conf.h>
|
||||||
|
#include <sys/buf.h>
|
||||||
|
#include <sys/inode.h>
|
||||||
|
#include <sys/ino.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#include <sys/mmu.h>
|
||||||
|
#include <sys/s.out.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
extern int Ninode;
|
||||||
|
extern int Nmount;
|
||||||
|
|
||||||
|
/*------------------------------------------ Typdefinitionen ----------------*/
|
||||||
|
|
||||||
|
typedef struct fblk *FBLKP;
|
||||||
|
|
||||||
|
/*------------------------------------------ Funktionen ---------------------*/
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* alloc
|
||||||
|
* alloc weist den naechsten verfuegbaren (freien) Diskblock aus der
|
||||||
|
* Freispeicherliste des Superblockes des entsprechenden Geraetes (dev) zu.
|
||||||
|
*
|
||||||
|
* Der Superblock enthaelt bis zu NICFREE freie Bloecke.
|
||||||
|
* Die letzte Eintragung verweist auf einen weiteren Ankerblock der
|
||||||
|
* Freispeicherliste.
|
||||||
|
* "no space on dev x/y" --> wenn die Freiliste erschoepft ist
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
struct buf *
|
||||||
|
alloc(dev)
|
||||||
|
dev_t dev;
|
||||||
|
{
|
||||||
|
daddr_t bno;
|
||||||
|
register struct filsys *fp;
|
||||||
|
register struct buf *bp;
|
||||||
|
|
||||||
|
fp = getfs(dev);
|
||||||
|
while(fp->s_flock)
|
||||||
|
sleep((caddr_t)&fp->s_flock, PINOD);
|
||||||
|
do {
|
||||||
|
if(fp->s_nfree <= 0)
|
||||||
|
goto nospace;
|
||||||
|
if (fp->s_nfree > NICFREE) {
|
||||||
|
prdev("Bad free count", dev);
|
||||||
|
goto nospace;
|
||||||
|
}
|
||||||
|
bno = fp->s_free[--fp->s_nfree];
|
||||||
|
if(bno == 0)
|
||||||
|
goto nospace;
|
||||||
|
} while (badblock(fp, bno, dev));
|
||||||
|
if(fp->s_nfree <= 0) {
|
||||||
|
fp->s_flock++;
|
||||||
|
bp = bread(dev, bno);
|
||||||
|
if ((bp->b_flags&B_ERROR) == 0) {
|
||||||
|
fp->s_nfree = ((FBLKP)(bp->b_un.b_addr))->df_nfree;
|
||||||
|
bcopy((caddr_t)((FBLKP)(bp->b_un.b_addr))->df_free,
|
||||||
|
(caddr_t)fp->s_free, sizeof(fp->s_free));
|
||||||
|
}
|
||||||
|
brelse(bp);
|
||||||
|
fp->s_flock = 0;
|
||||||
|
wakeup((caddr_t)&fp->s_flock);
|
||||||
|
if (fp->s_nfree <=0)
|
||||||
|
goto nospace;
|
||||||
|
}
|
||||||
|
bp = getblk(dev, bno);
|
||||||
|
clrbuf(bp);
|
||||||
|
if(fp->s_tfree) /* Decrem. freelist-counter */
|
||||||
|
fp->s_tfree--;
|
||||||
|
fp->s_fmod = 1;
|
||||||
|
return(bp);
|
||||||
|
|
||||||
|
nospace:
|
||||||
|
fp->s_nfree = 0;
|
||||||
|
fp->s_tfree = 0; /* Total Free Blocks zero */
|
||||||
|
prdev("no space", dev);
|
||||||
|
u.u_error = ENOSPC;
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* free
|
||||||
|
* Rueckketten des Blockes (bno) in die Freispeicherliste des
|
||||||
|
* Superblockes des entsprechenden Geraetes (dev)
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
free(dev, bno)
|
||||||
|
dev_t dev;
|
||||||
|
daddr_t bno;
|
||||||
|
{
|
||||||
|
register struct filsys *fp;
|
||||||
|
register struct buf *bp;
|
||||||
|
|
||||||
|
fp = getfs(dev);
|
||||||
|
fp->s_fmod = 1;
|
||||||
|
while(fp->s_flock)
|
||||||
|
sleep((caddr_t)&fp->s_flock, PINOD);
|
||||||
|
if (badblock(fp, bno, dev))
|
||||||
|
return;
|
||||||
|
if(fp->s_nfree <= 0) {
|
||||||
|
fp->s_nfree = 1;
|
||||||
|
fp->s_free[0] = 0;
|
||||||
|
}
|
||||||
|
if(fp->s_nfree >= NICFREE) {
|
||||||
|
fp->s_flock++;
|
||||||
|
bp = getblk(dev, bno);
|
||||||
|
((FBLKP)(bp->b_un.b_addr))->df_nfree = fp->s_nfree;
|
||||||
|
bcopy((caddr_t)fp->s_free,
|
||||||
|
(caddr_t)((FBLKP)(bp->b_un.b_addr))->df_free,
|
||||||
|
sizeof(fp->s_free));
|
||||||
|
fp->s_nfree = 0;
|
||||||
|
bwrite(bp);
|
||||||
|
fp->s_flock = 0;
|
||||||
|
wakeup((caddr_t)&fp->s_flock);
|
||||||
|
}
|
||||||
|
fp->s_free[fp->s_nfree++] = bno;
|
||||||
|
fp->s_tfree++; /* Total Free Blocks */
|
||||||
|
fp->s_fmod = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* badblock
|
||||||
|
* Test, ob Blocknummer bn zwischen dem Ende der I-Liste und dem
|
||||||
|
* ersten nicht vorhandenen Block des Geraetes (dev) liegt
|
||||||
|
* Wird hauptsaechlich genutzt, um zu kontrollieren, ob ein "Garbage"-
|
||||||
|
* Filesystem gemounted ist
|
||||||
|
* "bad block on dev x/y" ==> Blck liegt ausserhalb zulaess. Bereich
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
badblock(fp, bn, dev)
|
||||||
|
register struct filsys *fp;
|
||||||
|
register daddr_t bn;
|
||||||
|
dev_t dev;
|
||||||
|
{
|
||||||
|
|
||||||
|
if (bn < fp->s_isize || bn >= fp->s_fsize) {
|
||||||
|
prdev("bad block", dev);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* ialloc
|
||||||
|
* Weist einen unbenutzten Inode aus der Inode-Freiliste des Superblockes
|
||||||
|
* fuer das angegebene Geraet (dev) zu und stellt ihn in der Inode-Tabelle
|
||||||
|
* bereit
|
||||||
|
* Wird zur File-Kreation benoetigt
|
||||||
|
* Der Algorithmus durchlaeuft die Inodes, die im Superblock eingetragen
|
||||||
|
* sind (NICINODE Stueck). Wenn diese nicht ausreichen, so erfolgt eine
|
||||||
|
* lineare Suche durch die Inodes in den Inode-Bloecken des Geraetes,
|
||||||
|
* um NICINODE freie Inodes bereitzustellen
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
struct inode *
|
||||||
|
ialloc(dev)
|
||||||
|
dev_t dev;
|
||||||
|
{
|
||||||
|
register struct filsys *fp;
|
||||||
|
register struct buf *bp;
|
||||||
|
register struct inode *ip;
|
||||||
|
int i;
|
||||||
|
struct dinode *dp;
|
||||||
|
ino_t ino;
|
||||||
|
daddr_t adr;
|
||||||
|
|
||||||
|
fp = getfs(dev);
|
||||||
|
while(fp->s_ilock)
|
||||||
|
sleep((caddr_t)&fp->s_ilock, PINOD);
|
||||||
|
loop:
|
||||||
|
if(fp->s_ninode > 0) {
|
||||||
|
ino = fp->s_inode[--fp->s_ninode];
|
||||||
|
if (ino < ROOTINO)
|
||||||
|
goto loop;
|
||||||
|
ip = iget(dev, ino);
|
||||||
|
if(ip == NULL)
|
||||||
|
return(NULL);
|
||||||
|
if(ip->i_mode == 0) {
|
||||||
|
for (i=0; i<NADDR; i++)
|
||||||
|
ip->i_blks.i_p.i_a[i] = 0;
|
||||||
|
if(fp->s_tinode) /* Decr. Inode Counter */
|
||||||
|
fp->s_tinode--;
|
||||||
|
fp->s_fmod = 1;
|
||||||
|
return(ip);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Inode was allocated after all.
|
||||||
|
* Look some more.
|
||||||
|
*/
|
||||||
|
iput(ip);
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
fp->s_ilock++;
|
||||||
|
ino = 1;
|
||||||
|
for(adr = SUPERB+1; adr < fp->s_isize; adr++) {
|
||||||
|
bp = bread(dev, adr);
|
||||||
|
if (bp->b_flags & B_ERROR) {
|
||||||
|
brelse(bp);
|
||||||
|
ino += INOPB;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dp = bp->b_un.b_dino;
|
||||||
|
for(i=0; i<INOPB; i++) {
|
||||||
|
if(dp->di_mode != 0)
|
||||||
|
goto cont;
|
||||||
|
for(ip = &inode[0]; ip < &inode[Ninode]; ip++)
|
||||||
|
if(dev==ip->i_dev && ino==ip->i_number)
|
||||||
|
goto cont;
|
||||||
|
fp->s_inode[fp->s_ninode++] = ino;
|
||||||
|
if(fp->s_ninode >= NICINOD)
|
||||||
|
break;
|
||||||
|
cont:
|
||||||
|
ino++;
|
||||||
|
dp++;
|
||||||
|
}
|
||||||
|
brelse(bp);
|
||||||
|
if(fp->s_ninode >= NICINOD)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fp->s_ilock = 0;
|
||||||
|
wakeup((caddr_t)&fp->s_ilock);
|
||||||
|
if(fp->s_ninode > 0)
|
||||||
|
goto loop;
|
||||||
|
prdev("Out of inodes", dev);
|
||||||
|
u.u_error = ENOSPC;
|
||||||
|
fp->s_tinode = 0; /* Clear Inode Counter */
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* ifree
|
||||||
|
* Freigabe der spezifizierten Inode-Nr.(ino) auf dem spezifizierten Device
|
||||||
|
* Der Algorithmus speichert bis zu NICINOD Inodes im Superblock ab; folgende
|
||||||
|
* Inodes werden uebergangen
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
ifree(dev, ino)
|
||||||
|
dev_t dev;
|
||||||
|
ino_t ino;
|
||||||
|
{
|
||||||
|
register struct filsys *fp;
|
||||||
|
|
||||||
|
fp = getfs(dev);
|
||||||
|
fp->s_tinode++; /* Total free inodes */
|
||||||
|
if(fp->s_ilock)
|
||||||
|
return;
|
||||||
|
if(fp->s_ninode >= NICINOD)
|
||||||
|
return;
|
||||||
|
fp->s_inode[fp->s_ninode++] = ino;
|
||||||
|
fp->s_fmod = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* getfs
|
||||||
|
* Bereitstellen eines Pointers auf den im Kern befindlichen Superblock
|
||||||
|
* fuer eine angegebene Devicenummer "dev"
|
||||||
|
* Der Alogorithmus stellt eine lineare Suche durch die Mount-Tabelle dar.
|
||||||
|
* Konsistenzcheck der sich im Kern befindenden Freispeicherliste und des
|
||||||
|
* Inode-Zaehlers
|
||||||
|
*
|
||||||
|
* "bad count on dev x/y" --> fehlerhafter Inode-Check
|
||||||
|
* Ab diesem Punkt werden die Inode- Zaehler auf Null gesetzt, was immer
|
||||||
|
* zu der Diagnose - Ausschrift "no space" fuehrt
|
||||||
|
* "panic: no fs" --> Device ist nicht gemounted.
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
struct filsys *
|
||||||
|
getfs(dev)
|
||||||
|
dev_t dev;
|
||||||
|
{
|
||||||
|
register struct mount *mp;
|
||||||
|
register struct filsys *fp;
|
||||||
|
struct filsys *fp1; /* ??? 4 Byte */
|
||||||
|
|
||||||
|
for(mp = &mount[0]; mp < &mount[Nmount]; mp++)
|
||||||
|
if(mp->m_bufp != NULL && mp->m_dev == dev) {
|
||||||
|
fp = mp->m_bufp->b_un.b_filsys;
|
||||||
|
if(fp->s_nfree > NICFREE || fp->s_ninode > NICINOD) {
|
||||||
|
prdev("bad count", dev);
|
||||||
|
fp->s_nfree = 0;
|
||||||
|
fp->s_ninode = 0;
|
||||||
|
}
|
||||||
|
return(fp);
|
||||||
|
}
|
||||||
|
panic("no fs");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* update
|
||||||
|
* update ist der interne Name von 'sync;
|
||||||
|
* -durchlaeuft Disk-Queues zur Aktualisierung zwischengepufferter I/O-Bloecke
|
||||||
|
* -durchlaeuft Inodes zum Schreiben modifizierter Inodes
|
||||||
|
* -durchlaeuft Mount-Tabelle zur Aktualiseirung modifizierter Superbloecke
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
update()
|
||||||
|
{
|
||||||
|
register struct inode *ip;
|
||||||
|
register struct mount *mp;
|
||||||
|
register struct buf *bp;
|
||||||
|
struct buf *bp1; /* 4 Byte recomp ???? */
|
||||||
|
struct filsys *fp;
|
||||||
|
int fcw;
|
||||||
|
|
||||||
|
if(updlock)
|
||||||
|
return;
|
||||||
|
updlock++;
|
||||||
|
for(mp = &mount[0]; mp < &mount[Nmount]; mp++)
|
||||||
|
if(mp->m_bufp != NULL) {
|
||||||
|
fp = mp->m_bufp->b_un.b_filsys;
|
||||||
|
if(fp->s_fmod==0 || fp->s_ilock!=0 ||
|
||||||
|
fp->s_flock!=0 || fp->s_ronly!=0)
|
||||||
|
continue;
|
||||||
|
bp = getblk(mp->m_dev, SUPERB);
|
||||||
|
if (bp->b_flags & B_ERROR)
|
||||||
|
continue;
|
||||||
|
fp->s_fmod = 0;
|
||||||
|
fp->s_time = time;
|
||||||
|
bcopy((caddr_t)fp, bp->b_un.b_addr, BSIZE);
|
||||||
|
bwrite(bp);
|
||||||
|
}
|
||||||
|
for(ip = &inode[0]; ip < &inode[Ninode]; ip++) {
|
||||||
|
fcw=dvi();
|
||||||
|
if((ip->i_flag&ILOCK)==0 && ip->i_count) {
|
||||||
|
ip->i_flag |= ILOCK;
|
||||||
|
ip->i_count++;
|
||||||
|
iupdat(ip, &time, &time);
|
||||||
|
iput(ip);
|
||||||
|
}
|
||||||
|
rvi(fcw);
|
||||||
|
}
|
||||||
|
updlock = 0;
|
||||||
|
bflush(NODEV);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,312 @@
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/state.h>
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/callo.h>
|
||||||
|
#include <sys/mmu.h>
|
||||||
|
#include <sys/s.out.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
#include <sys/proc.h>
|
||||||
|
#include <sys/text.h>
|
||||||
|
|
||||||
|
#define sreg state->s_reg
|
||||||
|
#define eventid state->s_eventid
|
||||||
|
#define ps state->s_ps
|
||||||
|
#define pcseg state->s_pcseg
|
||||||
|
#define pc state->s_pc
|
||||||
|
|
||||||
|
#define NBPTS 5
|
||||||
|
#define NBPL 16
|
||||||
|
#define UMASK 0x3f00ffffL
|
||||||
|
#define KMASK 0x7f00ffffL
|
||||||
|
#define HMASK (unsigned char)0x0f
|
||||||
|
|
||||||
|
extern char *zpr();
|
||||||
|
extern mmut;
|
||||||
|
extern fubyte(), fpbyte(), fkbyte();
|
||||||
|
extern getchar();
|
||||||
|
int kdebug;
|
||||||
|
static char kdbstr[6];
|
||||||
|
char hzif[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
|
||||||
|
static unsigned char format[18];
|
||||||
|
static unsigned int kval;
|
||||||
|
static struct {
|
||||||
|
unsigned a;
|
||||||
|
union {
|
||||||
|
unsigned int *b;
|
||||||
|
struct {
|
||||||
|
unsigned short b;
|
||||||
|
unsigned short c;
|
||||||
|
} l;
|
||||||
|
} b;
|
||||||
|
unsigned d;
|
||||||
|
unsigned e;
|
||||||
|
} breakpt[NBPTS];
|
||||||
|
|
||||||
|
long
|
||||||
|
gethex()
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
long val;
|
||||||
|
|
||||||
|
for (val = 0; ; )
|
||||||
|
if (c = getchar()){
|
||||||
|
if ((c >= 'A') && (c <= 'F'))
|
||||||
|
c = c - 0x37;
|
||||||
|
else if ((c >= 'a') && (c <= 'f'))
|
||||||
|
c = c - 0x57;
|
||||||
|
else if ((c >= '0') && (c <= '9'))
|
||||||
|
c -= 0x30;
|
||||||
|
else return(val);
|
||||||
|
val = (val << 4) + (long)c;
|
||||||
|
}
|
||||||
|
else return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
zpr(hval)
|
||||||
|
unsigned int hval;
|
||||||
|
{
|
||||||
|
unsigned int h;
|
||||||
|
char *phzif;
|
||||||
|
|
||||||
|
phzif = hzif;
|
||||||
|
h = hval;
|
||||||
|
kdbstr[0] = phzif[(unsigned char)((int)h >> 12 & HMASK)];
|
||||||
|
kdbstr[1] = phzif[(unsigned char)((int)h >> 8 & HMASK)];
|
||||||
|
kdbstr[2] = phzif[(unsigned char)((int)h >> 4 & HMASK)];
|
||||||
|
kdbstr[3] = phzif[(unsigned char)((int)h & HMASK)];
|
||||||
|
kdbstr[4] = 0;
|
||||||
|
return (kdbstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug(state)
|
||||||
|
struct state *state;
|
||||||
|
{
|
||||||
|
caddr_t dadr;
|
||||||
|
unsigned int *kadr;
|
||||||
|
int s, v2, v1;
|
||||||
|
int ic;
|
||||||
|
int bp_cnt, event;
|
||||||
|
unsigned long acount, count;
|
||||||
|
int (*sad)();
|
||||||
|
struct segd sdrf;
|
||||||
|
unsigned char attr;
|
||||||
|
|
||||||
|
if (!kdebug)
|
||||||
|
return;
|
||||||
|
s = dvi();
|
||||||
|
event = eventid & 0xff;
|
||||||
|
bp_cnt = NBPTS;
|
||||||
|
if (event == 2){
|
||||||
|
for (bp_cnt = 0; bp_cnt < NBPTS; bp_cnt++)
|
||||||
|
if ((breakpt[bp_cnt].a) &&
|
||||||
|
(hiword(breakpt[bp_cnt].b) == (pcseg & USEGW)) &&
|
||||||
|
(breakpt[bp_cnt].b.l.c == (pc -2)))
|
||||||
|
break;
|
||||||
|
if (bp_cnt >= NBPTS)
|
||||||
|
printf("KDB: Unset breakpoint\n");
|
||||||
|
else {
|
||||||
|
breakpt[bp_cnt].a = 0;
|
||||||
|
kadr = breakpt[bp_cnt].b.b;
|
||||||
|
printf("KDB: @%X Breakpoint",breakpt[bp_cnt].b.b);
|
||||||
|
getsd(mmut, hibyte(kadr), &sdrf);
|
||||||
|
attr = sdrf.sg_attr;
|
||||||
|
sdrf.sg_attr &= 0xfe;
|
||||||
|
loadsd(mmut, hibyte(kadr), &sdrf);
|
||||||
|
*kadr = breakpt[bp_cnt].d;
|
||||||
|
sdrf.sg_attr = attr;
|
||||||
|
loadsd(mmut, hibyte(kadr), &sdrf);
|
||||||
|
pc -= (unsigned) 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (1){
|
||||||
|
printf("KDB>\007");
|
||||||
|
ic = getchar();
|
||||||
|
switch(ic){
|
||||||
|
case 'J':
|
||||||
|
case 'j':
|
||||||
|
{ printf("ump call to @");
|
||||||
|
sad = (int (*)())(((unsigned long)gethex()) & KMASK), (*sad)();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{ putchar('\n');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'B':
|
||||||
|
case 'b':
|
||||||
|
{ printf("reak point @");
|
||||||
|
kadr = (unsigned int *)((gethex() & UMASK) & KMASK);
|
||||||
|
for (bp_cnt = 0; breakpt[bp_cnt].a && ++bp_cnt<NBPTS; );
|
||||||
|
if (bp_cnt >= NBPTS){
|
||||||
|
printf("KDB: No more break slots\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
breakpt[bp_cnt].a = 1;
|
||||||
|
breakpt[bp_cnt].b.b = kadr;
|
||||||
|
breakpt[bp_cnt].d = *kadr;
|
||||||
|
getsd(mmut, hibyte(kadr), &sdrf);
|
||||||
|
attr = sdrf.sg_attr;
|
||||||
|
sdrf.sg_attr &= ~RD_AT;
|
||||||
|
loadsd(mmut, hibyte(kadr), &sdrf);
|
||||||
|
if (!(skbyte(kadr, 0x7f)) && /* 7f02 break */
|
||||||
|
(skbyte((((char *)kadr)+1), 0x02))){
|
||||||
|
printf(" FAULT ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sdrf.sg_attr = attr;
|
||||||
|
loadsd(mmut, hibyte(kadr), &sdrf);
|
||||||
|
break;
|
||||||
|
} /* von break - Routine */
|
||||||
|
case 'U':
|
||||||
|
case 'u':
|
||||||
|
{ printf("ser space d");
|
||||||
|
sad = fubyte;
|
||||||
|
goto Mdisplay;
|
||||||
|
} /* von user - Routine */
|
||||||
|
case 'P':
|
||||||
|
case 'p':
|
||||||
|
{ printf("hysical space d");
|
||||||
|
sad = fpbyte;
|
||||||
|
goto Mdisplay;
|
||||||
|
}
|
||||||
|
case 'D':
|
||||||
|
case 'd':
|
||||||
|
{ sad = fkbyte;
|
||||||
|
Mdisplay: printf("isplay @");
|
||||||
|
dadr = (caddr_t)(gethex() & KMASK);
|
||||||
|
printf("for ");
|
||||||
|
count = gethex();
|
||||||
|
printf("words\n");
|
||||||
|
v1 = 0;
|
||||||
|
count = (((unsigned long)(count + 7L))>>3)<<3;
|
||||||
|
for (acount = 0; acount < count; acount++){
|
||||||
|
if (!(v1)){
|
||||||
|
if(acount)
|
||||||
|
printf("\n");
|
||||||
|
printf("%s", zpr(hiword(dadr)));
|
||||||
|
printf("%s: ", zpr(loword(dadr)));
|
||||||
|
}
|
||||||
|
if ((*sad)(dadr, &format[v1])){
|
||||||
|
printf(" FAULT ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
kval = format[v1]<<8;
|
||||||
|
if ((format[v1] < ' ') ||
|
||||||
|
(format[v1] > '~'))
|
||||||
|
format[v1] = ' ';
|
||||||
|
v1++;
|
||||||
|
dadr++;
|
||||||
|
if ((*sad)(dadr, &format[v1])){
|
||||||
|
printf(" FAULT ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
kval |= format[v1];
|
||||||
|
if ((format[v1] < ' ') ||
|
||||||
|
(format[v1] > '~'))
|
||||||
|
format[v1] = ' ';
|
||||||
|
v1++;
|
||||||
|
dadr++;
|
||||||
|
printf("%s ", zpr(kval));
|
||||||
|
if (!(v1 % 0x10)){
|
||||||
|
printf(" |%s|", format);
|
||||||
|
v1 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'M':
|
||||||
|
case 'm':
|
||||||
|
{ printf("odify ");
|
||||||
|
switch((getchar())){
|
||||||
|
case 'R':
|
||||||
|
case 'r':
|
||||||
|
{ printf("egister ");
|
||||||
|
count = gethex();
|
||||||
|
printf("(%s) with ", (char *)zpr(sreg[count]));
|
||||||
|
v2 = ((unsigned int)gethex());
|
||||||
|
printf("OK ");
|
||||||
|
switch(getchar()){
|
||||||
|
case 'Y':
|
||||||
|
case 'y':
|
||||||
|
sreg[count] = v2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'M':
|
||||||
|
case 'm':
|
||||||
|
{ printf("emory @");
|
||||||
|
kadr = (unsigned int *)(gethex() & KMASK);
|
||||||
|
printf("(%s) with ", zpr(*kadr));
|
||||||
|
v2 = ((unsigned int)gethex());
|
||||||
|
printf("OK ");
|
||||||
|
switch(getchar()){
|
||||||
|
{ case 'Y':
|
||||||
|
case 'y':
|
||||||
|
getsd(mmut, hibyte(kadr), &sdrf);
|
||||||
|
attr = sdrf.sg_attr;
|
||||||
|
sdrf.sg_attr &= ~RD_AT;
|
||||||
|
loadsd(mmut, hibyte(kadr), &sdrf);
|
||||||
|
if ((!(skbyte(kadr, hibyte(v2)))) &&
|
||||||
|
(skbyte(((char *)kadr+1), hibyte(v2)))){
|
||||||
|
printf(" FAULT ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sdrf.sg_attr = attr;
|
||||||
|
loadsd(mmut, hibyte(kadr), &sdrf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} /* von memory - Routine */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} /* von modify - Routine */
|
||||||
|
case 'R':
|
||||||
|
case 'r':
|
||||||
|
{ printf("egisters\n");
|
||||||
|
for (acount = 0; acount < 16; acount++){
|
||||||
|
if (!(acount & 7))
|
||||||
|
putchar('\n');
|
||||||
|
printf("r%d:%s ", zpr(sreg[acount]));
|
||||||
|
}
|
||||||
|
printf("\nfcw=%s ", zpr(ps));
|
||||||
|
printf("pcseg=%s ", zpr(pcseg));
|
||||||
|
printf("pcoff=%s", zpr(pc));
|
||||||
|
break;
|
||||||
|
} /* von register - Routine */
|
||||||
|
case 'S':
|
||||||
|
case 's':
|
||||||
|
{ printf("ingle step\n");
|
||||||
|
ps |= TBIT;
|
||||||
|
rvi(s);
|
||||||
|
return(1);
|
||||||
|
} /* von step - Routine */
|
||||||
|
case 'T':
|
||||||
|
case 't':
|
||||||
|
{ printf("ape crash dump\n");
|
||||||
|
printf("writable tape loaded in drive 0? ");
|
||||||
|
switch(getchar()){
|
||||||
|
{ case 'Y':
|
||||||
|
case 'y':
|
||||||
|
dump(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'C':
|
||||||
|
case 'c':
|
||||||
|
{ printf("ontinue\n");
|
||||||
|
rvi(s);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
case 'E':
|
||||||
|
case 'e':
|
||||||
|
{ printf("xit\n");
|
||||||
|
rvi(s);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
} /* von switch */
|
||||||
|
} /* von while (1) */
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,309 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1988
|
||||||
|
KERN 3.2 Modul: fio.c
|
||||||
|
|
||||||
|
|
||||||
|
Bearbeiter:
|
||||||
|
Datum: $D$
|
||||||
|
Version: $R$
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#include <sys/filsys.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <sys/conf.h>
|
||||||
|
#include <sys/inode.h>
|
||||||
|
#include <sys/acct.h>
|
||||||
|
#include <sys/mmu.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#include <sys/s.out.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
extern int Nfile;
|
||||||
|
extern int Nmount;
|
||||||
|
|
||||||
|
/*------------------------------------------ Funktionen ---------------------*/
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* getf
|
||||||
|
* Konvertiert einen vom Nutzer gelieferten Dateidescriptor in der
|
||||||
|
* Nutzer-Dateidescriptortabelle (u.u_ofile) in einen Zeiger auf eine
|
||||||
|
* file-Struktur in der Dateitabelle (file[])
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
struct file *
|
||||||
|
getf(f)
|
||||||
|
register int f;
|
||||||
|
{
|
||||||
|
register struct file *fp;
|
||||||
|
|
||||||
|
if(0 <= f && f < NOFILE) {
|
||||||
|
fp = u.u_ofile[f];
|
||||||
|
if(fp != NULL)
|
||||||
|
return(fp);
|
||||||
|
}
|
||||||
|
u.u_error = EBADF;
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* closef
|
||||||
|
* - interne Form von close
|
||||||
|
* - dekrementiert den Datei-Referenzzaehler der file-Struktur
|
||||||
|
* - sichert, dass das pipe-Protokoll nicht verstopft ist
|
||||||
|
*
|
||||||
|
* - dekrementiert den Inode-Referenzszaehler, um die Freigabe der
|
||||||
|
* zugehoerigen Filestruktur zu verfolgen
|
||||||
|
* - ruft den Device-Handler beim letzten close auf
|
||||||
|
* Beachte: Der Device-Handler wird bei jedem Open aber nur beim letzten
|
||||||
|
* Close aufgerufen
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
closef(fp)
|
||||||
|
register struct file *fp;
|
||||||
|
{
|
||||||
|
register struct inode *ip;
|
||||||
|
struct mount *mp;
|
||||||
|
int flag, fmt;
|
||||||
|
dev_t dev;
|
||||||
|
int (*cfunc)();
|
||||||
|
|
||||||
|
if (fp == NULL)
|
||||||
|
return;
|
||||||
|
unlock(fp->f_inode);
|
||||||
|
if ((unsigned)fp->f_count > 1) {
|
||||||
|
fp->f_count--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ip = fp->f_inode;
|
||||||
|
plock(ip);
|
||||||
|
flag = fp->f_flag;
|
||||||
|
dev = (dev_t)ip->i_rdev;
|
||||||
|
fmt = ip->i_mode&IFMT;
|
||||||
|
fp->f_count = 0;
|
||||||
|
switch(fmt) {
|
||||||
|
|
||||||
|
case IFCHR:
|
||||||
|
cfunc = cdevsw[major(dev)].d_close;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IFBLK:
|
||||||
|
cfunc = bdevsw[major(dev)].d_close;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IFIFO:
|
||||||
|
closep(ip, flag);
|
||||||
|
|
||||||
|
default:
|
||||||
|
iput(ip);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (fp = file; fp < &file[Nfile]; fp++) {
|
||||||
|
register struct inode *tip;
|
||||||
|
|
||||||
|
if (fp->f_count) {
|
||||||
|
tip = fp->f_inode;
|
||||||
|
if (tip->i_rdev == dev &&
|
||||||
|
(tip->i_mode&IFMT) == fmt)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fmt == IFBLK) {
|
||||||
|
for (mp = mount; mp < &mount[Nmount]; mp++)
|
||||||
|
if (mp->m_flags == MINUSE && mp->m_dev == dev)
|
||||||
|
goto out;
|
||||||
|
bflush(dev);
|
||||||
|
(*cfunc)(dev, flag);
|
||||||
|
binval(dev);
|
||||||
|
} else {
|
||||||
|
prele(ip);
|
||||||
|
(*cfunc)(dev, flag);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
iput(ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* openi
|
||||||
|
* Ausfuehrung OPEN-Aktion
|
||||||
|
* wird aufgerufen, um dem Handler von special files die Moeglichkeit zur
|
||||||
|
* Initialisierung und Validisierung zu geben, bevor aktuelle I/O folgen
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
openi(ip, flag)
|
||||||
|
register struct inode *ip;
|
||||||
|
{
|
||||||
|
dev_t dev;
|
||||||
|
register unsigned int maj;
|
||||||
|
|
||||||
|
dev = (dev_t)ip->i_rdev;
|
||||||
|
maj = major(dev);
|
||||||
|
switch(ip->i_mode&IFMT) {
|
||||||
|
|
||||||
|
case IFCHR:
|
||||||
|
if (maj >= nchrdev)
|
||||||
|
goto bad;
|
||||||
|
if (u.u_ttyp == NULL)
|
||||||
|
u.u_ttyd = dev;
|
||||||
|
(*cdevsw[maj].d_open)(dev, flag);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IFBLK:
|
||||||
|
if (maj >= nblkdev)
|
||||||
|
goto bad;
|
||||||
|
(*bdevsw[maj].d_open)(dev, flag);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IFIFO:
|
||||||
|
openp(ip, flag);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
bad:
|
||||||
|
u.u_error = ENXIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
/* access
|
||||||
|
* Kontrolle Zugriffsrechte auf einen Inode Pointer
|
||||||
|
* Mode ist READ, WRITE oder EXEC
|
||||||
|
* WRITE: Read-only Status des Files wird gecheckt;
|
||||||
|
* reine Textsegmente koennen nicht geschrieben werden
|
||||||
|
* Der Mode wird verschoben, um die owner/group/other-Felder
|
||||||
|
* zu selektieren
|
||||||
|
* Der Superuser hat alle Zugriffsrechte
|
||||||
|
*/
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
access(ip, mode)
|
||||||
|
register struct inode *ip;
|
||||||
|
{
|
||||||
|
register m;
|
||||||
|
|
||||||
|
m = mode;
|
||||||
|
if (m == IWRITE) {
|
||||||
|
if (getfs(ip->i_dev)->s_ronly) {
|
||||||
|
u.u_error = EROFS;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
if (ip->i_flag&ITEXT)
|
||||||
|
xrele(ip);
|
||||||
|
if (ip->i_flag & ITEXT) {
|
||||||
|
u.u_error = ETXTBSY;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (u.u_uid == 0)
|
||||||
|
return(0);
|
||||||
|
if (u.u_uid != ip->i_uid) {
|
||||||
|
m >>= 3;
|
||||||
|
if (u.u_gid != ip->i_gid)
|
||||||
|
m >>= 3;
|
||||||
|
}
|
||||||
|
if ((ip->i_mode&m) != 0)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
u.u_error = EACCES;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
|
/* owner
|
||||||
|
* Absteigen Pfadnamen und Test, ob die resultierende Inode dem
|
||||||
|
* aktuellen Nutzer gehoert. Wenn nicht, Test auf Superuser
|
||||||
|
* Ist Zugriff erlaubt, Rueckgabee des Inode-Pointers
|
||||||
|
*/
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
|
struct inode *
|
||||||
|
owner()
|
||||||
|
{
|
||||||
|
register struct inode *ip;
|
||||||
|
|
||||||
|
ip = namei(uchar, 0);
|
||||||
|
if (ip == NULL)
|
||||||
|
return(NULL);
|
||||||
|
if (u.u_uid == ip->i_uid )
|
||||||
|
return(ip);
|
||||||
|
if( suser())
|
||||||
|
return(ip);
|
||||||
|
iput(ip);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* Test, ob der aktuelle Nutzer der Superuser ist
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------*/
|
||||||
|
suser()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (u.u_uid == 0) {
|
||||||
|
u.u_acflag |= ASU;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
u.u_error = EPERM;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* Zuweisung eines User Filedescriptors
|
||||||
|
*/
|
||||||
|
/*----------------------------------------------*/
|
||||||
|
ufalloc(i)
|
||||||
|
register i;
|
||||||
|
{
|
||||||
|
|
||||||
|
for(; i<NOFILE; i++)
|
||||||
|
if (u.u_ofile[i] == NULL) {
|
||||||
|
u.u_r.r_val.r_val1 = i;
|
||||||
|
u.u_pofile[i] = 0;
|
||||||
|
return(i);
|
||||||
|
}
|
||||||
|
u.u_error = EMFILE;
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------*/
|
||||||
|
/* falloc
|
||||||
|
* Zuweisung eines User-Filedescriptors und einer Filestruktur
|
||||||
|
* Initialisierung des Descriptors, so dass er auf die File-
|
||||||
|
* struktur verweist
|
||||||
|
*
|
||||||
|
* (kein File,wenn keine Filestruktur verfuegbar)
|
||||||
|
*/
|
||||||
|
/*----------------------------------------------------------*/
|
||||||
|
struct file *
|
||||||
|
falloc()
|
||||||
|
{
|
||||||
|
register struct file *fp;
|
||||||
|
struct file *fp1; /* nicht notwendig;==> */
|
||||||
|
/* BYTE-KOMPATIBILITAET*/
|
||||||
|
register i;
|
||||||
|
|
||||||
|
i = ufalloc(0);
|
||||||
|
if (i < 0)
|
||||||
|
return(NULL);
|
||||||
|
for(fp = &file[0]; fp < &file[Nfile]; fp++)
|
||||||
|
if (fp->f_count == 0) {
|
||||||
|
u.u_ofile[i] = fp;
|
||||||
|
fp->f_count++;
|
||||||
|
fp->f_offset = 0;
|
||||||
|
return(fp);
|
||||||
|
}
|
||||||
|
printf("no file\n");
|
||||||
|
/*syserr.fileovf++;*/
|
||||||
|
u.u_error = ENFILE;
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,341 @@
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#include <sys/inode.h>
|
||||||
|
#include <sys/ino.h>
|
||||||
|
#include <sys/filsys.h>
|
||||||
|
#include <sys/conf.h>
|
||||||
|
#include <sys/buf.h>
|
||||||
|
#include <sys/mmu.h>
|
||||||
|
#include <sys/s.out.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
extern int Ninode;
|
||||||
|
extern int Nmount;
|
||||||
|
|
||||||
|
char igetwstr[]="@[$]iget.c Rev : 4.1 08/27/83 11:54:46";
|
||||||
|
|
||||||
|
struct inode *ihash[INOHSZ] = 0 ;
|
||||||
|
struct inode *ifreelist;
|
||||||
|
|
||||||
|
ihinit()
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
register struct inode *ip;
|
||||||
|
|
||||||
|
ifreelist = inode;
|
||||||
|
for(ip=inode; ip < &inode[Ninode-1]; ip++)
|
||||||
|
ip->i_link = (struct inode *) ip+1;
|
||||||
|
ip->i_link = (struct inode *) 0;
|
||||||
|
for(i=0;i< INOHSZ;i++)
|
||||||
|
ihash[i] = (struct inode *) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct inode *
|
||||||
|
ifind(idev,inum)
|
||||||
|
register dev_t idev;
|
||||||
|
register ino_t inum;
|
||||||
|
{
|
||||||
|
register struct inode *ip;
|
||||||
|
|
||||||
|
ip=ihash[INOHASH(idev,inum)];
|
||||||
|
while(ip !=(struct inode *)0) {
|
||||||
|
if(inum == ip->i_number && idev == ip->i_dev)
|
||||||
|
return(ip);
|
||||||
|
ip=ip->i_link;
|
||||||
|
}
|
||||||
|
return((struct inode *)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct inode *
|
||||||
|
iget(dev, ino)
|
||||||
|
register dev_t dev;
|
||||||
|
register ino_t ino;
|
||||||
|
{
|
||||||
|
register struct inode *ip;
|
||||||
|
register struct mount *mp;
|
||||||
|
register h_index;
|
||||||
|
register struct buf *bp;
|
||||||
|
register struct dinode *dp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sysinfo.iget++;
|
||||||
|
loop:
|
||||||
|
h_index = INOHASH(dev, ino);
|
||||||
|
for(ip=ihash[h_index];ip!=(struct inode *) 0;ip=ip->i_link) {
|
||||||
|
if(ino == ip->i_number && dev == ip->i_dev) {
|
||||||
|
while((ip->i_flag & ILOCK) != 0) {
|
||||||
|
ip->i_flag |= IWANT;
|
||||||
|
sleep((caddr_t)ip, PINOD);
|
||||||
|
if(ino == ip->i_number && dev == ip->i_dev)
|
||||||
|
continue;
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
if((ip->i_flag & IMOUNT) !=0) {
|
||||||
|
for(mp = &mount[0]; mp < &mount[Nmount]; mp++)
|
||||||
|
if(mp->m_inodp == ip) {
|
||||||
|
dev = mp->m_dev;
|
||||||
|
ino = ROOTINO;
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
panic("no imt");
|
||||||
|
}
|
||||||
|
ip->i_count++;
|
||||||
|
ip->i_flag |= ILOCK;
|
||||||
|
return(ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ifreelist == NULL) {
|
||||||
|
printf("Inode table overflow\n");
|
||||||
|
u.u_error = ENFILE;
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
ip=ifreelist;
|
||||||
|
ifreelist=ip->i_link;
|
||||||
|
ip->i_link=ihash[h_index];
|
||||||
|
ihash[h_index]=ip;
|
||||||
|
ip->i_dev = dev;
|
||||||
|
ip->i_number = ino;
|
||||||
|
ip->i_flag = ILOCK;
|
||||||
|
ip->i_count++;
|
||||||
|
ip->i_blks.i_l = (daddr_t) 0;
|
||||||
|
bp = bread(dev, itod(ino));
|
||||||
|
|
||||||
|
if((bp->b_flags&B_ERROR) != 0) {
|
||||||
|
brelse(bp);
|
||||||
|
iput(ip);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
dp = bp->b_un.b_dino;
|
||||||
|
dp += itoo(ino);
|
||||||
|
iexpand(ip, dp);
|
||||||
|
brelse(bp);
|
||||||
|
return(ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
iexpand(ip, dp)
|
||||||
|
register struct inode *ip;
|
||||||
|
register struct dinode *dp;
|
||||||
|
{
|
||||||
|
ip->i_mode = dp->di_mode;
|
||||||
|
ip->i_nlink = dp->di_nlink;
|
||||||
|
ip->i_uid = dp->di_uid;
|
||||||
|
ip->i_gid = dp->di_gid;
|
||||||
|
ip->i_size = dp->di_size;
|
||||||
|
l3tol((char *) ip->i_blks.i_p.i_a, (char *)dp->di_addr, NADDR);
|
||||||
|
ip->i_locklist = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
iput(ip)
|
||||||
|
register struct inode *ip;
|
||||||
|
{
|
||||||
|
register struct inode *ip1;
|
||||||
|
register h_index, i_unbenutzt;
|
||||||
|
long unbenutzt;
|
||||||
|
|
||||||
|
if(ip->i_count == 1) {
|
||||||
|
ip->i_flag |= ILOCK;
|
||||||
|
if(ip->i_nlink <= 0) {
|
||||||
|
itrunc(ip);
|
||||||
|
ip->i_mode = 0;
|
||||||
|
ip->i_flag |= IUPD|ICHG;
|
||||||
|
ifree(ip->i_dev, ip->i_number);
|
||||||
|
}
|
||||||
|
iupdat(ip, &time, &time);
|
||||||
|
prele(ip);
|
||||||
|
h_index = INOHASH(ip->i_dev, ip->i_number);
|
||||||
|
if(ip == ihash[h_index])
|
||||||
|
ihash[h_index] = ip->i_link;
|
||||||
|
else {
|
||||||
|
ip1 = ihash[h_index];
|
||||||
|
for(;ip1;ip1=ip1->i_link)
|
||||||
|
if(ip == ip1->i_link) {
|
||||||
|
ip1->i_link = ip->i_link;
|
||||||
|
goto m1;
|
||||||
|
}
|
||||||
|
panic("iput");
|
||||||
|
}
|
||||||
|
m1:
|
||||||
|
ip->i_link = ifreelist;
|
||||||
|
ifreelist = ip;
|
||||||
|
ip ->i_flag= NULL;
|
||||||
|
ip->i_number = 0;
|
||||||
|
} else
|
||||||
|
prele(ip);
|
||||||
|
ip->i_count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
iupdat(ip, ta, tm)
|
||||||
|
register struct inode *ip;
|
||||||
|
time_t *ta, *tm;
|
||||||
|
{
|
||||||
|
register struct buf *bp;
|
||||||
|
register struct dinode *dp;
|
||||||
|
char *di_addr;
|
||||||
|
char *i_f;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if((ip->i_flag&(IUPD|IACC|ICHG)) == 0)
|
||||||
|
return;
|
||||||
|
if(getfs(ip->i_dev)->s_ronly) {
|
||||||
|
if(ip->i_flag & (IUPD | ICHG))
|
||||||
|
u.u_error = EROFS;
|
||||||
|
ip->i_flag &= ~(IUPD | ICHG | IACC);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bp = bread(ip->i_dev, itod(ip->i_number));
|
||||||
|
if (bp->b_flags & B_ERROR) {
|
||||||
|
brelse(bp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dp = bp->b_un.b_dino;
|
||||||
|
dp += itoo(ip->i_number);
|
||||||
|
dp->di_mode = ip->i_mode;
|
||||||
|
dp->di_nlink = ip->i_nlink;
|
||||||
|
dp->di_uid = ip->i_uid;
|
||||||
|
dp->di_gid = ip->i_gid;
|
||||||
|
dp->di_size = ip->i_size;
|
||||||
|
|
||||||
|
if((ip->i_mode & IFMT) == IFIFO) {
|
||||||
|
di_addr = (char *) dp->di_addr;
|
||||||
|
i_f = (char *) ip->i_faddr;
|
||||||
|
i=0;
|
||||||
|
do {
|
||||||
|
*di_addr++ = *i_f++;
|
||||||
|
if( * i_f++)
|
||||||
|
printf("iaddress > 2^24\n");
|
||||||
|
*di_addr++ = *i_f++;
|
||||||
|
*di_addr++ = *i_f++;
|
||||||
|
}while(++i < NFADDR);
|
||||||
|
|
||||||
|
for(;i<13;i++) {
|
||||||
|
*di_addr++ = 0;
|
||||||
|
*di_addr++ = 0;
|
||||||
|
*di_addr++ = 0;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
ltol3((char *)dp->di_addr, (char *)ip->i_addr, NADDR);
|
||||||
|
if(ip->i_flag&IACC)
|
||||||
|
dp->di_atime = *ta;
|
||||||
|
if(ip->i_flag&IUPD)
|
||||||
|
dp->di_mtime = *tm;
|
||||||
|
if(ip->i_flag&ICHG)
|
||||||
|
dp->di_ctime = time;
|
||||||
|
ip->i_flag &= ~(IUPD|IACC|ICHG);
|
||||||
|
bdwrite(bp);
|
||||||
|
}
|
||||||
|
|
||||||
|
itrunc(ip)
|
||||||
|
register struct inode *ip;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
register dev_t dev;
|
||||||
|
register daddr_t bn;
|
||||||
|
|
||||||
|
i = ip->i_mode & IFMT;
|
||||||
|
if (i!=IFREG && i!=IFDIR)
|
||||||
|
return;
|
||||||
|
dev = ip->i_dev;
|
||||||
|
for(i=NADDR-1; i>=0; i--) {
|
||||||
|
bn = ip->i_addr[i];
|
||||||
|
if(bn == (daddr_t)0)
|
||||||
|
continue;
|
||||||
|
ip->i_addr[i] = (daddr_t)0;
|
||||||
|
switch(i) {
|
||||||
|
|
||||||
|
default:
|
||||||
|
free(dev, bn);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NADDR-3:
|
||||||
|
tloop(dev, bn, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NADDR-2:
|
||||||
|
tloop(dev, bn, 1, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NADDR-1:
|
||||||
|
tloop(dev, bn, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ip->i_size = 0;
|
||||||
|
ip->i_flag |= ICHG|IUPD;
|
||||||
|
}
|
||||||
|
|
||||||
|
tloop(dev, bn, f1, f2)
|
||||||
|
dev_t dev;
|
||||||
|
daddr_t bn;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
register struct buf *bp;
|
||||||
|
register daddr_t *bap;
|
||||||
|
int unbenutzt, u2, u3, u4, u5;
|
||||||
|
daddr_t nb;
|
||||||
|
|
||||||
|
bp = NULL;
|
||||||
|
for(i=NINDIR-1; i>=0; i--) {
|
||||||
|
if(bp == NULL) {
|
||||||
|
bp = bread(dev, bn);
|
||||||
|
if (bp->b_flags & B_ERROR) {
|
||||||
|
brelse(bp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bap = bp->b_un.b_daddr;
|
||||||
|
}
|
||||||
|
nb = bap[i];
|
||||||
|
if(nb == (daddr_t)0)
|
||||||
|
continue;
|
||||||
|
if(f1) {
|
||||||
|
brelse(bp);
|
||||||
|
bp = NULL;
|
||||||
|
tloop(dev, nb, f2, 0);
|
||||||
|
} else
|
||||||
|
free(dev, nb);
|
||||||
|
}
|
||||||
|
if(bp != NULL)
|
||||||
|
brelse(bp);
|
||||||
|
free(dev, bn);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct inode *
|
||||||
|
maknode(mode)
|
||||||
|
{
|
||||||
|
register struct inode *ip;
|
||||||
|
struct inode *ip1;
|
||||||
|
|
||||||
|
ip = ialloc(u.u_pdir->i_dev);
|
||||||
|
if(ip == NULL) {
|
||||||
|
iput(u.u_pdir);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
ip->i_flag |= IACC|IUPD|ICHG;
|
||||||
|
if((mode&IFMT) == 0)
|
||||||
|
mode |= IFREG;
|
||||||
|
ip->i_mode = mode & ~u.u_cmask;
|
||||||
|
ip->i_nlink = 1;
|
||||||
|
ip->i_uid = u.u_uid;
|
||||||
|
ip->i_gid = u.u_gid;
|
||||||
|
wdir(ip);
|
||||||
|
return(ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
wdir(ip)
|
||||||
|
struct inode *ip;
|
||||||
|
{
|
||||||
|
|
||||||
|
if (u.u_pdir->i_nlink <= 0) {
|
||||||
|
u.u_error = ENOTDIR;
|
||||||
|
} else {
|
||||||
|
u.u_dent.d_ino = ip->i_number;
|
||||||
|
bcopy((caddr_t)u.u_dbuf, (caddr_t)u.u_dent.d_name, DIRSIZ);
|
||||||
|
u.u_count = sizeof(struct direct);
|
||||||
|
u.u_segflg = 1;
|
||||||
|
u.u_base.l= (caddr_t) &u.u_dent;
|
||||||
|
writei(u.u_pdir);
|
||||||
|
u.u_segflg = 0;
|
||||||
|
}
|
||||||
|
iput(u.u_pdir);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1988
|
||||||
|
KERN 3.2 Modul: malloc.c
|
||||||
|
|
||||||
|
Bearbeiter:
|
||||||
|
Datum: $D$
|
||||||
|
Version: $R$
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "sys/param.h"
|
||||||
|
#include "sys/sysinfo.h"
|
||||||
|
#include "sys/systm.h"
|
||||||
|
#include "sys/map.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------- Funktionen ------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Die Module malloc und mfree dienen der Speicherverwaltung in den
|
||||||
|
* beiden Speichern coremap und swapmap
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* malloc
|
||||||
|
* Bereitstellung von freiem Speicher aus der core- bzw. swapmap
|
||||||
|
* Zuweisung von 'size' Einheiten
|
||||||
|
* Rueckgabe Basis des zugewiesenen Bereiches
|
||||||
|
* In der map werden die Adressen erhoeht, die Liste wird durch eine
|
||||||
|
* 0-Laenge beendet
|
||||||
|
* Coremap-Unit = 64 Byte; Swapmap-Unit = 512 Byte
|
||||||
|
* Algorithmus ist first-fit.
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
malloc(mp, size)
|
||||||
|
struct map *mp;
|
||||||
|
{
|
||||||
|
register unsigned int a;
|
||||||
|
register struct map *bp;
|
||||||
|
|
||||||
|
for (bp=mp; bp->m_size; bp++) {
|
||||||
|
if (bp->m_size >= size) {
|
||||||
|
a = bp->m_addr;
|
||||||
|
bp->m_addr += size;
|
||||||
|
if ((bp->m_size -= size) == 0) {
|
||||||
|
do {
|
||||||
|
bp++;
|
||||||
|
(bp-1)->m_addr = bp->m_addr;
|
||||||
|
} while ((bp-1)->m_size = bp->m_size);
|
||||||
|
}
|
||||||
|
return(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* mfree
|
||||||
|
* Freigabe des vorher zugewiesenen Speichers a mit der Laenge von size
|
||||||
|
* Einheiten an die spezifizierte Map
|
||||||
|
* 'a' wird in die Map einsortiert und ein oder beide Enden kombiniert,
|
||||||
|
* wenn moeglich
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
mfree(mp, size, a)
|
||||||
|
struct map *mp;
|
||||||
|
register int a;
|
||||||
|
{
|
||||||
|
register struct map *bp;
|
||||||
|
register unsigned int t;
|
||||||
|
|
||||||
|
if ((bp = mp)==coremap && runin) {
|
||||||
|
runin = 0;
|
||||||
|
wakeup((caddr_t)&runin);
|
||||||
|
}
|
||||||
|
for (; bp->m_addr<=a && bp->m_size!=0; bp++);
|
||||||
|
if (bp>mp && (bp-1)->m_addr+(bp-1)->m_size == a) {
|
||||||
|
(bp-1)->m_size += size;
|
||||||
|
if (a+size == bp->m_addr) {
|
||||||
|
(bp-1)->m_size += bp->m_size;
|
||||||
|
while (bp->m_size) {
|
||||||
|
bp++;
|
||||||
|
(bp-1)->m_addr = bp->m_addr;
|
||||||
|
(bp-1)->m_size = bp->m_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (a+size == bp->m_addr && bp->m_size) {
|
||||||
|
bp->m_addr -= size;
|
||||||
|
bp->m_size += size;
|
||||||
|
} else if (size) {
|
||||||
|
do {
|
||||||
|
t = bp->m_addr;
|
||||||
|
bp->m_addr = a;
|
||||||
|
a = t;
|
||||||
|
t = bp->m_size;
|
||||||
|
bp->m_size = size;
|
||||||
|
bp++;
|
||||||
|
} while (size = t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/sysparm.h>
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#include <sys/mmu.h>
|
||||||
|
#include <sys/buf.h>
|
||||||
|
#include <sys/conf.h>
|
||||||
|
#include <sys/proc.h>
|
||||||
|
#include <sys/s.out.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
#include <sys/map.h>
|
||||||
|
|
||||||
|
char mksegwstr[]="@@[$]mkseg.c@i@iRev : 4.1@i08/27/83 11:56:13";
|
||||||
|
|
||||||
|
mkseg()
|
||||||
|
{
|
||||||
|
register unsigned segno;
|
||||||
|
register unsigned size;
|
||||||
|
register struct proc *pp;
|
||||||
|
struct a {
|
||||||
|
unsigned segno;
|
||||||
|
unsigned size;
|
||||||
|
}
|
||||||
|
*uap;
|
||||||
|
char i, j;
|
||||||
|
|
||||||
|
pp = u.u_procp;
|
||||||
|
segno = ((struct a *)u.u_ap)->segno & 0x7f;
|
||||||
|
size = ((struct a *)u.u_ap)->size;
|
||||||
|
if (!segno){
|
||||||
|
loop:
|
||||||
|
i = 4;
|
||||||
|
for (j=0; j<u.u_nsegs; j++)
|
||||||
|
if ((u.u_segno[j]&0x7f) == i)
|
||||||
|
if (++i > STAK){
|
||||||
|
u.u_error = ENOSEG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto loop;
|
||||||
|
segno = i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for (j=0; j<u.u_nsegs; j++)
|
||||||
|
if (segno == u.u_segno[j]){
|
||||||
|
u.u_error = ENOSEG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
j = u.u_nsegs;
|
||||||
|
if (u.u_tsize+u.u_dsize+u.u_ssize+(unsigned)USIZE > umemory){
|
||||||
|
u.u_error = ENOMEM;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
u.u_segno[j] = segno;
|
||||||
|
u.u_nsegs++;
|
||||||
|
u.u_dsize += size;
|
||||||
|
sestabur(size, j, j, 0);
|
||||||
|
if (u.u_error)
|
||||||
|
return;
|
||||||
|
shufflecore(pp->p_size+size, pp->p_size, u.u_ssize);
|
||||||
|
u.u_r.r_val1 = segno<<8;
|
||||||
|
u.u_r.r_val2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sgstat is defined here; it is directly never used */
|
||||||
|
|
||||||
|
#define NSEGS 10
|
||||||
|
sgstat()
|
||||||
|
{
|
||||||
|
cnt_t i,j;
|
||||||
|
struct {
|
||||||
|
unsigned segno;
|
||||||
|
unsigned limit;
|
||||||
|
} segstat[10];
|
||||||
|
register paddr_t *saddr;
|
||||||
|
|
||||||
|
saddr = (paddr_t *)u.u_ap;
|
||||||
|
j = 0;
|
||||||
|
if (u.u_sep)
|
||||||
|
for (i=0; ; ){
|
||||||
|
if (i< u.u_nsegs){
|
||||||
|
if (u.u_segno[i] & 0x80){
|
||||||
|
hibyte(segstat[j].segno) = u.u_segno[i] & 0x7f;
|
||||||
|
if (u.u_segmts[i].sg_limit == 0xff)
|
||||||
|
segstat[j].limit = 0xfffe;
|
||||||
|
else
|
||||||
|
segstat[j].limit = ((unsigned int)(u.u_segmts[i].sg_limit)+1)<<8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j++ != NSEGS)
|
||||||
|
i++;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hibyte(segstat[0].segno) = u.u_tseg;
|
||||||
|
segstat[0].limit = u.u_toff<<8;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
for(i=j; i<NSEGS; i++){
|
||||||
|
hibyte(segstat[i].segno) = 0xff;
|
||||||
|
segstat[i].limit = 0;
|
||||||
|
}
|
||||||
|
if (copyout(segstat, *saddr, sizeof(segstat)) < 0)
|
||||||
|
u.u_error = EFAULT;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,198 @@
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1985
|
||||||
|
KERN 3.2 Modul: pipe.c
|
||||||
|
|
||||||
|
|
||||||
|
Bearbeiter:
|
||||||
|
Datum: $D$
|
||||||
|
Version: $R$
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/mmu.h>
|
||||||
|
#include <sys/s.out.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
#include <sys/inode.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
|
||||||
|
/*------------------------------------------ Funktionen ---------------------*/
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* pipe
|
||||||
|
* Der Pipe-Systemaufruf.
|
||||||
|
* Zuweisen eines Inodes des Wurzelgeraetes (root dev).
|
||||||
|
* Zuweisen von zwei File-Strukturen und Verbinden
|
||||||
|
* dieser Teile durch Setzen entsprechender Flags.
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
pipe()
|
||||||
|
{
|
||||||
|
register struct inode *ip;
|
||||||
|
register struct file *rf, *wf;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
ip = ialloc(pipedev);
|
||||||
|
if(ip == NULL)
|
||||||
|
return;
|
||||||
|
rf = falloc();
|
||||||
|
if(rf == NULL) {
|
||||||
|
iput(ip);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
r = u.u_r.r_val1;
|
||||||
|
wf = falloc();
|
||||||
|
if(wf == NULL) {
|
||||||
|
rf->f_count = 0;
|
||||||
|
u.u_ofile[r] = NULL;
|
||||||
|
iput(ip);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
u.u_r.r_val2 = u.u_r.r_val1;
|
||||||
|
u.u_r.r_val1 = r;
|
||||||
|
wf->f_flag = FWRITE;
|
||||||
|
wf->f_inode = ip;
|
||||||
|
rf->f_flag = FREAD;
|
||||||
|
rf->f_inode = ip;
|
||||||
|
ip->i_count = 2;
|
||||||
|
ip->i_mode = IFIFO;
|
||||||
|
ip->i_flag = IACC|IUPD|ICHG;
|
||||||
|
ip->i_frcnt=1;
|
||||||
|
ip->i_fwcnt=1;
|
||||||
|
iupdat(ip,&time,&time);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* openp
|
||||||
|
* Eroeffnen einer Pipe
|
||||||
|
* Kontrolle Lese-/Schreibgroesse; streichen, wenn notwendig
|
||||||
|
*/
|
||||||
|
/*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
openp(ip, mode)
|
||||||
|
register struct inode *ip;
|
||||||
|
register mode;
|
||||||
|
{
|
||||||
|
if (mode&FREAD) {
|
||||||
|
if (ip->i_frcnt++ == 0)
|
||||||
|
wakeup((caddr_t)&ip->i_frcnt);
|
||||||
|
}
|
||||||
|
if (mode&FWRITE) {
|
||||||
|
if (mode&FNDELAY && ip->i_frcnt == 0) {
|
||||||
|
u.u_error = ENXIO;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ip->i_fwcnt++ == 0)
|
||||||
|
wakeup((caddr_t)&ip->i_fwcnt);
|
||||||
|
}
|
||||||
|
if (mode&FREAD) {
|
||||||
|
while (ip->i_fwcnt == 0) {
|
||||||
|
if (mode&FNDELAY || ip->i_size)
|
||||||
|
return;
|
||||||
|
sleep(&ip->i_fwcnt, PPIPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mode&FWRITE) {
|
||||||
|
while (ip->i_frcnt == 0)
|
||||||
|
sleep(&ip->i_frcnt, PPIPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* closep
|
||||||
|
* Schliessen einer Pipe
|
||||||
|
* Update counts and cleanup
|
||||||
|
*/
|
||||||
|
/*------------------------------------------------*/
|
||||||
|
|
||||||
|
closep(ip, mode)
|
||||||
|
register struct inode *ip;
|
||||||
|
register mode;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
daddr_t bn;
|
||||||
|
|
||||||
|
if (mode&FREAD) {
|
||||||
|
if ((--ip->i_frcnt == 0) && (ip->i_fflag&IFIW)) {
|
||||||
|
ip->i_fflag &= ~IFIW;
|
||||||
|
wakeup((caddr_t)&ip->i_fwcnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mode&FWRITE) {
|
||||||
|
if ((--ip->i_fwcnt == 0) && (ip->i_fflag&IFIR)) {
|
||||||
|
ip->i_fflag &= ~IFIR;
|
||||||
|
wakeup((caddr_t)&ip->i_frcnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((ip->i_frcnt == 0) && (ip->i_fwcnt == 0)) {
|
||||||
|
for (i=NFADDR-1; i>=0; i--) {
|
||||||
|
bn = ip->i_faddr[i];
|
||||||
|
if (bn == (daddr_t)0)
|
||||||
|
continue;
|
||||||
|
ip->i_faddr[i] = (daddr_t)0;
|
||||||
|
free(ip->i_dev, bn);
|
||||||
|
}
|
||||||
|
ip->i_size = 0;
|
||||||
|
ip->i_frptr = 0;
|
||||||
|
ip->i_fwptr = 0;
|
||||||
|
ip->i_flag |= IUPD|ICHG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* plock
|
||||||
|
* Blockieren eines Pipekanals.
|
||||||
|
* Wenn er bereits blockiert ist, so wird das WANT-Flag gesetzt
|
||||||
|
* und auf die Freigabe gewartet.
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
plock(ip)
|
||||||
|
register struct inode *ip;
|
||||||
|
{
|
||||||
|
int fcw;
|
||||||
|
|
||||||
|
fcw=dvi();
|
||||||
|
while(ip->i_flag&ILOCK) {
|
||||||
|
ip->i_flag |= IWANT;
|
||||||
|
sleep((caddr_t)ip, PINOD);
|
||||||
|
}
|
||||||
|
ip->i_flag |= ILOCK;
|
||||||
|
rvi(fcw);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* prele
|
||||||
|
* Aufhebung der Blockierung eines Inodes.
|
||||||
|
* Wenn das WANT-Flag gesetzt ist,
|
||||||
|
* so Aufwecken des wartenden Prozesses.
|
||||||
|
* Diese Routine wird auch allgemein benutzt,
|
||||||
|
* um die Blockierung eines Inodes aufzuheben.
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
prele(ip)
|
||||||
|
register struct inode *ip;
|
||||||
|
{
|
||||||
|
int fcw;
|
||||||
|
|
||||||
|
fcw=dvi();
|
||||||
|
ip->i_flag &= ~ILOCK;
|
||||||
|
if(ip->i_flag&IWANT) {
|
||||||
|
ip->i_flag &= ~IWANT;
|
||||||
|
wakeup((caddr_t)ip);
|
||||||
|
}
|
||||||
|
rvi(fcw);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,441 @@
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#include <sys/state.h>
|
||||||
|
#include <sys/conf.h>
|
||||||
|
#include <sys/proc.h>
|
||||||
|
#include <sys/mmu.h>
|
||||||
|
#include <sys/s.out.h>
|
||||||
|
#include <sys/text.h>
|
||||||
|
#include <sys/map.h>
|
||||||
|
#include <sys/inode.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <sys/buf.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
|
||||||
|
#define SQSIZE 0100
|
||||||
|
struct proc *slpque[SQSIZE+1];
|
||||||
|
|
||||||
|
#define HASH(x) (( (int) x >> 5) & (SQSIZE-1))
|
||||||
|
|
||||||
|
extern unsigned Nproc;
|
||||||
|
|
||||||
|
sleep(chan, pri)
|
||||||
|
caddr_t chan;
|
||||||
|
int pri;
|
||||||
|
{
|
||||||
|
register struct proc *rp;
|
||||||
|
register s, h;
|
||||||
|
register sig;
|
||||||
|
|
||||||
|
rp = u.u_procp;
|
||||||
|
s = dvi();
|
||||||
|
if (chan==0)
|
||||||
|
panic("zero wchan");
|
||||||
|
rp->p_stat = SSLEEP;
|
||||||
|
rp->p_wchan = chan;
|
||||||
|
rp->p_pri = pri;
|
||||||
|
h = 0x40;
|
||||||
|
else
|
||||||
|
h = HASH(chan);
|
||||||
|
rp->p_link = slpque[h];
|
||||||
|
slpque[h] = rp;
|
||||||
|
if(pri > PZERO) {
|
||||||
|
if(rp->p_sig != 0 && (sig=issig()) != 0)
|
||||||
|
if((sig & ~(SIGHUP|SIGILL)) || !(rp->p_flag&STRC)) {
|
||||||
|
rp->p_wchan = 0;
|
||||||
|
rp->p_stat = SRUN;
|
||||||
|
slpque[h] = rp->p_link;
|
||||||
|
evi();
|
||||||
|
goto psig;
|
||||||
|
}
|
||||||
|
evi();
|
||||||
|
if(runin != 0) {
|
||||||
|
runin = 0;
|
||||||
|
wakeup((caddr_t)&runin);
|
||||||
|
}
|
||||||
|
swtch();
|
||||||
|
if(rp->p_sig !=0 && (sig=issig()) != 0)
|
||||||
|
if((sig & ~(SIGHUP|SIGILL)) || !(rp->p_flag & STRC))
|
||||||
|
goto psig;
|
||||||
|
} else {
|
||||||
|
evi();
|
||||||
|
swtch();
|
||||||
|
}
|
||||||
|
rvi(s);
|
||||||
|
return;
|
||||||
|
|
||||||
|
psig:
|
||||||
|
resume(u.u_procp->p_addr, u.u_qsav);
|
||||||
|
}
|
||||||
|
|
||||||
|
wakeup(chan)
|
||||||
|
register caddr_t chan;
|
||||||
|
{
|
||||||
|
register struct proc *p, *q;
|
||||||
|
register i;
|
||||||
|
register int s;
|
||||||
|
struct proc *sp;
|
||||||
|
|
||||||
|
s = dvi();
|
||||||
|
if (chan == &runout)
|
||||||
|
i = 0x40;
|
||||||
|
else
|
||||||
|
i = HASH(chan);
|
||||||
|
restrt:
|
||||||
|
p = slpque[i];
|
||||||
|
q = NULL;
|
||||||
|
while(p != NULL) {
|
||||||
|
if(p->p_wchan==chan && p->p_stat!=SZOMB) {
|
||||||
|
if (q == NULL)
|
||||||
|
sp = slpque[i] = p->p_link;
|
||||||
|
else
|
||||||
|
sp = q->p_link = p->p_link;
|
||||||
|
p->p_wchan = 0;
|
||||||
|
setrun(p);
|
||||||
|
p = sp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
q = p;
|
||||||
|
p = p->p_link;
|
||||||
|
}
|
||||||
|
rvi(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
setrq(p)
|
||||||
|
struct proc *p;
|
||||||
|
{
|
||||||
|
register struct proc *q;
|
||||||
|
register s;
|
||||||
|
|
||||||
|
s=dvi();
|
||||||
|
for(q=runq; q!=NULL; q=q->p_link)
|
||||||
|
if(q == p) {
|
||||||
|
prstate(u.u_state);
|
||||||
|
panic("proc on q\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
p->p_link = runq;
|
||||||
|
runq = p;
|
||||||
|
out:
|
||||||
|
rvi(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
setrun(p)
|
||||||
|
register struct proc *p;
|
||||||
|
{
|
||||||
|
register caddr_t w;
|
||||||
|
|
||||||
|
if (p->p_stat==0 || p->p_stat==SZOMB) {
|
||||||
|
prstate(u.u_state);
|
||||||
|
panic("Running a dead proc");
|
||||||
|
}
|
||||||
|
if (w = p->p_wchan) {
|
||||||
|
wakeup(w);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p->p_stat = SRUN;
|
||||||
|
setrq(p);
|
||||||
|
if(p->p_pri < curpri)
|
||||||
|
runrun++;
|
||||||
|
if(runout != 0 && (p->p_flag&SLOAD) == 0) {
|
||||||
|
runout = 0;
|
||||||
|
wakeup((caddr_t)&runout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setpri(pp)
|
||||||
|
register struct proc *pp;
|
||||||
|
{
|
||||||
|
register p;
|
||||||
|
|
||||||
|
p = (pp->p_cpu & 0377)/16;
|
||||||
|
p += PUSER + pp->p_nice - NZERO;
|
||||||
|
if(p > 127)
|
||||||
|
p = 127;
|
||||||
|
if(p < curpri)
|
||||||
|
runrun++;
|
||||||
|
pp->p_pri = p;
|
||||||
|
return(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
sched()
|
||||||
|
{
|
||||||
|
register struct proc *rp, *p;
|
||||||
|
register outage, inage;
|
||||||
|
register maxsize;
|
||||||
|
|
||||||
|
|
||||||
|
loop:
|
||||||
|
dvi();
|
||||||
|
outage = -20000;
|
||||||
|
for (rp = &proc[0]; rp < &proc[Nproc]; rp++)
|
||||||
|
if (rp->p_stat==SRUN && (rp->p_flag&SLOAD)==0 &&
|
||||||
|
rp->p_time - (rp->p_nice-NZERO)*8 > outage) {
|
||||||
|
p = rp;
|
||||||
|
outage = rp->p_time - (rp->p_nice-NZERO)*8;
|
||||||
|
}
|
||||||
|
if (outage == -20000) {
|
||||||
|
runout++;
|
||||||
|
sleep((caddr_t)&runout, PSWP);
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
evi();
|
||||||
|
|
||||||
|
if (swapin(p))
|
||||||
|
goto loop;
|
||||||
|
|
||||||
|
|
||||||
|
dvi();
|
||||||
|
p = NULL;
|
||||||
|
maxsize = -1;
|
||||||
|
inage = -1;
|
||||||
|
for (rp = &proc[0]; rp < &proc[Nproc]; rp++) {
|
||||||
|
if (rp->p_stat==SZOMB
|
||||||
|
|| (rp->p_flag&(SSYS|SLOCK|SULOCK|SLOAD))!=SLOAD)
|
||||||
|
continue;
|
||||||
|
if (rp->p_textp && rp->p_textp->x_flag&XLOCK)
|
||||||
|
continue;
|
||||||
|
if (rp->p_stat==SSLEEP&&rp->p_pri>=PZERO || rp->p_stat==SSTOP) {
|
||||||
|
if (maxsize < rp->p_size) {
|
||||||
|
p = rp;
|
||||||
|
maxsize = rp->p_size;
|
||||||
|
}
|
||||||
|
} else if (maxsize<0 && (rp->p_stat==SRUN||rp->p_stat==SSLEEP)) {
|
||||||
|
if (rp->p_time+rp->p_nice-NZERO > inage) {
|
||||||
|
p = rp;
|
||||||
|
inage = rp->p_time+rp->p_nice-NZERO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
evi();
|
||||||
|
if (maxsize>=0 || (outage>=3 && inage>=2)) {
|
||||||
|
p->p_flag &= ~SLOAD;
|
||||||
|
xswap(p, 1, 0);
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
dvi();
|
||||||
|
runin++;
|
||||||
|
sleep((caddr_t)&runin, PSWP);
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
swapin(p)
|
||||||
|
register struct proc *p;
|
||||||
|
{
|
||||||
|
register struct text *xp;
|
||||||
|
register int a;
|
||||||
|
register int x;
|
||||||
|
|
||||||
|
if ((a = malloc(coremap, p->p_size)) == NULL)
|
||||||
|
return(0);
|
||||||
|
if (xp = p->p_textp) {
|
||||||
|
xlock(xp);
|
||||||
|
if (xp->x_ccount==0) {
|
||||||
|
if ((x = malloc(coremap, xp->x_size)) == NULL) {
|
||||||
|
xunlock(xp);
|
||||||
|
mfree(coremap, p->p_size, a);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
xp->x_caddr = x;
|
||||||
|
if ((xp->x_flag&XLOAD)==0)
|
||||||
|
swap(swapdev,xp->x_daddr,x,xp->x_size,B_READ);
|
||||||
|
}
|
||||||
|
xp->x_ccount++;
|
||||||
|
xunlock(xp);
|
||||||
|
}
|
||||||
|
swap(swapdev, p->p_addr, a, p->p_size, B_READ);
|
||||||
|
mfree(swapmap, ctod(p->p_size), p->p_addr);
|
||||||
|
p->p_addr = a;
|
||||||
|
p->p_flag |= SLOAD;
|
||||||
|
p->p_time = 0;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
qswtch()
|
||||||
|
{
|
||||||
|
|
||||||
|
sysinfo.qswitch++;
|
||||||
|
setrq(u.u_procp);
|
||||||
|
swtch();
|
||||||
|
}
|
||||||
|
|
||||||
|
swtch()
|
||||||
|
{
|
||||||
|
register n;
|
||||||
|
register struct proc *p, *q;
|
||||||
|
int undef1, undef2, undef3;
|
||||||
|
struct proc *pp, *pq;
|
||||||
|
|
||||||
|
if (u.u_procp != &proc[0]) {
|
||||||
|
if (save(u.u_rsav)) {
|
||||||
|
sysinfo.pswitch++;
|
||||||
|
setscr();
|
||||||
|
if(u.u_segmented) {
|
||||||
|
invsdrs();
|
||||||
|
segureg();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sureg();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resume(proc[0].p_addr, u.u_qsav);
|
||||||
|
}
|
||||||
|
if (save(u.u_qsav)==0 && save(u.u_rsav)) {
|
||||||
|
setscr();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loop:
|
||||||
|
dvi();
|
||||||
|
runrun = 0;
|
||||||
|
pp = NULL;
|
||||||
|
q = NULL;
|
||||||
|
n = 128;
|
||||||
|
for(p=runq; p!=NULL; p=p->p_link) {
|
||||||
|
if((p->p_stat==SRUN) && (p->p_flag&SLOAD)) {
|
||||||
|
if(p->p_pri <= n) {
|
||||||
|
pp = p;
|
||||||
|
pq = q;
|
||||||
|
n = p->p_pri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
q = p;
|
||||||
|
}
|
||||||
|
p = pp;
|
||||||
|
if(p == NULL) {
|
||||||
|
sysinfo.idle++;
|
||||||
|
idle();
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
q = pq;
|
||||||
|
if(q == NULL)
|
||||||
|
runq = p->p_link;
|
||||||
|
else
|
||||||
|
q->p_link = p->p_link;
|
||||||
|
curpri = n;
|
||||||
|
evi();
|
||||||
|
n = p->p_flag&SSWAP;
|
||||||
|
p->p_flag &= ~SSWAP;
|
||||||
|
resume(p->p_addr, n? u.u_ssav: u.u_rsav);
|
||||||
|
}
|
||||||
|
|
||||||
|
newproc()
|
||||||
|
{
|
||||||
|
long undef;
|
||||||
|
struct proc *rpp, *rip;
|
||||||
|
int n;
|
||||||
|
register a1, a2;
|
||||||
|
register struct proc *p, *up;
|
||||||
|
|
||||||
|
p = NULL;
|
||||||
|
retry:
|
||||||
|
mpid++;
|
||||||
|
if(mpid >= 30000) {
|
||||||
|
mpid = 0;
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
for(rpp = &proc[0]; rpp < &proc[Nproc]; rpp++) {
|
||||||
|
if(rpp->p_stat == NULL && p==NULL)
|
||||||
|
p = rpp;
|
||||||
|
if (rpp->p_pid==mpid || rpp->p_pgrp==mpid)
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
if ((rpp = p)==NULL)
|
||||||
|
panic("no procs");
|
||||||
|
|
||||||
|
rip = u.u_procp;
|
||||||
|
up =rip;
|
||||||
|
rpp->p_stat = SRUN;
|
||||||
|
rpp->p_clktim = 0;
|
||||||
|
rpp->p_flag = SLOAD;
|
||||||
|
rpp->p_uid = rip->p_uid;
|
||||||
|
rpp->p_pgrp = rip->p_pgrp;
|
||||||
|
rpp->p_nice = rip->p_nice;
|
||||||
|
rpp->p_textp = rip->p_textp;
|
||||||
|
rpp->p_pid = mpid;
|
||||||
|
rpp->p_ppid = rip->p_pid;
|
||||||
|
rpp->p_time = 0;
|
||||||
|
rpp->p_cpu = 0;
|
||||||
|
|
||||||
|
|
||||||
|
for(n=0; n<NOFILE; n++)
|
||||||
|
if(u.u_ofile[n] != NULL)
|
||||||
|
u.u_ofile[n]->f_count++;
|
||||||
|
if(up->p_textp != NULL) {
|
||||||
|
up->p_textp->x_count++;
|
||||||
|
up->p_textp->x_ccount++;
|
||||||
|
}
|
||||||
|
u.u_cdir->i_count++;
|
||||||
|
if (u.u_rdir)
|
||||||
|
u.u_rdir->i_count++;
|
||||||
|
rpp = p;
|
||||||
|
u.u_procp = rpp;
|
||||||
|
rip = up;
|
||||||
|
n = rip->p_size;
|
||||||
|
a1 = rip->p_addr;
|
||||||
|
rpp->p_size = n;
|
||||||
|
if (save(u.u_ssav)) {
|
||||||
|
setscr();
|
||||||
|
if(u.u_segmented) {
|
||||||
|
invsdrs();
|
||||||
|
segureg();
|
||||||
|
} else
|
||||||
|
sureg();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
a2 = malloc(coremap, n);
|
||||||
|
if(a2 == NULL) {
|
||||||
|
rip->p_stat = SIDL;
|
||||||
|
rpp->p_addr = a1;
|
||||||
|
xswap(rpp, 0, 0);
|
||||||
|
rip->p_stat = SRUN;
|
||||||
|
} else {
|
||||||
|
rpp->p_addr = a2;
|
||||||
|
while(n--)
|
||||||
|
copyseg(a1++, a2++);
|
||||||
|
}
|
||||||
|
u.u_procp = rip;
|
||||||
|
setrq(rpp);
|
||||||
|
rpp->p_flag |= SSWAP;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
expand(newsize)
|
||||||
|
{
|
||||||
|
register i, n;
|
||||||
|
register struct proc *p;
|
||||||
|
register a1, a2;
|
||||||
|
int k;
|
||||||
|
|
||||||
|
p = u.u_procp;
|
||||||
|
n = p->p_size;
|
||||||
|
p->p_size = newsize;
|
||||||
|
a1 = p->p_addr;
|
||||||
|
if(n >= newsize) {
|
||||||
|
mfree(coremap, n-newsize, a1+newsize);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (save(u.u_ssav)) {
|
||||||
|
setscr();
|
||||||
|
if(u.u_segmented) {
|
||||||
|
invsdrs();
|
||||||
|
segureg();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sureg();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
a2 = malloc(coremap, newsize);
|
||||||
|
if(a2 == NULL) {
|
||||||
|
xswap(p, 1, n);
|
||||||
|
p->p_flag |= SSWAP;
|
||||||
|
qswtch();
|
||||||
|
/* no return */
|
||||||
|
}
|
||||||
|
p->p_addr = a2;
|
||||||
|
for(i=0; i<n; i++)
|
||||||
|
copyseg(a1+i, a2+i);
|
||||||
|
mfree(coremap, n, a1);
|
||||||
|
resume(a2, u.u_ssav);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,707 @@
|
||||||
|
char sys1wstr[] = "@[$]%M Rev :%I %H";
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/sysparm.h>
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/state.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <sys/inode.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#include <sys/mmu.h>
|
||||||
|
#include <sys/buf.h>
|
||||||
|
#include <sys/conf.h>
|
||||||
|
#include <sys/proc.h>
|
||||||
|
#include <sys/s.out.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
#include <sys/map.h>
|
||||||
|
#include <sys/tty.h>
|
||||||
|
#include <sys/acct.h>
|
||||||
|
|
||||||
|
extern Nproc, Maxmem, Maxuprc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* exec system call, with and without environments.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct execa {
|
||||||
|
char *fname;
|
||||||
|
char **argp;
|
||||||
|
char **envp;
|
||||||
|
};
|
||||||
|
|
||||||
|
exec()
|
||||||
|
{
|
||||||
|
((struct execa *)u.u_ap)->envp = NULL;
|
||||||
|
exece();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NCABLK (NCARGS+BSIZE-1)/BSIZE
|
||||||
|
exece()
|
||||||
|
{
|
||||||
|
register int nc, nc1;
|
||||||
|
register char *cp;
|
||||||
|
register struct buf *bp;
|
||||||
|
register struct execa *uap;
|
||||||
|
int ne;
|
||||||
|
int bno;
|
||||||
|
unsigned ap;
|
||||||
|
char b;
|
||||||
|
saddr_t c, stkv;
|
||||||
|
struct inode *ip;
|
||||||
|
extern struct inode *gethead();
|
||||||
|
|
||||||
|
if ((ip = namei(uchar, 0)) == NULL)
|
||||||
|
return;
|
||||||
|
bno = 0;
|
||||||
|
bp = 0;
|
||||||
|
if (access(ip, IEXEC))
|
||||||
|
goto bad1;
|
||||||
|
if ((ip->i_mode & IFMT) != IFREG ||
|
||||||
|
(ip->i_mode & (IEXEC|(IEXEC>>3)|(IEXEC>>6))) == 0){
|
||||||
|
bad: u.u_error = EACCES;
|
||||||
|
goto bad1;
|
||||||
|
}
|
||||||
|
nc1 = 0;
|
||||||
|
ne = 0;
|
||||||
|
nc = 0;
|
||||||
|
uap = (struct execa *)u.u_ap;
|
||||||
|
if ((bno = malloc(swapmap, 10)) == 0)
|
||||||
|
panic("Out of swap");
|
||||||
|
if (((!u.u_segmented) && ((long)uap->argp & 0x0ffffL) != 0L) ||
|
||||||
|
(u.u_segmented && uap->argp))
|
||||||
|
for (;;){
|
||||||
|
c.l = 0;
|
||||||
|
if (((!u.u_segmented) && (long)uap->argp & 0x0ffffL) ||
|
||||||
|
(u.u_segmented && uap->argp)){
|
||||||
|
if (u.u_segmented){
|
||||||
|
if (fuword(uap->argp, &c.left) ||
|
||||||
|
(fuword((long)uap->argp+2, &c.right)))
|
||||||
|
goto bad;
|
||||||
|
(long)uap->argp += 4;
|
||||||
|
} else { if (fuword(uap->argp,&c.right))
|
||||||
|
goto bad;
|
||||||
|
c.left = nsseg(c.right);
|
||||||
|
(long)uap->argp += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((!u.u_segmented && c.right == NULL && ((long)uap->envp & 0xffffL) != NULL) ||
|
||||||
|
(u.u_segmented && (c.l == 0L) && (uap->envp != 0L))){
|
||||||
|
uap->argp = 0;
|
||||||
|
/* b24 */ if (u.u_segmented){
|
||||||
|
if ((fuword(uap->envp, &c.left)) ||
|
||||||
|
(fuword((long)uap->envp+2, &c.right)))
|
||||||
|
goto bad;
|
||||||
|
/* 27 */ if (!c.l)
|
||||||
|
break;
|
||||||
|
(long)uap->envp += 2;
|
||||||
|
} else {
|
||||||
|
/* 28 */ if (fuword(uap->envp, &c.right))
|
||||||
|
goto bad;
|
||||||
|
if (c.right != 0L)
|
||||||
|
break;
|
||||||
|
c.left = nsseg(c.right);
|
||||||
|
}
|
||||||
|
(long)uap->envp += 2;
|
||||||
|
ne++;
|
||||||
|
}
|
||||||
|
/* 30 */ if ((u.u_segmented || c.right != 0L) &&
|
||||||
|
(!u.u_segmented || c.l != 0)){
|
||||||
|
nc1++;
|
||||||
|
do {
|
||||||
|
/* 34 */ if (nc >= 0x13ff)
|
||||||
|
u.u_error = E2BIG;
|
||||||
|
if (fubyte (c.l++, &b))
|
||||||
|
u.u_error = EFAULT;
|
||||||
|
if (u.u_error)
|
||||||
|
goto bad1;
|
||||||
|
if ((nc & 0x1ff) == 0){
|
||||||
|
if (bp)
|
||||||
|
bawrite(bp);
|
||||||
|
bp = getblk(swapdev, (daddr_t)(bno+swplo+(nc>>BSHIFT)));
|
||||||
|
cp = bp->b_un.b_addr;
|
||||||
|
}
|
||||||
|
nc++;
|
||||||
|
*cp++ = b;
|
||||||
|
} while (b > 0);
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*40*/ if (bp)
|
||||||
|
bawrite(bp);
|
||||||
|
bp = 0;
|
||||||
|
nc = (nc + NBPW -1) & ~(NBPW -1);
|
||||||
|
if (u.u_error || getxfile(ip, nc) || u.u_error){
|
||||||
|
u.u_segmented = (u.u_state->s_ps & SEGFCW)?1:0;
|
||||||
|
setscr();
|
||||||
|
goto bad1;
|
||||||
|
}
|
||||||
|
ap = -nc - NBPW;
|
||||||
|
c.left = u.u_stakseg << 8;
|
||||||
|
/*45*/ if (u.u_segmented)
|
||||||
|
c.right = ap - nc1*2*NBPW - 3*2*NBPW;
|
||||||
|
else
|
||||||
|
c.right = ap - nc1*NBPW - 3*NBPW;
|
||||||
|
u.u_state->s_sp = c.right;
|
||||||
|
/*46*/ if (suword(c.l, nc1 - ne))
|
||||||
|
goto bad;
|
||||||
|
nc = 0;
|
||||||
|
while (1){
|
||||||
|
/* b57 */ if (u.u_segmented){
|
||||||
|
c.right += 2;
|
||||||
|
/* b58 */ if (nc1 == ne){
|
||||||
|
if (suword(c.l, 0) || suword(c.l+2, 0))
|
||||||
|
goto bad;
|
||||||
|
c.right += 4;
|
||||||
|
}
|
||||||
|
/* b61 */ if (--nc1 >= 0){
|
||||||
|
if (suword(c.l, u.u_stakseg<<8) || suword(c.l+2, ap))
|
||||||
|
goto bad;
|
||||||
|
c.right += 2;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
c.right += 2;
|
||||||
|
if (nc1 == ne){
|
||||||
|
if (suword(c.l, 0))
|
||||||
|
goto bad;
|
||||||
|
c.right += 2;
|
||||||
|
}
|
||||||
|
/* b54 */ if (--nc1 >= 0){
|
||||||
|
if (suword(c.l, ap))
|
||||||
|
goto bad;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (1){
|
||||||
|
/* b49 */ if ((nc & 0x1ff) == 0){
|
||||||
|
if (bp)
|
||||||
|
brelse(bp);
|
||||||
|
bp = bread(swapdev, (daddr_t)bno+swplo+(nc>>BSHIFT));
|
||||||
|
cp = bp->b_un.b_addr;
|
||||||
|
}
|
||||||
|
stkv.left = u.u_stakseg<<8;
|
||||||
|
stkv.right = ap++;
|
||||||
|
if (subyte(stkv.l, (b = *cp++)))
|
||||||
|
goto bad;
|
||||||
|
nc++;
|
||||||
|
/* b56 */ if (b & 0xff)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (suword(c.l, 0))
|
||||||
|
goto bad;
|
||||||
|
if (u.u_error)
|
||||||
|
if (suword(c.l+2, 0))
|
||||||
|
goto bad;
|
||||||
|
stkv.left = u.u_stakseg<<8;
|
||||||
|
stkv.right = ap;
|
||||||
|
if (suword(stkv.l, 0))
|
||||||
|
goto bad;
|
||||||
|
setregs();
|
||||||
|
bad1: if (bp)
|
||||||
|
brelse(bp);
|
||||||
|
if (bno)
|
||||||
|
mfree(swapmap, 10, bno);
|
||||||
|
iput(ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read in and set up memory for executed file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
getxfile(ip, nargc)
|
||||||
|
register struct inode *ip;
|
||||||
|
register unsigned nargc;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
register magic, udsize;
|
||||||
|
unsigned int utsize, ussize, head_size;
|
||||||
|
int sepid;
|
||||||
|
int ovly;
|
||||||
|
unsigned long curdsiz;
|
||||||
|
unsigned long code_size, data_size;
|
||||||
|
unsigned long bss_size;
|
||||||
|
int scn, nseg, cseg;
|
||||||
|
int segment;
|
||||||
|
int stackno, offs;
|
||||||
|
char segno[NUSEGS];
|
||||||
|
int j;
|
||||||
|
unsigned int segmts[NUSEGS-1];
|
||||||
|
unsigned int stext;
|
||||||
|
unsigned int sdata;
|
||||||
|
unsigned int sbss;
|
||||||
|
|
||||||
|
u.u_base.l = (caddr_t)&u.u_exdata;
|
||||||
|
u.u_count = sizeof(struct s_head);
|
||||||
|
u.u_offset = 0;
|
||||||
|
u.u_segflg = 1;
|
||||||
|
readi();
|
||||||
|
u.u_segflg = 0;
|
||||||
|
if (u.u_error) /* 1 */
|
||||||
|
return ovly;
|
||||||
|
if (u.u_count){
|
||||||
|
bad0: u.u_error = ENOEXEC;
|
||||||
|
return ovly;
|
||||||
|
}
|
||||||
|
sepid = 0;
|
||||||
|
ovly = 0;
|
||||||
|
if (((magic = u.u_exdata.s_exc.s_magic) & 0x100) == 0){
|
||||||
|
bss_size = 0;
|
||||||
|
data_size = 0;
|
||||||
|
code_size = 0;
|
||||||
|
cseg = 0;
|
||||||
|
nseg = u.u_exdata.s_exc.s_segt/sizeof(struct segt);
|
||||||
|
if (u.u_exdata.s_exc.s_flag & SF_7FSTK)
|
||||||
|
stackno = STAK;
|
||||||
|
else
|
||||||
|
stackno = OLDSEGSTAK;
|
||||||
|
if (nseg > NUSEGS){
|
||||||
|
u.u_error = ENOEXEC;
|
||||||
|
return ovly;
|
||||||
|
}
|
||||||
|
switch (magic){
|
||||||
|
case S_MAGIC3: sepid++;
|
||||||
|
case S_MAGIC1: scn = -1;
|
||||||
|
for (i=0; i < (nseg+1)/2; i++){
|
||||||
|
for(j = 0; ; j++){
|
||||||
|
if ( j <= 1){
|
||||||
|
segment = u.u_exdata.segtable[j].sg_segno;
|
||||||
|
stext = u.u_exdata.segtable[j].sg_code;
|
||||||
|
sdata = u.u_exdata.segtable[j].sg_data;
|
||||||
|
sbss = u.u_exdata.segtable[j].sg_bss;
|
||||||
|
if (++cseg > nseg) /* 10 */
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
segno[++scn] = segment;
|
||||||
|
segmts[scn] = 0;
|
||||||
|
/* 11 */ if (u.u_exdata.segtable[j].sg_atr & SG_CODE){
|
||||||
|
segmts[scn] = stext;
|
||||||
|
/* 12 */ if (sepid){
|
||||||
|
segno[scn] |= 0x80;
|
||||||
|
code_size += (unsigned long)stext;
|
||||||
|
/* 13 */ if (sestabur(lbtoc((long)stext), segno[scn], scn, 0))
|
||||||
|
goto bad0;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
u.u_tseg = segno[scn];
|
||||||
|
u.u_toff = lbtoc((long)stext);
|
||||||
|
data_size += stext;
|
||||||
|
if (sdata == 0 && sbss == 0)
|
||||||
|
if (sestabur(lbtoc((long)stext), segno[scn], scn, 1))
|
||||||
|
goto bad0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 17 */ if (u.u_exdata.segtable[j].sg_atr & SG_DATA){
|
||||||
|
segmts[scn] += sdata;
|
||||||
|
curdsiz = (unsigned long)segmts[scn] + (unsigned long)sbss;
|
||||||
|
if ((unsigned)curdsiz != curdsiz){
|
||||||
|
u.u_error = ENOMEM;
|
||||||
|
return ovly;
|
||||||
|
}
|
||||||
|
data_size += sdata;
|
||||||
|
bss_size += sbss;
|
||||||
|
/* 19 */ if (sestabur(lbtoc((long)(segmts[scn]+sbss)), segno[scn], scn, 1))
|
||||||
|
goto bad0;
|
||||||
|
} else {
|
||||||
|
if (u.u_exdata.segtable[j].sg_atr & SG_BSS){
|
||||||
|
bss_size += sbss;
|
||||||
|
/* 21 */ if (sestabur(lbtoc((long)(sbss + stext)), segno[scn], scn, 1))
|
||||||
|
goto bad0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
u.u_base.l = (caddr_t)u.u_exdata.segtable;
|
||||||
|
u.u_count = 32;
|
||||||
|
u.u_segflg = 1;
|
||||||
|
readi(ip);
|
||||||
|
u.u_segflg = 0;
|
||||||
|
}
|
||||||
|
if (code_size && (ip->i_flag & ITEXT) == 0 && ip->i_count != 1){
|
||||||
|
u.u_error = ENOSEG;
|
||||||
|
return ovly;
|
||||||
|
}
|
||||||
|
ussize = lbtoc((long)nargc) + SSIZE;
|
||||||
|
u.u_stakseg = stackno;
|
||||||
|
/* 25*/ if (sestabur(ussize, stackno, 0, 0))
|
||||||
|
goto bad0;
|
||||||
|
utsize = lbtoc((long)code_size);
|
||||||
|
udsize = lbtoc((long)(data_size + bss_size));
|
||||||
|
if ((utsize+USIZE+udsize+ussize) > umemory){
|
||||||
|
u.u_error = ENOMEM;
|
||||||
|
return ovly;
|
||||||
|
}
|
||||||
|
u.u_segmented = 1;
|
||||||
|
setscr();
|
||||||
|
u.u_exdsz = u.u_exdata.s_exc.s_segt + 24;
|
||||||
|
u.u_nsegs = nseg;
|
||||||
|
/* 27*/ for (i = 0; i < nseg; i++)
|
||||||
|
u.u_segno[i] = segno[i];
|
||||||
|
u.u_sep = (unsigned char)sepid;
|
||||||
|
u.u_prof[0].pr_scale = 0;
|
||||||
|
u.u_nprof = 0;
|
||||||
|
xfree();
|
||||||
|
i = udsize + USIZE + ussize;
|
||||||
|
expand(i);
|
||||||
|
while (--i >= USIZE)
|
||||||
|
clearseg(u.u_procp->p_addr + i);
|
||||||
|
xalloc(ip, code_size, &segmts[0]);
|
||||||
|
if (code_size == 0){
|
||||||
|
invsdrs();
|
||||||
|
segureg();
|
||||||
|
}
|
||||||
|
u.u_offset = u.u_exdsz;
|
||||||
|
for (scn = 0;scn < nseg; scn++){
|
||||||
|
if (u.u_segno[scn] & 0x80){
|
||||||
|
u.u_offset += segmts[scn];
|
||||||
|
sestabur(u.u_segmts[scn].sg_limit+1, u.u_segno[scn], scn, 1);
|
||||||
|
} else {
|
||||||
|
u.u_base.left = ctob(u.u_segno[scn] & 0x7f);
|
||||||
|
u.u_base.right = 0;
|
||||||
|
u.u_count = segmts[scn];
|
||||||
|
readi(ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((u.u_procp->p_flag & STRC) == 0){
|
||||||
|
if ((ip->i_mode & ISUID) && (u.u_uid)){
|
||||||
|
u.u_uid = ip->i_uid;
|
||||||
|
u.u_procp->p_uid = ip->i_uid;
|
||||||
|
}
|
||||||
|
if (ip->i_mode & ISGID)
|
||||||
|
u.u_gid = ip->i_gid;
|
||||||
|
} else
|
||||||
|
psignal(u.u_procp, SIGTRAP);
|
||||||
|
u.u_dsize = u.u_tsize = utsize;
|
||||||
|
u.u_ssize = ussize;
|
||||||
|
segureg();
|
||||||
|
return ovly;
|
||||||
|
case S_MAGIC4:
|
||||||
|
default: u.u_error = ENOEXEC;
|
||||||
|
return ovly;
|
||||||
|
}
|
||||||
|
} else /* von b3 */
|
||||||
|
code_size = u.u_exdata.segtable[0].sg_code;
|
||||||
|
if ((head_size = u.u_exdata.s_exc.s_segt) == sizeof(struct segt) || (magic == N_MAGIC1))
|
||||||
|
data_size = u.u_exdata.segtable[0].sg_data;
|
||||||
|
else
|
||||||
|
data_size = u.u_exdata.segtable[1].sg_data;
|
||||||
|
bss_size = (unsigned)u.u_exdata.s_exc.s_bss;
|
||||||
|
u.u_exdsz = sizeof(struct s_head);
|
||||||
|
if (head_size == sizeof(struct segt))
|
||||||
|
u.u_exdsz -= head_size;
|
||||||
|
switch(magic){
|
||||||
|
case N_MAGIC1:
|
||||||
|
{ data_size = curdsiz = data_size + code_size;
|
||||||
|
u.u_exdata.segtable[0].sg_data = curdsiz;
|
||||||
|
if ((unsigned)curdsiz != curdsiz){
|
||||||
|
u.u_error = ENOMEM;
|
||||||
|
return ovly;
|
||||||
|
}
|
||||||
|
code_size=0;
|
||||||
|
u.u_exdata.segtable[0].sg_code=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case N_MAGIC4:
|
||||||
|
{ ovly++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case N_MAGIC3:
|
||||||
|
{ sepid++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{ u.u_error = ENOEXEC;
|
||||||
|
return ovly;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (code_size && (ip->i_flag & ITEXT) == 0 &&
|
||||||
|
ip->i_count!=(cnt_t)1){
|
||||||
|
u.u_error = ENOSEG;
|
||||||
|
return ovly;
|
||||||
|
}
|
||||||
|
utsize = lbtoc((long)code_size);
|
||||||
|
curdsiz = data_size + bss_size;
|
||||||
|
/* 45 */if ((unsigned)curdsiz != curdsiz){
|
||||||
|
u.u_error = ENOMEM;
|
||||||
|
return ovly;
|
||||||
|
}
|
||||||
|
udsize = lbtoc((long)curdsiz);
|
||||||
|
ussize = lbtoc((long)nargc) + SSIZE;
|
||||||
|
u.u_segmented = 0;
|
||||||
|
setscr();
|
||||||
|
if (ovly){
|
||||||
|
if (u.u_sep == 0)
|
||||||
|
if (ctos(utsize) != ctos(u.u_tsize)){
|
||||||
|
u.u_error = ENOMEM;
|
||||||
|
return ovly;
|
||||||
|
}
|
||||||
|
/* 49 */if (nargc){
|
||||||
|
u.u_error = ENOMEM;
|
||||||
|
return ovly;
|
||||||
|
}
|
||||||
|
udsize = u.u_dsize;
|
||||||
|
ussize = u.u_ssize;
|
||||||
|
sepid = u.u_sep;
|
||||||
|
xfree();
|
||||||
|
xalloc(ip, code_size);
|
||||||
|
u.u_state->s_pc = u.u_exdata.s_exc.s_entry & -2L;
|
||||||
|
} else {
|
||||||
|
u.u_prof[0].pr_scale = 0;
|
||||||
|
xfree();
|
||||||
|
i = udsize + USIZE + ussize;
|
||||||
|
expand(i);
|
||||||
|
while (--i >= USIZE)
|
||||||
|
clearseg(u.u_procp->p_addr + i);
|
||||||
|
xalloc(ip, code_size);
|
||||||
|
estabur(0, udsize, 0, 1);
|
||||||
|
u.u_base.left = USEGW;
|
||||||
|
u.u_base.right = 0;
|
||||||
|
u.u_offset = (unsigned long)(u.u_exdsz+(unsigned)code_size);
|
||||||
|
u.u_count = data_size;
|
||||||
|
readi(ip);
|
||||||
|
/* 51 */ if ((u.u_procp->p_flag & STRC)==0){
|
||||||
|
if ((ip->i_mode & ISUID) && (u.u_uid)){
|
||||||
|
u.u_uid = ip->i_uid;
|
||||||
|
u.u_procp->p_uid = ip->i_uid;
|
||||||
|
}
|
||||||
|
if (ip->i_mode & ISGID)
|
||||||
|
u.u_gid = ip->i_gid;
|
||||||
|
} else
|
||||||
|
psignal(u.u_procp, SIGTRAP);
|
||||||
|
}
|
||||||
|
u.u_tsize = utsize;
|
||||||
|
u.u_dsize = udsize;
|
||||||
|
u.u_ssize = ussize;
|
||||||
|
u.u_sep = (unsigned char)sepid;
|
||||||
|
u.u_stakseg = STAK;
|
||||||
|
estabur(utsize, udsize, ussize, 1);
|
||||||
|
return ovly;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clear registers on exec
|
||||||
|
*/
|
||||||
|
setregs()
|
||||||
|
{
|
||||||
|
register long *rp;
|
||||||
|
register i;
|
||||||
|
register struct file *fp;
|
||||||
|
|
||||||
|
for (rp = &u.u_signal[0]; rp < &u.u_signal[NSIG]; rp++)
|
||||||
|
if ((*rp & 1) == 0)
|
||||||
|
*rp = 0;
|
||||||
|
for (i = 0; i < 15; i++)
|
||||||
|
u.u_state->s_reg[i] = 0;
|
||||||
|
if (u.u_segmented)
|
||||||
|
u.u_state->s_reg[14] = u.u_stakseg<<8;
|
||||||
|
for (i = 0; i < 8; i++){
|
||||||
|
u.u_fpstate.uf_reg[i][0] = 0x3fff;
|
||||||
|
u.u_fpstate.uf_reg[i][1] = 0x8000;
|
||||||
|
u.u_fpstate.uf_reg[i][2] = 0;
|
||||||
|
u.u_fpstate.uf_reg[i][3] = 0;
|
||||||
|
u.u_fpstate.uf_reg[i][4] = 0;
|
||||||
|
}
|
||||||
|
fsetregs();
|
||||||
|
u.u_state->s_pc = u.u_exdata.s_exc.s_entry & -2;
|
||||||
|
if (!u.u_segmented)
|
||||||
|
u.u_state->s_pcseg = USEGW;
|
||||||
|
else
|
||||||
|
u.u_state->s_pcseg = u.u_exdata.s_exc.s_entry >> 16;
|
||||||
|
for (i=0; i<NOFILE; i++) {
|
||||||
|
if (u.u_pofile[i]&EXCLOSE){
|
||||||
|
fp = u.u_ofile[i];
|
||||||
|
u.u_ofile[i] = NULL;
|
||||||
|
closef(fp);
|
||||||
|
u.u_pofile[i] &= ~EXCLOSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Remember file name for accounting.
|
||||||
|
*/
|
||||||
|
u.u_acflag &= ~AFORK;
|
||||||
|
bcopy((caddr_t)u.u_dent.d_name, (caddr_t)u.u_comm, DIRSIZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* exit system call:
|
||||||
|
* pass back caller's arg
|
||||||
|
*/
|
||||||
|
rexit()
|
||||||
|
{
|
||||||
|
register struct a {
|
||||||
|
int rval;
|
||||||
|
} *uap;
|
||||||
|
|
||||||
|
uap = (struct a *)u.u_ap;
|
||||||
|
exit((uap->rval & 0xff) << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Release resources.
|
||||||
|
* Enter zombie state.
|
||||||
|
* Wake up parent and init processes,
|
||||||
|
* and dispose of children.
|
||||||
|
*/
|
||||||
|
exit(rv)
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
register struct proc *p, *q;
|
||||||
|
struct file *fp;
|
||||||
|
|
||||||
|
p = u.u_procp;
|
||||||
|
p->p_flag &= ~(SULOCK | STRC);
|
||||||
|
p->p_clktim = 0;
|
||||||
|
for (i=0; i<NSIG; i++)
|
||||||
|
u.u_signal[i] = 1;
|
||||||
|
if ((p->p_pid == p->p_pgrp)
|
||||||
|
&& (u.u_ttyp != NULL)
|
||||||
|
&& (u.u_ttyp->t_pgrp == p->p_pgrp)) {
|
||||||
|
u.u_ttyp->t_pgrp = 0;
|
||||||
|
signal(p->p_pgrp, SIGHUP);
|
||||||
|
}
|
||||||
|
p->p_pgrp = 0;
|
||||||
|
for (i=0; i<NOFILE; i++) {
|
||||||
|
fp = u.u_ofile[i];
|
||||||
|
u.u_ofile[i] = NULL;
|
||||||
|
closef(fp);
|
||||||
|
}
|
||||||
|
plock(u.u_cdir);
|
||||||
|
iput(u.u_cdir);
|
||||||
|
if (u.u_rdir) {
|
||||||
|
plock(u.u_rdir);
|
||||||
|
iput(u.u_rdir);
|
||||||
|
}
|
||||||
|
xfree();
|
||||||
|
acct();
|
||||||
|
mfree(coremap, p->p_size, p->p_addr);
|
||||||
|
p->p_stat = SZOMB;
|
||||||
|
((struct xproc *)p)->xp_xstat = rv;
|
||||||
|
((struct xproc *)p)->xp_utime = u.u_cutime + u.u_utime;
|
||||||
|
((struct xproc *)p)->xp_stime = u.u_cstime + u.u_stime;
|
||||||
|
for (q = &proc[1]; q < &proc[Nproc]; q++) {
|
||||||
|
if (p->p_pid == q->p_ppid) {
|
||||||
|
q->p_ppid = 1;
|
||||||
|
if (q->p_stat == SZOMB)
|
||||||
|
psignal(&proc[1], SIGCLD);
|
||||||
|
if (q->p_stat == SSTOP)
|
||||||
|
setrun(q);
|
||||||
|
} else if (p->p_ppid==q->p_pid)
|
||||||
|
psignal(q, SIGSYS);
|
||||||
|
if (p->p_pid == q->p_pgrp)
|
||||||
|
q->p_pgrp = 0;
|
||||||
|
}
|
||||||
|
swtch();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait system call.
|
||||||
|
* Search for a terminated (zombie) child,
|
||||||
|
* finally lay it to rest, and collect its status.
|
||||||
|
* Look also for stopped (traced) children,
|
||||||
|
* and pass back status from them.
|
||||||
|
*/
|
||||||
|
wait()
|
||||||
|
{
|
||||||
|
register f;
|
||||||
|
register struct proc *p;
|
||||||
|
|
||||||
|
loop:
|
||||||
|
f = 0;
|
||||||
|
for (p = &proc[1]; p < &proc[Nproc]; p++)
|
||||||
|
if (p->p_ppid == u.u_procp->p_pid) {
|
||||||
|
f++;
|
||||||
|
if (p->p_stat == SZOMB) {
|
||||||
|
freeproc(p, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (p->p_stat == SSTOP) {
|
||||||
|
if ((p->p_flag&SWTED) == 0) {
|
||||||
|
p->p_flag |= SWTED;
|
||||||
|
u.u_r.r_val1 = p->p_pid;
|
||||||
|
u.u_r.r_val2 = (fsig(p)<<8) | 0177;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (f) {
|
||||||
|
sleep((caddr_t)u.u_procp, PWAIT);
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
u.u_error = ECHILD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove zombie children from the process table.
|
||||||
|
*/
|
||||||
|
freeproc(p, flag)
|
||||||
|
register struct proc *p;
|
||||||
|
{
|
||||||
|
if (flag) {
|
||||||
|
u.u_r.r_val1 = p->p_pid;
|
||||||
|
u.u_r.r_val2 = ((struct xproc *)p)->xp_xstat;
|
||||||
|
}
|
||||||
|
u.u_cutime += ((struct xproc *)p)->xp_utime;
|
||||||
|
u.u_cstime += ((struct xproc *)p)->xp_stime;
|
||||||
|
p->p_stat = NULL;
|
||||||
|
p->p_pid = 0;
|
||||||
|
p->p_ppid = 0;
|
||||||
|
p->p_sig = 0L;
|
||||||
|
p->p_flag = 0;
|
||||||
|
p->p_wchan = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fork system call.
|
||||||
|
*/
|
||||||
|
fork()
|
||||||
|
{
|
||||||
|
register struct proc *p1, *p2;
|
||||||
|
register a;
|
||||||
|
register n;
|
||||||
|
|
||||||
|
if (u.u_segmented){
|
||||||
|
n = ctod(u.u_tsize + USIZE + u.u_dsize + u.u_ssize);
|
||||||
|
if ((a = malloc(swapmap, n)) == (int)0){
|
||||||
|
out0: u.u_error = ENOMEM;
|
||||||
|
goto out;
|
||||||
|
} else
|
||||||
|
mfree(swapmap, n, a);
|
||||||
|
} else
|
||||||
|
if ((a = malloc(swapmap, ctod(Maxmem))) == (int)0)
|
||||||
|
goto out0;
|
||||||
|
else
|
||||||
|
mfree(swapmap, ctod(Maxmem), a);
|
||||||
|
for (a=0,p2=0,p1 = &proc[0]; p1 < &proc[Nproc]; p1++){
|
||||||
|
if (p1->p_stat == NULL && p2 == NULL)
|
||||||
|
p2 = p1;
|
||||||
|
if (p1->p_uid == u.u_uid && p1->p_stat)
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
if (!p2 || u.u_uid && ((p2 == &proc[Nproc-1]) || (a>Maxuprc))){
|
||||||
|
u.u_error = EAGAIN;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
p1 = u.u_procp;
|
||||||
|
if (newproc()){
|
||||||
|
u.u_r.r_val1 = p1->p_pid;
|
||||||
|
u.u_start = time;
|
||||||
|
u.u_mem = p2->p_size;
|
||||||
|
u.u_ioch = 0;
|
||||||
|
u.u_iow = 0;
|
||||||
|
u.u_ior = 0;
|
||||||
|
u.u_cstime = 0;
|
||||||
|
u.u_stime = 0;
|
||||||
|
u.u_cutime = 0;
|
||||||
|
u.u_utime = 0;
|
||||||
|
u.u_acflag = AFORK;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
u.u_r.r_val1 = p2->p_pid;
|
||||||
|
|
||||||
|
out:
|
||||||
|
u.u_state->s_pc += NBPW;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,313 @@
|
||||||
|
/* @(#)text.c 1.2 */
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/sysparm.h>
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#include <sys/mmu.h>
|
||||||
|
#include <sys/buf.h>
|
||||||
|
#include <sys/proc.h>
|
||||||
|
#include <sys/text.h>
|
||||||
|
#include <sys/inode.h>
|
||||||
|
#include <sys/map.h>
|
||||||
|
#include <sys/s.out.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
|
||||||
|
char textwstr[]="@[$]text.c Rev : 4.1 08/27/83 12:00:24";
|
||||||
|
extern Ntext;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Swap out process p.
|
||||||
|
* The ff flag causes its core to be freed--
|
||||||
|
* it may be off when called to create an image for a
|
||||||
|
* child process in newproc.
|
||||||
|
* Os is the old size of the data area of the process,
|
||||||
|
* and is supplied during core expansion swaps.
|
||||||
|
*/
|
||||||
|
xswap(p, ff, os)
|
||||||
|
register struct proc *p;
|
||||||
|
{
|
||||||
|
register a;
|
||||||
|
|
||||||
|
if (os == 0)
|
||||||
|
os = p->p_size;
|
||||||
|
a = malloc(swapmap, ctod(p->p_size));
|
||||||
|
if (a == 0L)
|
||||||
|
panic("out of swap space");
|
||||||
|
p->p_flag |= SLOCK;
|
||||||
|
xccdec(p->p_textp);
|
||||||
|
swap(swapdev, a, p->p_addr, os, B_WRITE);
|
||||||
|
if (ff)
|
||||||
|
mfree(coremap, os, p->p_addr);
|
||||||
|
p->p_addr = a;
|
||||||
|
p->p_flag &= ~(SLOAD|SLOCK);
|
||||||
|
p->p_time = 0;
|
||||||
|
if (runout) {
|
||||||
|
runout = 0;
|
||||||
|
wakeup((caddr_t)&runout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* relinquish use of the shared text segment
|
||||||
|
* of a process.
|
||||||
|
*/
|
||||||
|
xfree()
|
||||||
|
{
|
||||||
|
char a[8]; /* fill stack region */
|
||||||
|
register struct text *xp;
|
||||||
|
register struct inode *ip;
|
||||||
|
int s;
|
||||||
|
|
||||||
|
if ((xp=u.u_procp->p_textp) == NULL)
|
||||||
|
return;
|
||||||
|
xlock(xp);
|
||||||
|
xp->x_flag &= ~XLOCK;
|
||||||
|
u.u_procp->p_textp = NULL;
|
||||||
|
ip = xp->x_iptr;
|
||||||
|
if (--xp->x_count==0 && (ip->i_mode&ISVTX)==0) {
|
||||||
|
xp->x_iptr = NULL;
|
||||||
|
mfree(swapmap, (ctod(xp->x_size)), xp->x_daddr);
|
||||||
|
mfree(coremap, xp->x_size, xp->x_caddr);
|
||||||
|
s = dvi();
|
||||||
|
ip->i_flag &= ~ITEXT;
|
||||||
|
if (ip->i_flag&ILOCK)
|
||||||
|
ip->i_count--;
|
||||||
|
else {
|
||||||
|
iput(ip);
|
||||||
|
rvi(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
xccdec(xp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attach to a shared text segment.
|
||||||
|
* If there is no shared text, just return.
|
||||||
|
* If there is, hook up to it:
|
||||||
|
* if it is not currently being used, it has to be read
|
||||||
|
* in from the inode (ip); the written bit is set to force it
|
||||||
|
* to be written out as appropriate.
|
||||||
|
* If it is being used, but is not currently in core,
|
||||||
|
* a swap has to be done to get it back.
|
||||||
|
*/
|
||||||
|
|
||||||
|
xalloc(ip, lc, ld)
|
||||||
|
register struct inode *ip;
|
||||||
|
long lc;
|
||||||
|
register unsigned int ld[];
|
||||||
|
{
|
||||||
|
register struct text *xp;
|
||||||
|
register unsigned ts;
|
||||||
|
register struct text *xp1;
|
||||||
|
short s;
|
||||||
|
unsigned s2;
|
||||||
|
|
||||||
|
if (lc == 0)
|
||||||
|
return;
|
||||||
|
xp1 = NULL;
|
||||||
|
loop:
|
||||||
|
for (xp = &text[0]; xp < &text[Ntext]; xp++) {
|
||||||
|
if (xp->x_iptr == NULL) {
|
||||||
|
if (xp1 == NULL)
|
||||||
|
xp1 = xp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( ip == xp->x_iptr) {
|
||||||
|
xlock(xp);
|
||||||
|
xp->x_count++;
|
||||||
|
u.u_procp->p_textp = xp;
|
||||||
|
if (xp->x_ccount == 0)
|
||||||
|
xexpand(xp);
|
||||||
|
else
|
||||||
|
xp->x_ccount++;
|
||||||
|
xunlock(xp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((xp=xp1) == NULL) {
|
||||||
|
printf("out of text");
|
||||||
|
psignal(u.u_procp, SIGKILL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
xp->x_flag = XLOAD|XLOCK;
|
||||||
|
xp->x_count = 1;
|
||||||
|
xp->x_ccount = 0;
|
||||||
|
xp->x_iptr = ip;
|
||||||
|
ip->i_flag |= ITEXT;
|
||||||
|
ip->i_count++;
|
||||||
|
ts = lbtoc(lc);
|
||||||
|
xp->x_size = ts;
|
||||||
|
if ((xp->x_daddr = malloc(swapmap, ctod((int)ts))) == NULL)
|
||||||
|
panic("out of swap space");
|
||||||
|
u.u_procp->p_textp = xp;
|
||||||
|
xexpand(xp);
|
||||||
|
u.u_segflg = 2;
|
||||||
|
u.u_offset = u.u_exdsz;
|
||||||
|
if (u.u_segmented){
|
||||||
|
invsdrs();
|
||||||
|
segureg();
|
||||||
|
for (s=0; u.u_nsegs > s; s++){
|
||||||
|
s2 = ld[s];
|
||||||
|
if (((int)u.u_segno[s] & 0x80) == 0)
|
||||||
|
u.u_offset += s2;
|
||||||
|
else
|
||||||
|
u.u_count = s2;
|
||||||
|
u.u_base.left = (u.u_segno[s] & 0x7f)<<8;
|
||||||
|
u.u_base.right = 0;
|
||||||
|
u.u_procp->p_flag |= SLOCK; /* proc can't be swapped */
|
||||||
|
readi(ip);
|
||||||
|
u.u_procp->p_flag &= ~SLOCK;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
estabur(ts, 0, 0, 0 );
|
||||||
|
u.u_count = lc.right;
|
||||||
|
u.u_base.left = USEGW;
|
||||||
|
u.u_base.right = 0;
|
||||||
|
u.u_procp->p_flag |= SLOCK;
|
||||||
|
readi(ip);
|
||||||
|
u.u_procp->p_flag &= ~SLOCK;
|
||||||
|
}
|
||||||
|
u.u_segflg = 0;
|
||||||
|
xp->x_flag = XWRIT;/* written into, must swap out */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assure core for text segment
|
||||||
|
* Text must be locked to keep someone else from
|
||||||
|
* freeing it in the meantime.
|
||||||
|
* x_ccount must be 0.
|
||||||
|
*/
|
||||||
|
xexpand(xp)
|
||||||
|
register struct text *xp;
|
||||||
|
{
|
||||||
|
if ((xp->x_caddr = malloc(coremap, xp->x_size)) != NULL) {
|
||||||
|
if ((xp->x_flag&XLOAD)==0)
|
||||||
|
swap(swapdev, xp->x_daddr, xp->x_caddr, xp->x_size, B_READ);
|
||||||
|
xp->x_ccount++;
|
||||||
|
xunlock(xp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (save(u.u_ssav)){
|
||||||
|
setscr();
|
||||||
|
if (u.u_segmented){
|
||||||
|
invsdrs();
|
||||||
|
segureg();
|
||||||
|
} else
|
||||||
|
sureg();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
xswap(u.u_procp, 1, 0);
|
||||||
|
xunlock(xp);
|
||||||
|
u.u_procp->p_flag |= SSWAP;
|
||||||
|
qswtch();
|
||||||
|
/* no return */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lock and unlock a text segment from swapping
|
||||||
|
*/
|
||||||
|
xlock(xp)
|
||||||
|
register struct text *xp;
|
||||||
|
{
|
||||||
|
|
||||||
|
while(xp->x_flag&XLOCK) {
|
||||||
|
xp->x_flag |= XWANT;
|
||||||
|
sleep((caddr_t)xp, PSWP);
|
||||||
|
}
|
||||||
|
xp->x_flag |= XLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
xunlock(xp)
|
||||||
|
register struct text *xp;
|
||||||
|
{
|
||||||
|
|
||||||
|
if (xp->x_flag&XWANT)
|
||||||
|
wakeup((caddr_t)xp);
|
||||||
|
xp->x_flag &= ~(XLOCK|XWANT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decrement the in-core usage count of a shared text segment.
|
||||||
|
* When it drops to zero, free the core space.
|
||||||
|
*/
|
||||||
|
xccdec(xp)
|
||||||
|
register struct text *xp;
|
||||||
|
{
|
||||||
|
|
||||||
|
if (xp==NULL || xp->x_ccount==0)
|
||||||
|
return;
|
||||||
|
xlock(xp);
|
||||||
|
if (--xp->x_ccount==0) {
|
||||||
|
if (xp->x_flag&XWRIT) {
|
||||||
|
xp->x_flag &= ~XWRIT;
|
||||||
|
swap(swapdev, xp->x_daddr, xp->x_caddr, xp->x_size, B_WRITE);
|
||||||
|
}
|
||||||
|
mfree(coremap, xp->x_size, xp->x_caddr);
|
||||||
|
}
|
||||||
|
xunlock(xp);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* free the swap image of all unused saved-text text segments
|
||||||
|
* which are from device dev (used by umount system call).
|
||||||
|
*/
|
||||||
|
xumount(dev)
|
||||||
|
register dev_t dev;
|
||||||
|
{
|
||||||
|
register struct text *xp;
|
||||||
|
|
||||||
|
for (xp = &text[0]; xp < &text[Ntext] ; xp++) {
|
||||||
|
if (xp->x_iptr == NULL)
|
||||||
|
continue;
|
||||||
|
if (dev != xp->x_iptr->i_dev)
|
||||||
|
continue;
|
||||||
|
xuntext(xp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* remove a shared text segment from the text table, if possible.
|
||||||
|
*/
|
||||||
|
xrele(ip)
|
||||||
|
register struct inode *ip;
|
||||||
|
{
|
||||||
|
register struct text *xp;
|
||||||
|
|
||||||
|
if ((ip->i_flag&ITEXT) == 0)
|
||||||
|
return;
|
||||||
|
for (xp = &text[0]; xp < &text[Ntext]; xp++)
|
||||||
|
if (ip==xp->x_iptr)
|
||||||
|
xuntext(xp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* remove text image from the text table.
|
||||||
|
* the use count must be zero.
|
||||||
|
*/
|
||||||
|
xuntext(xp)
|
||||||
|
register struct text *xp;
|
||||||
|
{
|
||||||
|
register struct inode *ip;
|
||||||
|
int s;
|
||||||
|
|
||||||
|
xlock(xp);
|
||||||
|
if (xp->x_count) {
|
||||||
|
xunlock(xp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ip = xp->x_iptr;
|
||||||
|
xp->x_flag &= ~XLOCK;
|
||||||
|
xp->x_iptr = NULL;
|
||||||
|
mfree(swapmap, ctod(xp->x_size), xp->x_daddr);
|
||||||
|
ip->i_flag &= ~ITEXT;
|
||||||
|
s = dvi();
|
||||||
|
if (ip->i_flag&ILOCK)
|
||||||
|
ip->i_count--;
|
||||||
|
else
|
||||||
|
iput(ip);
|
||||||
|
rvi(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue