DataMuseum.dk

Presents historical artifacts from the history of:

Commodore CBM-900

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Commodore CBM-900

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦8e348cb0d⟧ TextFile

    Length: 7555 (0x1d83)
    Types: TextFile
    Notes: UNIX file
    Names: »sys1.c«

Derivation

└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
    └─⟦2d53db1df⟧ UNIX V7 Filesystem
        └─ ⟦this⟧ »sys/coh/sys1.c« 

TextFile

/* (-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);
	}
}