add plain C files from SYSIII

This commit is contained in:
Oliver Lehmann 2008-05-17 16:23:17 +00:00
parent 969b0473d0
commit 50bff6952f
7 changed files with 2300 additions and 0 deletions

109
WEGA/src/uts/sys/acct.c Normal file
View File

@ -0,0 +1,109 @@
#include "sys/param.h"
#include "sys/systm.h"
#include "sys/acct.h"
#include "sys/dir.h"
#include "sys/user.h"
#include "sys/inode.h"
/*
* Perform process accounting functions.
*/
sysacct()
{
register struct inode *ip;
register struct a {
char *fname;
} *uap;
uap = (struct a *)u.u_ap;
if (!suser())
return;
if (uap->fname==NULL) {
if (acctp) {
plock(acctp);
iput(acctp);
acctp = NULL;
}
return;
}
if (acctp) {
u.u_error = EBUSY;
return;
}
#ifndef PNETDFS
ip = namei(uchar, 0);
#else
ip = namei(uchar, 0, NULL);
#endif
if(ip == NULL)
return;
if((ip->i_mode & IFMT) != IFREG) {
u.u_error = EACCES;
iput(ip);
return;
}
acctp = ip;
prele(ip);
}
/*
* On exit, write a record on the accounting file.
*/
acct(st)
{
register struct inode *ip;
off_t siz;
if ((ip=acctp)==NULL)
return;
plock(ip);
bcopy(u.u_comm,acctbuf.ac_comm,sizeof(acctbuf.ac_comm));
acctbuf.ac_btime = u.u_start;
acctbuf.ac_utime = compress(u.u_utime);
acctbuf.ac_stime = compress(u.u_stime);
acctbuf.ac_etime = compress(lbolt - u.u_ticks);
acctbuf.ac_mem = compress(u.u_mem);
acctbuf.ac_io = compress(u.u_ioch);
acctbuf.ac_rw = compress(u.u_ior+u.u_iow);
acctbuf.ac_uid = u.u_ruid;
acctbuf.ac_gid = u.u_rgid;
acctbuf.ac_tty = u.u_ttyp ? u.u_ttyd : NODEV;
acctbuf.ac_stat = st;
acctbuf.ac_flag = u.u_acflag;
siz = ip->i_size;
u.u_offset = siz;
u.u_base = (caddr_t)&acctbuf;
u.u_count = sizeof(acctbuf);
u.u_segflg = 1;
u.u_error = 0;
u.u_limit = (daddr_t)5000;
writei(ip);
if(u.u_error)
ip->i_size = siz;
prele(ip);
}
/*
* Produce a pseudo-floating point representation
* with 3 bits base-8 exponent, 13 bits fraction.
*/
compress(t)
register time_t t;
{
register exp = 0, round = 0;
while (t >= 8192) {
exp++;
round = t&04;
t >>= 3;
}
if (round) {
t++;
if (t >= 8192) {
t >>= 3;
exp++;
}
}
return((exp<<13) + t);
}

265
WEGA/src/uts/sys/nami.c Normal file
View File

@ -0,0 +1,265 @@
/******************************************************************************
*******************************************************************************
W E G A - Quelle
KERN 3.2 Modul: nami.c
Bearbeiter: O. Lehmann
Datum: 17.05.08
Version: 1.0
*******************************************************************************
******************************************************************************/
char namiwstr[] = "@[$]nami.c Rev : 4.1 08/27/83 11:56:22";
#include <sys/param.h>
#include <sys/sysparm.h>
#include <sys/sysinfo.h>
#include <sys/systm.h>
#include <sys/mount.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>
/*
* Convert a pathname into a pointer to
* an inode. Note that the inode is locked.
*
* func = function called to get next char of name
* &uchar if name is in user space
* &schar if name is in system space
* flag = 0 if name is sought
* 1 if name is to be created
* 2 if name is to be deleted
*/
struct inode *
namei(func, flag)
int (*func)();
{
register struct inode *dp;
register c;
register char *cp;
struct buf *bp;
int i;
dev_t d;
off_t eo;
/*
* If name starts with '/' start from
* root; otherwise start from current dir.
*/
sysinfo.namei++;
c = (*func)();
if (c == '\0') {
u.u_error = ENOENT;
return(NULL);
}
if (c == '/') {
if ((dp = u.u_rdir) == NULL)
dp = rootdir;
while(c == '/')
c = (*func)();
if(c == '\0' && flag != 0) {
u.u_error = ENOENT;
return(NULL);
}
} else
dp = u.u_cdir;
iget(dp->i_dev, dp->i_number);
cloop:
/*
* Here dp contains pointer
* to last component matched.
*/
if(u.u_error)
goto out;
if(c == '\0')
return(dp);
/*
* If there is another component,
* gather up name into users' dir buffer.
*/
cp = &u.u_dent.d_name[0];
while(c != '/' && c != '\0' && u.u_error == 0) {
if(cp < &u.u_dent.d_name[DIRSIZ])
*cp++ = c;
c = (*func)();
}
while(cp < &u.u_dent.d_name[DIRSIZ])
*cp++ = '\0';
while(c == '/')
c = (*func)();
seloop:
/*
* dp must be a directory and
* must have X permission.
*/
if ((dp->i_mode&IFMT) != IFDIR || dp->i_nlink==0)
u.u_error = ENOTDIR;
else
access(dp, IEXEC);
if (u.u_error)
goto out;
/*
* set up to search a directory
*/
u.u_offset = 0;
eo = 0;
bp = NULL;
if (dp == u.u_rdir)
if (u.u_dent.d_name[0] == '.')
if (u.u_dent.d_name[1] == '.')
if (u.u_dent.d_name[2] == '\0')
goto cloop;
eloop:
/*
* If at the end of the directory,
* the search failed. Report what
* is appropriate as per flag.
*/
if(u.u_offset >= dp->i_size) {
if(bp != NULL)
brelse(bp);
if(flag==1 && c=='\0') {
if(access(dp, IWRITE))
goto out;
u.u_pdir = dp;
if (eo)
u.u_offset = eo - sizeof(struct direct);
bmap(dp, (daddr_t)(u.u_offset>>BSHIFT), B_WRITE);
if (u.u_error)
goto out;
return(NULL);
}
u.u_error = ENOENT;
goto out;
}
/*
* If offset is on a block boundary,
* read the next directory block.
* Release previous if it exists.
*/
if((u.u_offset&BMASK) == 0) {
daddr_t bn;
if(bp != NULL)
brelse(bp);
sysinfo.dirblk++;
bn = bmap(dp, (daddr_t)(u.u_offset>>BSHIFT), B_READ);
if (u.u_error)
goto out;
if (bn < 0) {
u.u_error = EIO;
goto out;
}
bp = bread(dp->i_dev, bn);
if (u.u_error) {
brelse(bp);
goto out;
}
}
/*
* Note first empty directory slot
* in eo for possible creat.
* String compare the directory entry
* and the current component.
* If they do not match, go back to eloop.
*/
cp = bp->b_un.b_addr+(u.u_offset&BMASK);
u.u_offset += sizeof(struct direct);
u.u_dent.d_ino = ((struct direct *)cp)->d_ino;
if(u.u_dent.d_ino == 0) {
if(eo == 0)
eo = u.u_offset;
goto eloop;
}
cp = &((struct direct *)cp)->d_name[0];
for(i=0; i<DIRSIZ; i++)
if(*cp++ != u.u_dent.d_name[i])
goto eloop;
/*
* Here a component matched in a directory.
* If there is more pathname, go back to
* cloop, otherwise return.
*/
if(bp != NULL)
brelse(bp);
if(flag==2 && c=='\0') {
if(access(dp, IWRITE))
goto out;
return(dp);
}
d = dp->i_dev;
if(u.u_dent.d_ino == ROOTINO)
if(dp->i_number == ROOTINO)
if(u.u_dent.d_name[1] == '.')
for(i=1; i<NMOUNT; i++)
if(mount[i].m_flags == MINUSE)
if(mount[i].m_dev == d) {
iput(dp);
dp = mount[i].m_inodp;
dp->i_count++;
plock(dp);
goto seloop;
}
iput(dp);
dp = iget(d, u.u_dent.d_ino);
if(dp == NULL)
return(NULL);
goto cloop;
out:
iput(dp);
return(NULL);
}
/*
* Return the next character from the
* kernel string pointed at by dirp.
*/
schar()
{
return(u.u_dirp.left++ & 0377);
}
/*
* Return the next character from the
* user string pointed at by dirp.
*/
uchar()
{
register c;
c = fubyte(u.u_dirp.left++);
if(!c)
u.u_error = EFAULT;
return(c);
}

