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