|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 7555 (0x1d83)
Types: TextFile
Notes: UNIX file
Names: »sys1.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦2d53db1df⟧ UNIX Filesystem
└─⟦this⟧ »sys/coh/sys1.c«
/* (-lgl
* The information contained herein is a trade secret of Mark Williams
* Company, and is confidential information. It is provided under a
* license agreement, and may be copied or disclosed only under the
* terms of that agreement. Any reproduction or disclosure of this
* material without the express written authorization of Mark Williams
* Company or persuant to the license agreement is unlawful.
*
* COHERENT Version 0.7.3
* Copyright (c) 1982, 1983, 1984.
* An unpublished work by Mark Williams Company, Chicago.
* All rights reserved.
-lgl) */
/*
* Coherent.
* General system calls.
*/
#include <coherent.h>
#include <acct.h>
#include <con.h>
#include <errno.h>
#include <proc.h>
#include <sched.h>
#include <seg.h>
#include <signal.h>
#include <timeb.h>
#include <times.h>
#include <uproc.h>
/*
* Send a SIGALARM signal in `n' seconds.
*/
ualarm(n)
unsigned n;
{
register unsigned s;
s = SELF->p_alarm;
SELF->p_alarm = n;
return (s);
}
/*
* Change the size of our data segment.
* This version hacked to work on the Z8001 but
* is portable if the macroes are used properly.
*/
char *
ubrk(cp)
register char *cp;
{
register SEG *sp;
register paddr_t sb;
sp = SELF->p_segp[SIPDATA];
sb = vtop(u.u_segl[SIPDATA].sr_base);
if (cp != NULL)
segsize(sp, vtop(cp) - sb);
sb += ctob((paddr_t)sp->s_size);
return ((char *)ptov(sb));
}
/*
* Execute an l.out.
*/
uexece(np, argp, envp)
char *np;
char *argp[];
char *envp[];
{
pexece(np, argp, envp);
}
/*
* Exit.
*/
uexit(s)
{
pexit(s<<8);
}
/*
* Fork.
*/
ufork()
{
return (pfork());
}
/*
* Return date and time.
*/
uftime(tbp)
struct timeb *tbp;
{
register int s;
struct timeb timeb;
timeb.time = timer.t_time;
/* This should be a machine.h macro to avoid
* unnecessary long arithmetic and roundoff errors
*/
timeb.millitm = timer.t_tick*(1000/HZ);
timeb.timezone = timer.t_zone;
timeb.dstflag = timer.t_dstf;
s = sphi();
kucopy(&timeb, tbp, sizeof(timeb));
spl(s);
}
/*
* Get effective group id.
*/
ugetegid()
{
return (u.u_gid);
}
/*
* Get effective user id.
*/
ugeteuid()
{
return (u.u_uid);
}
/*
* Get group id.
*/
ugetgid()
{
return (u.u_rgid);
}
/*
* Get process id.
*/
ugetpid()
{
return (SELF->p_pid);
}
/*
* Get user id.
*/
ugetuid()
{
return (u.u_ruid);
}
/*
* Set the process group.
* When process group is 0 and a terminal is
* opened, this process is made the base of
* processes associated with that terminal.
*/
usetpgrp(group)
int group;
{
SELF->p_group = group;
}
/*
* Send the signal `sig' to the process with id `pid'.
*/
ukill(pid, sig)
register int pid;
register unsigned sig;
{
register PROC *pp;
register int sigflag;
if (sig==0 || sig>NSIG) {
u.u_error = EINVAL;
return;
}
sigflag = 0;
lock(pnxgate);
for (pp=procq.p_nforw; pp!=&procq; pp=pp->p_nforw) {
if (pp->p_state == PSDEAD)
continue;
switch (pid) {
case -1:
if (pp->p_pid == 0)
continue;
if (pp->p_pid == 1)
continue;
sigflag = 1;
if (super())
sendsig(sig, pp);
continue;
case 0:
if (pp->p_group == SELF->p_group) {
sigflag = 1;
if (sigperm(sig, pp))
sendsig(sig, pp);
}
continue;
default:
if (pp->p_pid == pid) {
sigflag = 1;
if (sigperm(sig, pp))
sendsig(sig, pp);
else
u.u_error = EPERM;
}
continue;
}
}
unlock(pnxgate);
if (sigflag == 0)
u.u_error = ESRCH;
return (0);
}
/*
* See if we have permission to send the signal, `sig' to the process, `pp'.
*/
sigperm(sig, pp)
register PROC *pp;
{
if (u.u_uid == pp->p_uid)
return (1);
if (u.u_ruid == pp->p_ruid) {
if (sig == SIGHUP
|| sig == SIGINT
|| sig == SIGQUIT
|| sig == SIGTERM)
return (1);
}
if (u.u_uid == 0) {
u.u_flag |= ASU;
return (1);
}
return (0);
}
/*
* Lock a process in core.
*/
ulock(f)
{
if (super() == 0)
return;
if (f)
SELF->p_flags |= PFLOCK;
else
SELF->p_flags &= ~PFLOCK;
return (0);
}
/*
* Change priority by the given increment.
*/
unice(n)
register int n;
{
n += SELF->p_nice;
if (n < MINNICE)
n = MINNICE;
if (n > MAXNICE)
n = MAXNICE;
if (n<SELF->p_nice && super()==0)
return;
SELF->p_nice = n;
return (0);
}
/*
* Non existant system call.
*/
unone()
{
u.u_error = EFAULT;
}
/*
* Null system call.
*/
unull()
{
}
/*
* Pause. Go to sleep on a channel that nobody will wakeup so that only
* signals will wake us up.
*/
upause()
{
for (;;)
sleep((char *)&u, CVPAUSE, IVPAUSE, SVPAUSE);
}
/*
* Start profiling. `bp' is the profile buffer, `n' is the size, `off'
* is the offset in the users programme and `scale' is the scaling
* factor.
*/
uprofil(bp, n, off, scale)
register char *bp;
{
u.u_pbase = bp;
u.u_pbend = bp + n;
u.u_pofft = off;
u.u_pscale = scale;
}
/*
* Process trace.
*/
uptrace(req, pid, add, data)
int *add;
{
if (req == 0) {
SELF->p_flags |= PFTRAC;
return (0);
}
return (ptset(req, pid, add, data));
}
/*
* Set group id.
*/
usetgid(gid)
register int gid;
{
if (u.u_gid!=gid && super()==0)
return;
u.u_gid = gid;
u.u_rgid = gid;
SELF->p_rgid = gid;
return (0);
}
/*
* Set user id.
*/
usetuid(uid)
register int uid;
{
if (uid!=u.u_ruid && super()==0)
return;
u.u_uid = uid;
u.u_ruid = uid;
SELF->p_uid = uid;
SELF->p_ruid = uid;
return (0);
}
/*
* Set up the action to be taken on a signal.
*/
int *
usignal(sig, f)
register int sig;
int (*f)();
{
register PROC *pp;
register sig_t s;
register int (*o)();
pp = SELF;
if (sig<=0 || sig>NSIG || sig==SIGKILL) {
u.u_error = EINVAL;
return;
}
s = (sig_t)1 << --sig;
o = u.u_sfunc[sig];
/* This order is critical to isig's use */
if (f == SIG_IGN) {
pp->p_isig |= s;
u.u_sfunc[sig] = f;
} else {
u.u_sfunc[sig] = f;
pp->p_isig &= ~s;
}
pp->p_ssig &= ~s;
return (o);
}
/*
* Load a device driver.
*/
usload(m, np, cp)
char *np;
CON *cp;
{
if (super() == 0)
return;
pload(m, np, cp);
return (0);
}
/*
* Set time and date.
*/
ustime(tp)
register time_t *tp;
{
register int s;
if (super() == 0)
return;
s = sphi();
ukcopy(tp, &timer.t_time, sizeof(*tp));
spl(s);
return (0);
}
/*
* Return process times.
*/
utimes(tp)
struct tbuffer *tp;
{
register PROC *pp;
struct tbuffer tbuffer;
pp = SELF;
tbuffer.tb_utime = pp->p_utime;
tbuffer.tb_stime = pp->p_stime;
tbuffer.tb_cutime = pp->p_cutime;
tbuffer.tb_cstime = pp->p_cstime;
kucopy(&tbuffer, tp, sizeof(tbuffer));
return (0);
}
/*
* Unload a device driver.
*/
usuload(m)
register int m;
{
if (super() == 0)
return;
puload(m);
return (0);
}
/*
* Wait for a child to terminate.
*/
uwait(stp)
int *stp;
{
register PROC *pp;
register PROC *ppp;
register PROC *cpp;
register int pid;
ppp = SELF;
for (;;) {
lock(pnxgate);
cpp = NULL;
pp = &procq;
while ((pp=pp->p_nforw) != &procq) {
if (pp == ppp)
continue;
if (pp->p_ppid != ppp->p_pid)
continue;
if ((pp->p_flags&PFSTOP) != 0)
continue;
if ((pp->p_flags&PFWAIT) != 0) {
pp->p_flags &= ~PFWAIT;
pp->p_flags |= PFSTOP;
unlock(pnxgate);
if (stp != NULL)
putuwd(stp, 0177);
return (pp->p_pid);
}
if (pp->p_state == PSDEAD) {
ppp->p_cutime += pp->p_utime + pp->p_cutime;
ppp->p_cstime += pp->p_stime + pp->p_cstime;
if (stp != NULL)
putuwd(stp, pp->p_exit);
pid = pp->p_pid;
unlock(pnxgate);
relproc(pp);
return (pid);
}
cpp = pp;
}
unlock(pnxgate);
if (cpp == NULL) {
u.u_error = ECHILD;
return;
}
sleep((char *)ppp, CVWAIT, IVWAIT, SVWAIT);
}
}