425
WEGA/src/uts/sys/sig.c Normal file
View File

@ -0,0 +1,425 @@
#include "sys/plexus.h"
#include "sys/param.h"
#include "sys/systm.h"
#include "sys/dir.h"
#include "sys/user.h"
#include "sys/proc.h"
#include "sys/inode.h"
#include "sys/reg.h"
#include "sys/text.h"
#include "sys/seg.h"
#include "sys/var.h"
#include "sys/psl.h"
/*
* Priority for tracing
*/
#define IPCPRI PZERO
/*
* Tracing variables.
* Used to pass trace command from
* parent to child being traced.
* This data base cannot be
* shared and is locked
* per user.
*/
struct
{
int ip_lock;
int ip_req;
int *ip_addr;
int ip_data;
} ipc;
/*
* Send the specified signal to
* all processes with 'pgrp' as
* process group.
* Called by tty.c for quits and
* interrupts.
*/
signal(pgrp, sig)
register pgrp;
{
register struct proc *p;
if(pgrp == 0)
return;
for(p = &proc[1]; p < (struct proc *)v.ve_proc; p++)
if(p->p_pgrp == pgrp)
psignal(p, sig);
}
/*
* Send the specified signal to
* the specified process.
*/
psignal(p, sig)
register struct proc *p;
register sig;
{
sig--;
if (sig < 0 || sig >= NSIG)
return;
p->p_sig |= 1L<<sig;
if(p->p_stat == SSLEEP && p->p_pri > PZERO) {
if(p->p_pri > PUSER)
p->p_pri = PUSER;
setrun(p);
}
}
/*
* Returns true if the current
* process has a signal to process.
* This is asked at least once
* each time a process enters the
* system.
* A signal does not do anything
* directly to a process; it sets
* a flag that asks the process to
* do something to itself.
*/
issig()
{
register n;
register struct proc *p, *q;
p = u.u_procp;
while(p->p_sig) {
n = fsig(p);
if (n == SIGCLD) {
if (u.u_signal[SIGCLD-1]&01) {
for (q = &proc[1];
q < (struct proc *)v.ve_proc; q++) {
if (p->p_pid == q->p_ppid &&
q->p_stat == SZOMB)
freeproc(q, 0) ;
}
} else
if (u.u_signal[SIGCLD-1])
return(n) ;
} else
if((u.u_signal[n-1]&1) == 0 || (p->p_flag&STRC))
return(n);
p->p_sig &= ~(1L<<(n-1));
}
return(0);
}
/*
* Enter the tracing STOP state.
* In this state, the parent is
* informed and the process is able to
* receive commands from the parent.
*/
stop()
{
register struct proc *pp, *cp;
loop:
cp = u.u_procp;
if(cp->p_ppid != 1)
for (pp = &proc[0]; pp < (struct proc *)v.ve_proc; pp++)
if (pp->p_pid == cp->p_ppid) {
wakeup((caddr_t)pp);
cp->p_stat = SSTOP;
swtch();
if ((cp->p_flag&STRC)==0 || procxmt())
return;
goto loop;
}
exit(fsig(u.u_procp));
}
/*
* Perform the action specified by
* the current signal.
* The usual sequence is:
* if(issig())
* psig();
*/
psig()
{
register n, p;
register struct proc *rp;
rp = u.u_procp;
if (rp->p_flag&STRC)
stop();
n = fsig(rp);
if (n==0)
return;
rp->p_sig &= ~(1L<<(n-1));
if((p=u.u_signal[n-1]) != 0) {
u.u_error = 0;
if(n != SIGILL && n != SIGTRAP)
u.u_signal[n-1] = 0;
sendsig(p, n);
return;
}
switch(n) {
case SIGQUIT:
case SIGILL:
case SIGTRAP:
case SIGIOT:
case SIGEMT:
case SIGFPE:
case SIGBUS:
case SIGSEGV:
case SIGSYS:
if(core())
n += 0200;
}
exit(n);
}
/*
* find the signal in bit-position
* representation in p_sig.
*/
fsig(p)
struct proc *p;
{
register i;
long n;
n = p->p_sig;
for(i=1; i<=NSIG; i++) {
if(n & 1L)
return(i);
n >>= 1;
}
return(0);
}
/*
* Create a core image on the file "core"
*
* It writes USIZE block of the
* user.h area followed by the entire
* data+stack segments.
*/
core()
{
register struct inode *ip;
register unsigned s;
extern schar();
if (u.u_uid != u.u_ruid)
return(0);
u.u_error = 0;
u.u_dirp = "core";
#ifndef PNETDFS
ip = namei(schar, 1);
#else
ip = namei(schar, 1, NULL);
#endif
if(ip == NULL) {
if(u.u_error)
return(0);
ip = maknode(0666);
if (ip==NULL)
return(0);
}
if(!access(ip, IWRITE) && (ip->i_mode&IFMT) == IFREG) {
itrunc(ip);
u.u_offset = 0;
u.u_base = (caddr_t)&u;
u.u_count = ctob(USIZE);
u.u_segflg = 1;
u.u_limit = (daddr_t)ctod(MAXMEM);
writei(ip);
s = u.u_procp->p_size - USIZE;
estabur((unsigned)0, s, (unsigned)0, 0, RO);
u.u_base = 0;
u.u_count = ctob(s);
u.u_segflg = 0;
writei(ip);
} else
u.u_error = EACCES;
iput(ip);
return(u.u_error==0);
}
/*
* grow the stack to include the SP
* true return if successful.
*/
grow(sp)
unsigned sp;
{
register si, i;
register struct proc *p;
register a;
si = btoc(USRSTACK-sp) - u.u_ssize;
if(si <= 0)
return(0);
if(estabur(u.u_tsize, u.u_dsize, u.u_ssize+si, u.u_sep, RO))
return(0);
p = u.u_procp;
expand(p->p_size+si);
a = p->p_addr + p->p_size;
for(i=u.u_ssize; i; i--) {
a--;
copyseg(a-si, a);
}
for(i=si; i; i--)
clearseg(--a);
u.u_ssize += si;
return(1);
}
/*
* sys-trace system call.
*/
ptrace()
{
register struct proc *p;
register struct a {
int data;
int pid;
int *addr;
int req;
} *uap;
uap = (struct a *)u.u_ap;
if (uap->req <= 0) {
u.u_procp->p_flag |= STRC;
return;
}
for (p=proc; p < (struct proc *)v.ve_proc; p++)
if (p->p_stat==SSTOP
&& p->p_pid==uap->pid
&& p->p_ppid==u.u_procp->p_pid)
goto found;
u.u_error = ESRCH;
return;
found:
while (ipc.ip_lock)
sleep((caddr_t)&ipc, IPCPRI);
ipc.ip_lock = p->p_pid;
ipc.ip_data = uap->data;
ipc.ip_addr = uap->addr;
ipc.ip_req = uap->req;
p->p_flag &= ~SWTED;
setrun(p);
while (ipc.ip_req > 0)
sleep((caddr_t)&ipc, IPCPRI);
u.u_rval1 = ipc.ip_data;
if (ipc.ip_req < 0)
u.u_error = EIO;
ipc.ip_lock = 0;
wakeup((caddr_t)&ipc);
}
/*
* Code that the child process
* executes to implement the command
* of the parent process in tracing.
*/
procxmt()
{
register int i;
register *p;
register struct text *xp;
if (ipc.ip_lock != u.u_procp->p_pid)
return(0);
i = ipc.ip_req;
ipc.ip_req = 0;
wakeup((caddr_t)&ipc);
switch (i) {
/* read user I */
case 1:
ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
break;
/* read user D */
case 2:
ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
break;
/* read u */
case 3:
i = (int)ipc.ip_addr;
if (i<0 || i >= ctob(USIZE))
goto error;
ipc.ip_data = ((physadr)&u)->r[i>>1];
break;
/* write user I */
/* Must set up to allow writing */
case 4:
/*
* If text, must assure exclusive use
*/
if (xp = u.u_procp->p_textp) {
if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX)
goto error;
xp->x_iptr->i_flag &= ~ITEXT;
}
estabur(u.u_tsize, u.u_dsize, u.u_ssize, u.u_sep, RW);
i = suiword((caddr_t)ipc.ip_addr, 0);
suiword((caddr_t)ipc.ip_addr, ipc.ip_data);
estabur(u.u_tsize, u.u_dsize, u.u_ssize, u.u_sep, RO);
if (i<0)
goto error;
if (xp)
xp->x_flag |= XWRIT;
break;
/* write user D */
case 5:
if (suword((caddr_t)ipc.ip_addr, 0) < 0)
goto error;
suword((caddr_t)ipc.ip_addr, ipc.ip_data);
break;
/* write u */
case 6:
i = (int)ipc.ip_addr;
p = (int *)&((physadr)&u)->r[i>>1];
for (i=0; i<15; i++)
if (p == &u.u_ar0[regloc[i]])
goto ok;
if (p == &u.u_ar0[PC])
goto ok;
if (p == &u.u_ar0[FCW]) {
ipc.ip_data &= (M_FLGS << S_FLGS);
ipc.ip_data |= (B_VI | B_NVI);
goto ok;
}
goto error;
ok:
*p = ipc.ip_data;
break;
/* set signal and continue */
/* one version causes a trace-trap */
case 9:
u.u_ar0[FCW] |= B_SINGL;
case 7:
u.u_procp->p_sig = 0;
if (ipc.ip_data)
psignal(u.u_procp, ipc.ip_data);
return(1);
/* force exit */
case 8:
exit(fsig(u.u_procp));
default:
error:
ipc.ip_req = -1;
}
return(0);
}

