BBN-V6/ken/sys4.c
#
/*
*/
/*
* Everything in this file is a routine implementing a system call.
*/
#include "../h/param.h"
#include "../h/user.h"
#include "../h/reg.h"
#include "../h/inode.h"
#include "../h/systm.h"
#include "../h/proc.h"
#include "../h/file.h"
getswit()
{
u.u_ar0[R0] = SW->integ;
}
gtime()
{
u.u_ar0[R0] = time[0];
u.u_ar0[R1] = time[1];
}
/* return time in 60ths of a second ( BBN:mek 1/11/78 ) */
qtime()
{
gtime();
u.u_ar0[R2] = lbolt;
}
stime()
{
if(suser()) {
time[0] = u.u_ar0[R0];
time[1] = u.u_ar0[R1];
wakeup(tout);
}
}
setuid()
{
register uid;
uid = u.u_ar0[R0].lobyte;
if(u.u_ruid == uid.lobyte || suser()) {
u.u_uid = uid;
u.u_procp->p_uid = uid;
u.u_ruid = uid;
}
}
getuid()
{
u.u_ar0[R0].lobyte = u.u_ruid;
u.u_ar0[R0].hibyte = u.u_uid;
}
setgid()
{
register gid;
gid = u.u_ar0[R0].lobyte;
if(u.u_rgid == gid.lobyte || suser()) {
u.u_gid = gid;
u.u_rgid = gid;
}
}
getgid()
{
u.u_ar0[R0].lobyte = u.u_rgid;
u.u_ar0[R0].hibyte = u.u_gid;
}
getpid()
{
u.u_ar0[R0] = u.u_procp->p_pid;
}
sync()
{
update();
}
nice()
{
register n;
n = u.u_ar0[R0];
if(n > 20)
n = 20;
if(n < 0 && !suser())
n = 0;
u.u_procp->p_nice = n;
}
/*
* Unlink system call.
* panic: unlink -- "cannot happen"
*/
unlink()
{
register *ip, *pp;
extern uchar;
pp = namei(&uchar, 2);
if(pp == NULL)
return;
/* The following lines are a change suggested by Ken Thompson
* to eliminate a prele(pp) which kept "lockfiles" from working
*/
if(pp->i_number == u.u_dent.u_ino) {
ip = pp;
ip->i_count++;
} else
ip = iget(pp->i_dev, u.u_dent.u_ino);
if(ip == NULL)
goto out1;
if((ip->i_mode&IFMT)==IFDIR && !suser())
goto out;
u.u_offset[1] =- DIRSIZ+2;
u.u_base = &u.u_dent;
u.u_count = DIRSIZ+2;
u.u_dent.u_ino = 0;
writei(pp);
ip->i_nlink--;
ip->i_flag =| IACC; /* IUPD to IACC jsq BBN 3-12-79 */
out:
iput(ip);
out1:
iput(pp);
}
chdir()
{
register *ip;
extern uchar;
ip = namei(&uchar, 0);
if(ip == NULL)
return;
if((ip->i_mode&IFMT) != IFDIR) {
u.u_error = ENOTDIR;
bad:
iput(ip);
return;
}
if(access(ip, IEXEC))
goto bad;
prele(ip); /* BBN:cdh improved locking */
plock(u.u_cdir); /* BBN:cdh improved locking */
iput(u.u_cdir); /* BBN:cdh improved locking */
u.u_cdir = ip;
}
chmod()
{
register *ip;
if ((ip = owner()) == NULL)
return;
ip->i_mode =& ~07777;
if (u.u_uid)
u.u_arg[1] =& ~ISVTX;
ip->i_mode =| u.u_arg[1]&07777;
ip->i_flag =| IUPD;
iput(ip);
}
chown()
{
register *ip;
if (!suser() || (ip = owner()) == NULL)
return;
ip->i_uid = u.u_arg[1].lobyte;
ip->i_gid = u.u_arg[1].hibyte;
ip->i_flag =| IUPD;
iput(ip);
}
#ifdef SMDATE
/*
* Change modified date of file:
* time to r0-r1; sys smdate; file
* This call has been withdrawn because it messes up
* incremental dumps (pseudo-old files aren't dumped).
* It works though and you can uncomment it if you like.
*/
smdate()
{
register struct inode *ip;
register int *tp;
int tbuf[2];
if ((ip = owner()) == NULL)
return;
ip->i_flag =| IUPD;
tp = &tbuf[2];
*--tp = u.u_ar0[R1];
*--tp = u.u_ar0[R0];
iupdat(ip, tp);
ip->i_flag =& ~IUPD;
iput(ip);
}
#endif
ssig()
{
register a;
a = u.u_arg[0];
if(a<=0 || a>=NSIG || a==SIGKIL) {
u.u_error = EINVAL;
return;
}
u.u_ar0[R0] = u.u_signal[a];
u.u_signal[a] = u.u_arg[1];
if(u.u_procp->p_sig == a)
u.u_procp->p_sig = 0;
}
kill()
{
register struct proc *p, *q;
register a;
int f;
f = 0;
a = u.u_ar0[R0];
q = u.u_procp;
for(p = &proc[0]; p <= MAXPROC; p++) {
if(p == q || p->p_stat == 0) /* Rand: check for null proc */
continue;
if(a != 0 && p->p_pid != a)
continue;
if(a == 0 && (p->p_pgrp != q->p_pgrp || p <= &proc[1]))
continue;
if(u.u_uid != 0 && u.u_uid != p->p_uid)
continue;
f++;
psignal(p, u.u_arg[0]);
}
if(f == 0)
u.u_error = ESRCH;
}
times()
{
register *p;
suword(u.u_arg[0], u.u_utime[1]);
suword(u.u_arg[0]+2, u.u_stime[1]);
u.u_arg[0] =+ 4;
for(p = &u.u_cutime[0]; p <= &u.u_cstime[1];) {
suword(u.u_arg[0], *p++);
u.u_arg[0] =+ 2;
}
}
/* BBN: mek (4/30/79 )
PROFIL system call removed for small machines.
*/
#ifndef SMALL
profil()
{
u.u_prof[0] = u.u_arg[0] & ~1; /* base of sample buf */
u.u_prof[1] = u.u_arg[1]; /* size of same */
u.u_prof[2] = u.u_arg[2]; /* pc offset */
u.u_prof[3] = (u.u_arg[3]>>1) & 077777; /* pc scale */
}
#endif
/*
* alarm clock signal
*/
alarm()
{
register c, *p;
p = u.u_procp;
c = p->p_clktim;
p->p_clktim = u.u_ar0[R0];
u.u_ar0[R0] = c;
}
/*
* indefinite wait.
* no one should wakeup(&u)
*/
pause()
{
for(;;)
sleep(&u, PSLEP);
}
/*
* itime -- enable interval timer by giving address
* of pointer to location to be incremented every second
* A pointer is used to allow the user process to perform
* an atomic operation to switch the pointer to a new location,
* to preserve the current increment and reset to 0 without
* the chance of missing a count
* (BBN: JFH 5/78)
*/
itime()
{
register *p;
p = u.u_procp;
p->p_itima = u.u_ar0[R0];
}
/*
* This is for the cutloose system call
*/
cutloose() {
u.u_procp->p_pgrp = 0;
u.u_ttyp = 0;
u.u_ttyd = 0;
}