add plain C files from SYSIII
This commit is contained in:
parent
969b0473d0
commit
50bff6952f
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
Loading…
Reference in New Issue