435
WEGA/src/uts/sys/sys2.c Normal file
View File

@ -0,0 +1,435 @@
#include "sys/param.h"
#include "sys/systm.h"
#include "sys/dir.h"
#include "sys/user.h"
#include "sys/file.h"
#include "sys/inode.h"
#include "sys/sysinfo.h"
#ifdef PNETDFS
extern ddbug;
#endif
/*
* read system call
*/
read()
{
rdwr(FREAD);
}
/*
* write system call
*/
write()
{
rdwr(FWRITE);
}
/*
* common code for read and write calls:
* check permissions, set base, count, and offset,
* and switch out to readi or writei code.
*/
rdwr(mode)
register mode;
{
register struct file *fp;
register struct inode *ip;
register struct a {
int fdes;
char *cbuf;
unsigned count;
} *uap;
int type;
uap = (struct a *)u.u_ap;
fp = getf(uap->fdes);
if (fp == NULL)
return;
if ((fp->f_flag&mode) == 0) {
u.u_error = EBADF;
return;
}
u.u_base = (caddr_t)uap->cbuf;
u.u_count = uap->count;
u.u_segflg = 0;
u.u_fmode = fp->f_flag;
ip = fp->f_inode;
#ifdef PNETDFS
if ( ip->i_flag & IRMT ) {
rrdwr( ip, uap->fdes, mode );
goto dfsout;
}
#endif
type = ip->i_mode&IFMT;
if (type==IFREG || type==IFDIR) {
if ((u.u_fmode&FAPPEND) && (mode == FWRITE))
fp->f_offset = ip->i_size;
if (ip->i_locklist &&
locked(1, ip, fp->f_offset, fp->f_offset + u.u_count))
return;
plock(ip);
} else if (type == IFIFO) {
fp->f_offset = 0;
if (ip->i_locklist &&
locked(1, ip, fp->f_offset, fp->f_offset + u.u_count))
return;
plock(ip);
}
u.u_offset = fp->f_offset;
if (mode == FREAD)
readi(ip);
else
writei(ip);
if (type==IFREG || type==IFDIR || type==IFIFO)
prele(ip);
#ifdef PNETDFS
dfsout:
#endif
fp->f_offset += uap->count-u.u_count;
u.u_rval1 = uap->count-u.u_count;
u.u_ioch += u.u_rval1;
if (mode == FREAD)
sysinfo.readch += u.u_rval1;
else
sysinfo.writech += u.u_rval1;
}
/*
* open system call
*/
open()
{
register struct a {
char *fname;
int mode;
int crtmode;
} *uap;
uap = (struct a *)u.u_ap;
copen(uap->mode-FOPEN, uap->crtmode);
}
/*
* creat system call
*/
creat()
{
register struct a {
char *fname;
int fmode;
} *uap;
uap = (struct a *)u.u_ap;
copen(FWRITE|FCREAT|FTRUNC, uap->fmode);
}
/*
* common code for open and creat.
* Check permissions, allocate an open file structure,
* and call the device open routine if any.
*/
copen(mode, arg)
register mode;
{
register struct inode *ip;
register struct file *fp;
int i;
if ((mode&(FREAD|FWRITE)) == 0) {
u.u_error = EINVAL;
return;
}
if (mode&FCREAT) {
#ifndef PNETDFS
ip = namei(uchar, 1);
#else
ip = namei(uchar, 1, NULL);
#endif
if (ip == NULL) {
if (u.u_error)
return;
ip = maknode(arg&07777&(~ISVTX));
if (ip == NULL)
return;
mode &= ~FTRUNC;
} else {
if (ip->i_locklist != NULL &&
(ip->i_flag & IFMT) == IFREG &&
locked(2, ip, (long)(0L), (long)(1L<<30))) {
iput(ip);
return;
}
if (mode&FEXCL) {
u.u_error = EEXIST;
iput(ip);
return;
}
mode &= ~FCREAT;
}
} else {
#ifndef PNETDFS
ip = namei(uchar, 0);
#else
ip = namei(uchar, 0, NULL);
#endif
if (ip == NULL)
return;
}
if (!(mode&FCREAT)) {
if (mode&FREAD)
access(ip, IREAD);
if (mode&(FWRITE|FTRUNC)) {
access(ip, IWRITE);
if ((ip->i_mode&IFMT) == IFDIR)
u.u_error = EISDIR;
}
}
if (u.u_error || (fp = falloc()) == NULL) {
iput(ip);
return;
}
if (mode&FTRUNC)
itrunc(ip);
prele(ip);
fp->f_flag = mode&FMASK;
fp->f_inode = ip;
i = u.u_rval1;
if (setjmp(u.u_qsav)) { /* catch half-opens */
if (u.u_abreq)
(*u.u_abreq)();
if (u.u_error == 0)
u.u_error = EINTR;
closef(fp);
u.u_ofile[i] = NULL;
} else {
openi(ip, mode);
if (u.u_error == 0)
return;
u.u_ofile[i] = NULL;
fp->f_count--;
iput(ip);
}
}
/*
* close system call
*/
close()
{
register struct file *fp;
register struct a {
int fdes;
} *uap;
uap = (struct a *)u.u_ap;
fp = getf(uap->fdes);
if (fp == NULL)
return;
closef(fp);
u.u_ofile[uap->fdes] = NULL;
}
/*
* seek system call
*/
seek()
{
register struct file *fp;
register struct inode *ip;
register struct a {
int fdes;
off_t off;
int sbase;
} *uap;
uap = (struct a *)u.u_ap;
fp = getf(uap->fdes);
if (fp == NULL)
return;
ip = fp->f_inode;
if ((ip->i_mode&IFMT)==IFIFO) {
u.u_error = ESPIPE;
return;
}
#ifdef PNETDFS
if ( ip->i_flag & IRMT ) {
if ( ddbug ) {
printf( "remote seek %x\n", ip );
debug();
}
rseek( uap->fdes, uap->off, uap->sbase );
return;
}
#endif
if (uap->sbase == 1)
uap->off += fp->f_offset;
else if (uap->sbase == 2)
uap->off += fp->f_inode->i_size;
else if (uap->sbase != 0) {
u.u_error = EINVAL;
psignal(u.u_procp, SIGSYS);
return;
}
if (uap->off < 0) {
u.u_error = EINVAL;
return;
}
fp->f_offset = uap->off;
u.u_roff = uap->off;
}
/*
* link system call
*/
link()
{
register struct inode *ip, *xp;
register struct a {
char *target;
char *linkname;
} *uap;
uap = (struct a *)u.u_ap;
#ifndef PNETDFS
ip = namei(uchar, 0);
#else
ip = namei(uchar, 0, NULL);
#endif
if (ip == NULL)
return;
if (ip->i_nlink >= MAXLINK) {
u.u_error = EMLINK;
goto out;
}
if ((ip->i_mode&IFMT)==IFDIR && !suser())
goto out;
/*
* Unlock to avoid possibly hanging the namei.
* Sadly, this means races. (Suppose someone
* deletes the file in the meantime?)
* Nor can it be locked again later
* because then there will be deadly
* embraces.
*/
prele(ip);
u.u_dirp = (caddr_t)uap->linkname;
#ifndef PNETDFS
xp = namei(uchar, 1);
#else
xp = namei(uchar, 1, NULL);
#endif
if (xp != NULL) {
u.u_error = EEXIST;
iput(xp);
goto out;
}
if (u.u_error)
goto out;
#ifdef PNETDFS
if ( u.u_pdir && u.u_pdir->i_flag & IRMT ) {
printf( "link on remote dfs, not there yet\n" );
debug();
u.u_error = EXDEV;
iput( u.u_pdir );
goto out;
}
#endif
if (u.u_pdir->i_dev != ip->i_dev) {
iput(u.u_pdir);
u.u_error = EXDEV;
goto out;
}
wdir(ip);
if (u.u_error==0) {
ip->i_nlink++;
ip->i_flag |= ICHG;
}
out:
iput(ip);
}
/*
* mknod system call
*/
mknod()
{
register struct inode *ip;
register struct a {
char *fname;
int fmode;
dev_t dev;
} *uap;
#ifdef PNETDFS
struct inode *rmaknode();
#endif
uap = (struct a *)u.u_ap;
if ((uap->fmode&IFMT) != IFIFO && !suser())
return;
#ifndef PNETDFS
ip = namei(uchar, 1);
#else
ip = namei(uchar, 1, NULL);
#endif
if (ip != NULL) {
u.u_error = EEXIST;
goto out;
}
if (u.u_error)
return;
#ifdef PNETDFS
if ( u.u_pdir->i_flag & IRMT ) {
ip = rmaknode( uap->fmode );
return;
}
#endif
ip = maknode(uap->fmode);
if (ip == NULL)
return;
switch(ip->i_mode&IFMT) {
case IFCHR:
case IFBLK:
ip->i_rdev = (dev_t)uap->dev;
ip->i_flag |= ICHG;
}
out:
iput(ip);
}
/*
* access system call
*/
saccess()
{
register svuid, svgid;
register struct inode *ip;
register struct a {
char *fname;
int fmode;
} *uap;
uap = (struct a *)u.u_ap;
svuid = u.u_uid;
svgid = u.u_gid;
u.u_uid = u.u_ruid;
u.u_gid = u.u_rgid;
#ifndef PNETDFS
ip = namei(uchar, 0);
#else
ip = namei(uchar, 0, NULL);
#endif
if (ip != NULL) {
if (uap->fmode&(IREAD>>6))
access(ip, IREAD);
if (uap->fmode&(IWRITE>>6))
access(ip, IWRITE);
if (uap->fmode&(IEXEC>>6))
access(ip, IEXEC);
iput(ip);
}
u.u_uid = svuid;
u.u_gid = svgid;
}

