add part 2 of the WEGA kernel

This commit is contained in:
Oliver Lehmann 2008-05-07 05:02:21 +00:00
parent 4c0135e7e2
commit 97ed1f156c
10 changed files with 3204 additions and 0 deletions

362
WEGA/src/uts/sys/alloc.c Normal file
View File

@ -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);
}

312
WEGA/src/uts/sys/debug.c Normal file
View File

@ -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) */
}

309
WEGA/src/uts/sys/fio.c Normal file
View File

@ -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);
}

341
WEGA/src/uts/sys/iget.c Normal file
View File

@ -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);
}

114
WEGA/src/uts/sys/malloc.c Normal file
View File

@ -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);
}
}
}

107
WEGA/src/uts/sys/mkseg.c Normal file
View File

@ -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;
}

198
WEGA/src/uts/sys/pipe.c Normal file
View File

@ -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);
}

441
WEGA/src/uts/sys/slp.c Normal file
View File

@ -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);
}

707
WEGA/src/uts/sys/sys1.c Normal file
View File

@ -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;
}

313
WEGA/src/uts/sys/text.c Normal file
View File

@ -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;
}