428
WEGA/src/uts/sys/sys3.c Normal file
View File

@ -0,0 +1,428 @@
#include "sys/param.h"
#include "sys/systm.h"
#include "sys/stat.h"
#include "sys/mount.h"
#include "sys/ino.h"
#include "sys/buf.h"
#include "sys/filsys.h"
#include "sys/dir.h"
#include "sys/user.h"
#include "sys/inode.h"
#include "sys/file.h"
#include "sys/conf.h"
#include "sys/ioctl.h"
#include "sys/var.h"
#ifdef PNETDFS
extern ddbug;
#endif
/*
* the fstat system call.
*/
fstat()
{
register struct file *fp;
register struct a {
int fdes;
struct stat *sb;
} *uap;
uap = (struct a *)u.u_ap;
fp = getf(uap->fdes);
if(fp == NULL)
return;
stat1(fp->f_inode, uap->sb);
}
/*
* the stat system call.
*/
stat()
{
register struct inode *ip;
register struct a {
char *fname;
struct stat *sb;
} *uap;
uap = (struct a *)u.u_ap;
#ifndef PNETDFS
ip = namei(uchar, 0);
#else
ip = namei(uchar, 0, NULL);
#endif
if(ip == NULL)
return;
stat1(ip, uap->sb);
iput(ip);
}
/*
* The basic routine for fstat and stat:
* get the inode and pass appropriate parts back.
*/
stat1(ip, ub)
register struct inode *ip;
struct stat *ub;
{
register struct buf *bp;
struct stat ds;
#ifdef PNETDFS
if ( ip->i_flag & IRMT ) {
rstat1( ip, ub );
return;
}
#endif
if(ip->i_flag&(IACC|IUPD|ICHG))
iupdat(ip, &time, &time);
/*
* first copy from inode table
*/
ds.st_dev = ip->i_dev;
ds.st_ino = ip->i_number;
ds.st_mode = ip->i_mode;
ds.st_nlink = ip->i_nlink;
ds.st_uid = ip->i_uid;
ds.st_gid = ip->i_gid;
ds.st_rdev = (dev_t)ip->i_rdev;
ds.st_size = ip->i_size;
/*
* next the dates in the disk
*/
bp = bread(ip->i_dev, itod(ip->i_number));
copyio(paddr(bp)+itoo(ip->i_number)*sizeof(struct dinode)
+(long)(&((struct dinode *)0)->di_atime),
&ds.st_atime, 3*sizeof(time_t), U_RKD);
brelse(bp);
if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0)
u.u_error = EFAULT;
}
/*
* the dup system call.
*
* dup2 has been added to the stock SYSTEM III code for compatibility
* with v7.
*/
dup()
{
register struct file *fp;
register struct a {
int fdes;
int fdes2;
} *uap;
register i,m;
uap = (struct a *)u.u_ap;
m = uap->fdes & ~077;
uap->fdes &= 077;
fp = getf(uap->fdes);
if(fp == NULL)
return;
if ((m&0100) == 0) {
if ((i = ufalloc(0)) < 0)
return;
} else {
i = uap->fdes2;
if (i<0 || i>=NOFILE) {
u.u_error = EBADF;
return;
}
u.u_rval1 = i;
}
if (i!=uap->fdes) {
if (u.u_ofile[i]!=NULL)
closef(u.u_ofile[i]);
u.u_ofile[i] = fp;
fp->f_count++;
}
}
/*
* the file control system call.
*/
fcntl()
{
register struct file *fp;
register struct a {
int fdes;
int cmd;
int arg;
} *uap;
register i;
uap = (struct a *)u.u_ap;
fp = getf(uap->fdes);
if (fp == NULL)
return;
switch(uap->cmd) {
case 0:
i = uap->arg;
if (i < 0 || i > NOFILE) {
u.u_error = EINVAL;
return;
}
if ((i = ufalloc(i)) < 0)
return;
#ifdef PNETDFS
if ( fp->f_inode->i_flag & IRMT ) {
if ( ddbug ) {
printf( "fcntl dup on remote file %x\n", fp );
debug();
}
rfcntl( uap->fdes, i, 0, uap->arg );
}
#endif
u.u_ofile[i] = fp;
fp->f_count++;
break;
case 1:
u.u_rval1 = u.u_pofile[uap->fdes];
break;
case 2:
u.u_pofile[uap->fdes] = uap->arg;
break;
case 3:
u.u_rval1 = fp->f_flag+FOPEN;
break;
case 4:
fp->f_flag &= (FREAD|FWRITE);
#ifdef PNETDFS
if ( fp->f_inode->i_flag & IRMT ) {
if ( ddbug ) {
printf( "fcntl setfl on remote file %x\n", fp );
debug();
}
rfcntl( uap->fdes, i, 4, uap->arg );
}
#endif
fp->f_flag |= (uap->arg-FOPEN) & ~(FREAD|FWRITE);
break;
default:
u.u_error = EINVAL;
}
}
/*
* character special i/o control
*/
ioctl()
{
register struct file *fp;
register struct inode *ip;
register struct a {
int fdes;
int cmd;
int arg;
} *uap;
register dev_t dev;
uap = (struct a *)u.u_ap;
if ((fp = getf(uap->fdes)) == NULL)
return;
ip = fp->f_inode;
if ((ip->i_mode&IFMT) != IFCHR) {
u.u_error = ENOTTY;
return;
}
u.u_rval1 = 0;
#ifdef PNETDFS
if ( ip->i_flag & IRMT ) {
rioctl( uap->fdes, uap->cmd, uap->arg );
return;
}
#endif
dev = (dev_t)ip->i_rdev;
(*cdevsw[major(dev)].d_ioctl)(minor(dev),uap->cmd,uap->arg,fp->f_flag);
}
/*
* old stty and gtty
*/
stty()
{
register struct a {
int fdes;
int arg;
int narg;
} *uap;
uap = (struct a *)u.u_ap;
uap->narg = uap->arg;
uap->arg = TIOCSETP;
ioctl();
}
gtty()
{
register struct a {
int fdes;
int arg;
int narg;
} *uap;
uap = (struct a *)u.u_ap;
uap->narg = uap->arg;
uap->arg = TIOCGETP;
ioctl();
}
/*
* the mount system call.
*/
smount()
{
dev_t dev;
register struct inode *ip;
register struct mount *mp;
struct mount *smp;
register struct filsys *fp;
struct buf *bp;
register struct a {
char *fspec;
char *freg;
int ronly;
} *uap;
uap = (struct a *)u.u_ap;
if(!suser())
return;
dev = getmdev();
if(u.u_error)
return;
u.u_dirp = (caddr_t)uap->freg;
#ifndef PNETDFS
ip = namei(uchar, 0);
#else
ip = namei(uchar, 0, NULL);
#endif
if(ip == NULL)
return;
if ((ip->i_mode&IFMT) != IFDIR) {
u.u_error = ENOTDIR;
goto out;
}
if (ip->i_count != 1)
goto out;
if (ip->i_number == ROOTINO)
goto out;
smp = NULL;
for(mp = &mount[0]; mp < (struct mount *)v.ve_mount; mp++) {
if(mp->m_flags != MFREE) {
if(dev == mp->m_dev)
goto out;
} else
if(smp == NULL)
smp = mp;
}
mp = smp;
if(mp == NULL)
goto out;
mp->m_flags = MINTER;
mp->m_dev = dev;
(*bdevsw[major(dev)].d_open)(minor(dev), !uap->ronly);
if(u.u_error)
goto out1;
bp = bread(dev, SUPERB);
if(u.u_error) {
brelse(bp);
goto out1;
}
mp->m_inodp = ip;
mp->m_bufp = getablk(1);
fp = (struct filsys *)paddr(mp->m_bufp);
copyio(paddr(bp), fp, sizeof(struct filsys), U_RKD);
mp->m_flags = MINUSE;
fp->s_ilock = 0;
fp->s_flock = 0;
fp->s_ninode = 0;
fp->s_inode[0] = 0;
fp->s_ronly = uap->ronly & 1;
brelse(bp);
ip->i_flag |= IMOUNT;
prele(ip);
return;
out1:
mp->m_flags = MFREE;
out:
if (u.u_error == 0)
u.u_error = EBUSY;
iput(ip);
}
/*
* the umount system call.
*/
sumount()
{
dev_t dev;
register struct inode *ip;
register struct mount *mp;
register struct a {
char *fspec;
};
if(!suser())
return;
dev = getmdev();
if(u.u_error)
return;
xumount(dev); /* remove unused sticky files from text table */
update();
for(mp = &mount[0]; mp < (struct mount *)v.ve_mount; mp++)
if(mp->m_flags == MINUSE && dev == mp->m_dev)
goto found;
u.u_error = EINVAL;
return;
found:
for(ip = &inode[0]; ip < (struct inode *)v.ve_inode; ip++)
if(ip->i_number != 0 && dev == ip->i_dev) {
u.u_error = EBUSY;
return;
}
(*bdevsw[major(dev)].d_close)(minor(dev), 0);
binval(dev);
ip = mp->m_inodp;
ip->i_flag &= ~IMOUNT;
plock(ip);
iput(ip);
brelse(mp->m_bufp);
mp->m_bufp = NULL;
mp->m_flags = MFREE;
}
/*
* Common code for mount and umount.
* Check that the user's argument is a reasonable
* thing on which to mount, and return the device number if so.
*/
dev_t
getmdev()
{
dev_t dev;
register struct inode *ip;
#ifndef PNETDFS
ip = namei(uchar, 0);
#else
ip = namei(uchar, 0, NULL);
#endif
if(ip == NULL)
return(NODEV);
if((ip->i_mode&IFMT) != IFBLK)
u.u_error = ENOTBLK;
dev = (dev_t)ip->i_rdev;
if(major(dev) >= bdevcnt)
u.u_error = ENXIO;
iput(ip);
return(dev);
}

531
WEGA/src/uts/sys/sys4.c Normal file
View File

@ -0,0 +1,531 @@
#include "sys/param.h"
#include "sys/plexus.h"
#include "sys/systm.h"
#include "sys/dir.h"
#include "sys/user.h"
#include "sys/inode.h"
#include "sys/proc.h"
#include "sys/var.h"
#ifdef PNETDFS
extern int ddbug;
#endif
/*
* Everything in this file is a routine implementing a system call.
*/
gtime()
{
u.u_rtime = time;
}
stime()
{
register struct a {
time_t time;
} *uap;
uap = (struct a *)u.u_ap;
if (suser()) {
logtchg(uap->time);
time = uap->time;
puttod(time);
}
}
setuid()
{
register uid;
register struct a {
int uid;
} *uap;
uap = (struct a *)u.u_ap;
uid = uap->uid;
if (uid >= MAXUID) {
u.u_error = EINVAL;
return;
}
if (u.u_ruid == uid || suser()) {
u.u_uid = uid;
u.u_procp->p_uid = uid;
u.u_ruid = uid;
}
}
getuid()
{
u.u_rval1 = u.u_ruid;
u.u_rval2 = u.u_uid;
}
setgid()
{
register gid;
register struct a {
int gid;
} *uap;
uap = (struct a *)u.u_ap;
gid = uap->gid;
if (gid >= MAXUID) {
u.u_error = EINVAL;
return;
}
if (u.u_rgid == gid || suser()) {
u.u_gid = gid;
u.u_rgid = gid;
}
}
getgid()
{
u.u_rval1 = u.u_rgid;
u.u_rval2 = u.u_gid;
}
getpid()
{
u.u_rval1 = u.u_procp->p_pid;
u.u_rval2 = u.u_procp->p_ppid;
}
setpgrp()
{
register struct a {
int flag;
} *uap;
uap = (struct a *)u.u_ap;
if (uap->flag) {
u.u_procp->p_pgrp = u.u_procp->p_pid;
u.u_ttyp = NULL;
}
u.u_rval1 = u.u_procp->p_pgrp;
}
sync()
{
update();
}
nice()
{
register n;
register struct a {
int niceness;
} *uap;
uap = (struct a *)u.u_ap;
n = uap->niceness;
if ((n < 0 || n > 2*NZERO) && !suser())
n = 0;
n += u.u_procp->p_nice;
if (n >= 2*NZERO)
n = 2*NZERO -1;
if (n < 0)
n = 0;
u.u_procp->p_nice = n;
u.u_rval1 = n - NZERO;
}
/*
* Unlink system call.
* Hard to avoid races here, especially
* in unlinking directories.
*/
unlink()
{
register struct inode *ip, *pp;
struct a {
char *fname;
};
#ifndef PNETDFS
pp = namei(uchar, 2);
#else
pp = namei(uchar, 2, NULL);
#endif
if (pp == NULL)
return;
#ifdef PNETDFS
if ( pp->i_flag & IRMT ) {
if ( ddbug ) {
printf( "remote unlink, not there yet\n" );
debug();
}
goto out1;
}
#endif
/*
* Check for unlink(".")
* to avoid hanging on the iget
*/
if (pp->i_number == u.u_dent.d_ino) {
ip = pp;
ip->i_count++;
} else
ip = iget(pp->i_dev, u.u_dent.d_ino);
if (ip == NULL)
goto out1;
if ((ip->i_mode&IFMT) == IFDIR && !suser())
goto out;
/*
* Don't unlink a mounted file.
*/
if (ip->i_dev != pp->i_dev) {
u.u_error = EBUSY;
goto out;
}
if (ip->i_flag&ITEXT)
xrele(ip); /* try once to free text */
if (ip->i_flag&ITEXT && ip->i_nlink == 1) {
u.u_error = ETXTBSY;
goto out;
}
u.u_offset -= sizeof(struct direct);
u.u_base = (caddr_t)&u.u_dent;
u.u_count = sizeof(struct direct);
u.u_dent.d_ino = 0;
u.u_segflg = 1;
writei(pp);
if (u.u_error)
goto out;
ip->i_nlink--;
ip->i_flag |= ICHG;
out:
iput(ip);
out1:
iput(pp);
}
chdir()
{
chdirec(&u.u_cdir);
}
chroot()
{
if (!suser())
return;
chdirec(&u.u_rdir);
}
chdirec(ipp)
register struct inode **ipp;
{
register struct inode *ip;
struct a {
char *fname;
};
#ifndef PNETDFS
ip = namei(uchar, 0);
#else
ip = namei(uchar, 0, NULL);
#endif
if (ip == NULL)
return;
if ((ip->i_mode&IFMT) != IFDIR) {
u.u_error = ENOTDIR;
goto bad;
}
if (access(ip, IEXEC))
goto bad;
prele(ip);
if (*ipp) {
plock(*ipp);
iput(*ipp);
}
*ipp = ip;
return;
bad:
iput(ip);
}
chmod()
{
register struct inode *ip;
register struct a {
char *fname;
int fmode;
} *uap;
uap = (struct a *)u.u_ap;
if ((ip = owner()) == NULL)
return;
ip->i_mode &= ~07777;
if (u.u_uid) {
uap->fmode &= ~ISVTX;
if (u.u_gid != ip->i_gid)
uap->fmode &= ~ISGID;
}
#ifdef PNETDFS
if ( ip->i_flag & IRMT ) {
rchmod( ip, uap->fmode );
return;
}
#endif
ip->i_mode |= uap->fmode&07777;
ip->i_flag |= ICHG;
if (ip->i_flag&ITEXT && (ip->i_mode&ISVTX)==0)
xrele(ip);
iput(ip);
}
chown()
{
register struct inode *ip;
register struct a {
char *fname;
int uid;
int gid;
} *uap;
uap = (struct a *)u.u_ap;
if ((ip = owner()) == NULL)
return;
#ifdef PNETDFS
if ( ip->i_flag & IRMT ) {
rchown( ip, uap->uid, uap->gid );
return;
}
#endif
ip->i_uid = uap->uid;
ip->i_gid = uap->gid;
if (u.u_uid != 0)
ip->i_mode &= ~(ISUID|ISGID);
ip->i_flag |= ICHG;
iput(ip);
}
ssig()
{
register a;
register struct proc *p;
struct a {
int signo;
int fun;
} *uap;
uap = (struct a *)u.u_ap;
a = uap->signo;
if (a <= 0 || a > NSIG || a == SIGKILL) {
u.u_error = EINVAL;
return;
}
u.u_rval1 = u.u_signal[a-1];
u.u_signal[a-1] = uap->fun;
u.u_procp->p_sig &= ~(1L<<(a-1));
if (a == SIGCLD) {
a = u.u_procp->p_pid;
for (p = &proc[1]; p < (struct proc *)v.ve_proc; p++) {
if (a == p->p_ppid && p->p_stat == SZOMB)
psignal(u.u_procp, SIGCLD);
}
}
}
kill()
{
register struct proc *p, *q;
register arg;
register struct a {
int pid;
int signo;
} *uap;
int f;
uap = (struct a *)u.u_ap;
if (uap->signo < 0 || uap->signo > NSIG) {
u.u_error = EINVAL;
return;
}
f = 0;
arg = uap->pid;
if (arg > 0)
p = &proc[1];
else
p = &proc[2];
q = u.u_procp;
if (arg == 0 && q->p_pgrp == 0) {
u.u_error = ESRCH;
return;
}
for(; p < (struct proc *)v.ve_proc; p++) {
if (p->p_stat == NULL)
continue;
if (arg > 0 && p->p_pid != arg)
continue;
if (arg == 0 && p->p_pgrp != q->p_pgrp)
continue;
if (arg < -1 && p->p_pgrp != -arg)
continue;
if (u.u_uid != 0 && u.u_uid != p->p_uid && u.u_procp != p)
if (arg > 0) {
u.u_error = EPERM;
return;
} else
continue;
f++;
if (uap->signo)
psignal(p, uap->signo);
if (arg > 0)
break;
}
if (f == 0)
u.u_error = ESRCH;
}
times()
{
register struct a {
time_t (*times)[4];
} *uap;
uap = (struct a *)u.u_ap;
if (copyout((caddr_t)&u.u_utime, (caddr_t)uap->times, sizeof(*uap->times)))
u.u_error = EFAULT;
spl7();
u.u_rtime = lbolt;
spl0();
}
profil()
{
register struct a {
short *bufbase;
unsigned bufsize;
unsigned pcoffset;
unsigned pcscale;
} *uap;
uap = (struct a *)u.u_ap;
u.u_prof.pr_base = uap->bufbase;
u.u_prof.pr_size = uap->bufsize;
u.u_prof.pr_off = uap->pcoffset;
u.u_prof.pr_scale = uap->pcscale;
}
/*
* alarm clock signal
*/
alarm()
{
register struct proc *p;
register c;
register struct a {
int deltat;
} *uap;
uap = (struct a *)u.u_ap;
p = u.u_procp;
c = p->p_clktim;
p->p_clktim = uap->deltat;
u.u_rval1 = c;
}
/*
* indefinite wait.
* no one should wakeup(&u)
*/
pause()
{
for(;;)
sleep((caddr_t)&u, PSLEP);
}
/*
* mode mask for creation of files
*/
umask()
{
register struct a {
int mask;
} *uap;
register t;
uap = (struct a *)u.u_ap;
t = u.u_cmask;
u.u_cmask = uap->mask & 0777;
u.u_rval1 = t;
}
/*
* Set IUPD and IACC times on file.
*/
utime()
{
register struct a {
char *fname;
time_t *tptr;
} *uap;
register struct inode *ip;
time_t tv[2];
uap = (struct a *)u.u_ap;
if (uap->tptr != NULL) {
if (copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof(tv))) {
u.u_error = EFAULT;
return;
}
} else {
tv[0] = time;
tv[1] = time;
}
#ifndef
ip = namei(uchar, 0);
#else
ip = namei(uchar, 0, NULL);
#endif
if (ip == NULL)
return;
if (u.u_uid != ip->i_uid && u.u_uid != 0) {
if (uap->tptr != NULL)
u.u_error = EPERM;
else
access(ip, IWRITE);
}
if (!u.u_error) {
#ifdef PNETDFS
if ( ip->i_flag & IRMT ) {
rutime( ip, &tv[0], &tv[1] );
return;
}
#endif
ip->i_flag |= IACC|IUPD|ICHG;
iupdat(ip, &tv[0], &tv[1]);
}
iput(ip);
}
ulimit()
{
register struct a {
int cmd;
long arg;
} *uap;
register brk, stk;
uap = (struct a *)u.u_ap;
switch(uap->cmd) {
case 2:
if (uap->arg > u.u_limit && !suser())
return;
u.u_limit = uap->arg;
case 1:
u.u_roff = u.u_limit;
break;
case 3:
u.u_roff = ctob((long)(NUMLOGPAGE - u.u_ssize));
break;
}
}

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

@ -0,0 +1,107 @@
#include "sys/plexus.h"
#include "sys/param.h"
#include "sys/systm.h"
#include "sys/dir.h"
#include "sys/user.h"
#include "sys/proc.h"
#include "sys/text.h"
#include "sys/seg.h"
/*
* Load the user hardware segmentation
* registers from the software prototype.
* The software registers must have
* been setup prior by estabur.
*/
sureg()
{
int taddr, daddr;
register i, c;
struct text *tp;
int maptemp[NUMLOGPAGE];
taddr = daddr = u.u_procp->p_addr;
if ((tp=u.u_procp->p_textp) != NULL)
taddr = tp->x_caddr;
for (i = 0; i < NUMLOGPAGE; i++) {
c = u.u_uisa[i];
if ((c & B_IP) == 0)
if (c & B_EX)
c += taddr;
else
c += daddr;
maptemp[i] = c;
}
copymout(maptemp, P_MUI0, NUMLOGPAGE << 1);
for (i = 0; i < NUMLOGPAGE; i++) {
c = u.u_uisa[i + NUMLOGPAGE];
if ((c & B_IP) == 0)
if (c & B_EX)
c += taddr;
else
c += daddr;
maptemp[i] = c;
}
copymout(maptemp, P_MUD0, NUMLOGPAGE << 1);
}
/*
* Set up software prototype segmentation
* registers to implement the 3 pseudo
* text,data,stack segment sizes passed
* as arguments.
* The argument sep specifies if the
* text and data+stack segments are to
* be separated.
* The last argument determines whether the text
* segment is read-write or read-only.
*/
estabur(nt, nd, ns, sep, xrw)
unsigned nt, nd, ns;
{
register a, *ap, i;
if (checkur(nt, nd, ns, sep))
return(-1);
a = 0;
ap = &u.u_uisa[0];
for (i = 0; i < nt; i++)
*ap++ = a++ | B_EX | (xrw == RO ? B_RO : 0);
if (sep)
for (i = 0; i < (NUMLOGPAGE - nt); i++)
*ap++ = B_IP | B_RO;
a = USIZE;
for (i = 0; i < nd; i++)
*ap++ = a++;
for (i = 0; i < (NUMLOGPAGE - nd - ns - ((!sep) ? nt : 0)); i++)
*ap++ = B_IP | B_RO;
for (i = 0; i < ns; i++)
*ap++ = a++;
if (!sep) {
ap = &u.u_uisa[0];
for (i = 0; i < NUMLOGPAGE; i++)
ap[i + NUMLOGPAGE] = ap[i];
}
sureg();
return(0);
}
checkur(nt, nd, ns, sep)
{
if(sep) {
if(ctos(nt) > NUMLOGPAGE || ctos(nd)+ctos(ns) > NUMLOGPAGE)
goto err;
} else {
if(ctos(nt)+ctos(nd)+ctos(ns) > NUMLOGPAGE)
goto err;
}
if(nt+nd+ns+USIZE > maxmem)
goto err;
return(0);
err:
u.u_error = ENOMEM;
return(-1);
}