Giant Pushdown
clock_gettime() clock_settime() nanosleep() settimeofday() adjtime() getitimer() setitimer() __sysctl() ogetkerninfo() sigaction() osigaction() sigpending() osigpending() osigvec() osigblock() osigsetmask() sigsuspend() osigsuspend() osigstack() sigaltstack() kill() okillpg() trapsignal() nosys()
This commit is contained in:
parent
c45dc66693
commit
5cd818cd1a
@ -345,6 +345,9 @@ struct sigaction_args {
|
||||
struct sigaction *oact;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
sigaction(p, uap)
|
||||
@ -355,17 +358,21 @@ sigaction(p, uap)
|
||||
register struct sigaction *actp, *oactp;
|
||||
int error;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
|
||||
actp = (uap->act != NULL) ? &act : NULL;
|
||||
oactp = (uap->oact != NULL) ? &oact : NULL;
|
||||
if (actp) {
|
||||
error = copyin(uap->act, actp, sizeof(act));
|
||||
if (error)
|
||||
return (error);
|
||||
goto done2;
|
||||
}
|
||||
error = do_sigaction(p, uap->sig, actp, oactp, 0);
|
||||
if (oactp && !error) {
|
||||
error = copyout(oactp, uap->oact, sizeof(oact));
|
||||
}
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -377,6 +384,9 @@ struct osigaction_args {
|
||||
struct osigaction *osa;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
osigaction(p, uap)
|
||||
@ -390,12 +400,16 @@ osigaction(p, uap)
|
||||
|
||||
if (uap->signum <= 0 || uap->signum >= ONSIG)
|
||||
return (EINVAL);
|
||||
|
||||
nsap = (uap->nsa != NULL) ? &nsa : NULL;
|
||||
osap = (uap->osa != NULL) ? &osa : NULL;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if (nsap) {
|
||||
error = copyin(uap->nsa, &sa, sizeof(sa));
|
||||
if (error)
|
||||
return (error);
|
||||
goto done2;
|
||||
nsap->sa_handler = sa.sa_handler;
|
||||
nsap->sa_flags = sa.sa_flags;
|
||||
OSIG2SIG(sa.sa_mask, nsap->sa_mask);
|
||||
@ -407,6 +421,8 @@ osigaction(p, uap)
|
||||
SIG2OSIG(osap->sa_mask, sa.sa_mask);
|
||||
error = copyout(&sa, uap->osa, sizeof(sa));
|
||||
}
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
#endif /* COMPAT_43 */
|
||||
@ -580,6 +596,9 @@ struct sigpending_args {
|
||||
sigset_t *set;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
sigpending(p, uap)
|
||||
@ -587,11 +606,15 @@ sigpending(p, uap)
|
||||
struct sigpending_args *uap;
|
||||
{
|
||||
sigset_t siglist;
|
||||
int error;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
PROC_LOCK(p);
|
||||
siglist = p->p_siglist;
|
||||
PROC_UNLOCK(p);
|
||||
return (copyout(&siglist, uap->set, sizeof(sigset_t)));
|
||||
mtx_unlock(&Giant);
|
||||
error = copyout(&siglist, uap->set, sizeof(sigset_t));
|
||||
return(error);
|
||||
}
|
||||
|
||||
#ifdef COMPAT_43 /* XXX - COMPAT_FBSD3 */
|
||||
@ -600,16 +623,20 @@ struct osigpending_args {
|
||||
int dummy;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
osigpending(p, uap)
|
||||
struct proc *p;
|
||||
struct osigpending_args *uap;
|
||||
{
|
||||
|
||||
mtx_lock(&Giant);
|
||||
PROC_LOCK(p);
|
||||
SIG2OSIG(p->p_siglist, p->p_retval[0]);
|
||||
PROC_UNLOCK(p);
|
||||
mtx_unlock(&Giant);
|
||||
return (0);
|
||||
}
|
||||
#endif /* COMPAT_43 */
|
||||
@ -625,6 +652,9 @@ struct osigvec_args {
|
||||
struct sigvec *osv;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
osigvec(p, uap)
|
||||
@ -652,7 +682,9 @@ osigvec(p, uap)
|
||||
nsap->sa_flags |= SA_USERTRAMP;
|
||||
#endif
|
||||
}
|
||||
mtx_lock(&Giant);
|
||||
error = do_sigaction(p, uap->signum, nsap, osap, 1);
|
||||
mtx_unlock(&Giant);
|
||||
if (osap && !error) {
|
||||
vec.sv_handler = osap->sa_handler;
|
||||
SIG2OSIG(osap->sa_mask, vec.sv_mask);
|
||||
@ -672,6 +704,9 @@ struct osigblock_args {
|
||||
int mask;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
osigblock(p, uap)
|
||||
register struct proc *p;
|
||||
@ -681,10 +716,12 @@ osigblock(p, uap)
|
||||
|
||||
OSIG2SIG(uap->mask, set);
|
||||
SIG_CANTMASK(set);
|
||||
mtx_lock(&Giant);
|
||||
PROC_LOCK(p);
|
||||
SIG2OSIG(p->p_sigmask, p->p_retval[0]);
|
||||
SIGSETOR(p->p_sigmask, set);
|
||||
PROC_UNLOCK(p);
|
||||
mtx_unlock(&Giant);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -693,6 +730,9 @@ struct osigsetmask_args {
|
||||
int mask;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
osigsetmask(p, uap)
|
||||
struct proc *p;
|
||||
@ -702,10 +742,12 @@ osigsetmask(p, uap)
|
||||
|
||||
OSIG2SIG(uap->mask, set);
|
||||
SIG_CANTMASK(set);
|
||||
mtx_lock(&Giant);
|
||||
PROC_LOCK(p);
|
||||
SIG2OSIG(p->p_sigmask, p->p_retval[0]);
|
||||
SIGSETLO(p->p_sigmask, set);
|
||||
PROC_UNLOCK(p);
|
||||
mtx_unlock(&Giant);
|
||||
return (0);
|
||||
}
|
||||
#endif /* COMPAT_43 || COMPAT_SUNOS */
|
||||
@ -720,6 +762,9 @@ struct sigsuspend_args {
|
||||
const sigset_t *sigmask;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
sigsuspend(p, uap)
|
||||
@ -741,6 +786,7 @@ sigsuspend(p, uap)
|
||||
* save it here and mark the sigacts structure
|
||||
* to indicate this.
|
||||
*/
|
||||
mtx_lock(&Giant);
|
||||
PROC_LOCK(p);
|
||||
ps = p->p_sigacts;
|
||||
p->p_oldsigmask = p->p_sigmask;
|
||||
@ -751,6 +797,7 @@ sigsuspend(p, uap)
|
||||
while (msleep((caddr_t) ps, &p->p_mtx, PPAUSE|PCATCH, "pause", 0) == 0)
|
||||
/* void */;
|
||||
PROC_UNLOCK(p);
|
||||
mtx_unlock(&Giant);
|
||||
/* always return EINTR rather than ERESTART... */
|
||||
return (EINTR);
|
||||
}
|
||||
@ -761,6 +808,9 @@ struct osigsuspend_args {
|
||||
osigset_t mask;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
osigsuspend(p, uap)
|
||||
@ -770,6 +820,7 @@ osigsuspend(p, uap)
|
||||
sigset_t mask;
|
||||
register struct sigacts *ps;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
PROC_LOCK(p);
|
||||
ps = p->p_sigacts;
|
||||
p->p_oldsigmask = p->p_sigmask;
|
||||
@ -780,6 +831,7 @@ osigsuspend(p, uap)
|
||||
while (msleep((caddr_t) ps, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0)
|
||||
/* void */;
|
||||
PROC_UNLOCK(p);
|
||||
mtx_unlock(&Giant);
|
||||
/* always return EINTR rather than ERESTART... */
|
||||
return (EINTR);
|
||||
}
|
||||
@ -792,6 +844,9 @@ struct osigstack_args {
|
||||
struct sigstack *oss;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
osigstack(p, uap)
|
||||
@ -799,7 +854,9 @@ osigstack(p, uap)
|
||||
register struct osigstack_args *uap;
|
||||
{
|
||||
struct sigstack ss;
|
||||
int error;
|
||||
int error = 0;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if (uap->oss != NULL) {
|
||||
PROC_LOCK(p);
|
||||
@ -808,12 +865,12 @@ osigstack(p, uap)
|
||||
PROC_UNLOCK(p);
|
||||
error = copyout(&ss, uap->oss, sizeof(struct sigstack));
|
||||
if (error)
|
||||
return (error);
|
||||
goto done2;
|
||||
}
|
||||
|
||||
if (uap->nss != NULL) {
|
||||
if ((error = copyin(uap->nss, &ss, sizeof(ss))) != 0)
|
||||
return (error);
|
||||
goto done2;
|
||||
PROC_LOCK(p);
|
||||
p->p_sigstk.ss_sp = ss.ss_sp;
|
||||
p->p_sigstk.ss_size = 0;
|
||||
@ -821,7 +878,9 @@ osigstack(p, uap)
|
||||
p->p_flag |= P_ALTSTACK;
|
||||
PROC_UNLOCK(p);
|
||||
}
|
||||
return (0);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
#endif /* COMPAT_43 || COMPAT_SUNOS */
|
||||
|
||||
@ -831,6 +890,9 @@ struct sigaltstack_args {
|
||||
stack_t *oss;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
sigaltstack(p, uap)
|
||||
@ -838,7 +900,10 @@ sigaltstack(p, uap)
|
||||
register struct sigaltstack_args *uap;
|
||||
{
|
||||
stack_t ss;
|
||||
int error, oonstack;
|
||||
int oonstack;
|
||||
int error = 0;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
|
||||
oonstack = sigonstack(cpu_getstack(p));
|
||||
|
||||
@ -849,19 +914,25 @@ sigaltstack(p, uap)
|
||||
? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
|
||||
PROC_UNLOCK(p);
|
||||
if ((error = copyout(&ss, uap->oss, sizeof(stack_t))) != 0)
|
||||
return (error);
|
||||
goto done2;
|
||||
}
|
||||
|
||||
if (uap->ss != NULL) {
|
||||
if (oonstack)
|
||||
return (EPERM);
|
||||
if (oonstack) {
|
||||
error = EPERM;
|
||||
goto done2;
|
||||
}
|
||||
if ((error = copyin(uap->ss, &ss, sizeof(ss))) != 0)
|
||||
return (error);
|
||||
if ((ss.ss_flags & ~SS_DISABLE) != 0)
|
||||
return (EINVAL);
|
||||
goto done2;
|
||||
if ((ss.ss_flags & ~SS_DISABLE) != 0) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
if (!(ss.ss_flags & SS_DISABLE)) {
|
||||
if (ss.ss_size < p->p_sysent->sv_minsigstksz)
|
||||
return (ENOMEM);
|
||||
if (ss.ss_size < p->p_sysent->sv_minsigstksz) {
|
||||
error = ENOMEM;
|
||||
goto done2;
|
||||
}
|
||||
PROC_LOCK(p);
|
||||
p->p_sigstk = ss;
|
||||
p->p_flag |= P_ALTSTACK;
|
||||
@ -872,7 +943,9 @@ sigaltstack(p, uap)
|
||||
PROC_UNLOCK(p);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -948,6 +1021,9 @@ struct kill_args {
|
||||
int signum;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
kill(cp, uap)
|
||||
@ -955,31 +1031,40 @@ kill(cp, uap)
|
||||
register struct kill_args *uap;
|
||||
{
|
||||
register struct proc *p;
|
||||
int error = 0;
|
||||
|
||||
if ((u_int)uap->signum > _SIG_MAXSIG)
|
||||
return (EINVAL);
|
||||
|
||||
mtx_lock(&Giant);
|
||||
if (uap->pid > 0) {
|
||||
/* kill single process */
|
||||
if ((p = pfind(uap->pid)) == NULL)
|
||||
return (ESRCH);
|
||||
if (p_cansignal(cp, p, uap->signum)) {
|
||||
if ((p = pfind(uap->pid)) == NULL) {
|
||||
error = ESRCH;
|
||||
} else if (p_cansignal(cp, p, uap->signum)) {
|
||||
PROC_UNLOCK(p);
|
||||
return (EPERM);
|
||||
error = EPERM;
|
||||
} else {
|
||||
if (uap->signum)
|
||||
psignal(p, uap->signum);
|
||||
PROC_UNLOCK(p);
|
||||
error = 0;
|
||||
}
|
||||
} else {
|
||||
switch (uap->pid) {
|
||||
case -1: /* broadcast signal */
|
||||
error = killpg1(cp, uap->signum, 0, 1);
|
||||
break;
|
||||
case 0: /* signal own process group */
|
||||
error = killpg1(cp, uap->signum, 0, 0);
|
||||
break;
|
||||
default: /* negative explicit process group */
|
||||
error = killpg1(cp, uap->signum, -uap->pid, 0);
|
||||
break;
|
||||
}
|
||||
if (uap->signum)
|
||||
psignal(p, uap->signum);
|
||||
PROC_UNLOCK(p);
|
||||
return (0);
|
||||
}
|
||||
switch (uap->pid) {
|
||||
case -1: /* broadcast signal */
|
||||
return (killpg1(cp, uap->signum, 0, 1));
|
||||
case 0: /* signal own process group */
|
||||
return (killpg1(cp, uap->signum, 0, 0));
|
||||
default: /* negative explicit process group */
|
||||
return (killpg1(cp, uap->signum, -uap->pid, 0));
|
||||
}
|
||||
/* NOTREACHED */
|
||||
mtx_unlock(&Giant);
|
||||
return(error);
|
||||
}
|
||||
|
||||
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
|
||||
@ -989,16 +1074,23 @@ struct okillpg_args {
|
||||
int signum;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
okillpg(p, uap)
|
||||
struct proc *p;
|
||||
register struct okillpg_args *uap;
|
||||
{
|
||||
int error;
|
||||
|
||||
if ((u_int)uap->signum > _SIG_MAXSIG)
|
||||
return (EINVAL);
|
||||
return (killpg1(p, uap->signum, uap->pgid, 0));
|
||||
mtx_lock(&Giant);
|
||||
error = killpg1(p, uap->signum, uap->pgid, 0);
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
#endif /* COMPAT_43 || COMPAT_SUNOS */
|
||||
|
||||
@ -1852,16 +1944,20 @@ struct nosys_args {
|
||||
int dummy;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
nosys(p, args)
|
||||
struct proc *p;
|
||||
struct nosys_args *args;
|
||||
{
|
||||
|
||||
mtx_lock(&Giant);
|
||||
PROC_LOCK(p);
|
||||
psignal(p, SIGSYS);
|
||||
PROC_UNLOCK(p);
|
||||
mtx_unlock(&Giant);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,8 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/sysproto.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_extern.h>
|
||||
@ -1060,10 +1062,13 @@ struct sysctl_args {
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
__sysctl(struct proc *p, struct sysctl_args *uap)
|
||||
{
|
||||
int error, i, name[CTL_MAXNAME];
|
||||
int error, name[CTL_MAXNAME];
|
||||
size_t j;
|
||||
|
||||
if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
|
||||
@ -1073,16 +1078,20 @@ __sysctl(struct proc *p, struct sysctl_args *uap)
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
mtx_lock(&Giant);
|
||||
|
||||
error = userland_sysctl(p, name, uap->namelen,
|
||||
uap->old, uap->oldlenp, 0,
|
||||
uap->new, uap->newlen, &j);
|
||||
if (error && error != ENOMEM)
|
||||
return (error);
|
||||
goto done2;
|
||||
if (uap->oldlenp) {
|
||||
i = copyout(&j, uap->oldlenp, sizeof(j));
|
||||
int i = copyout(&j, uap->oldlenp, sizeof(j));
|
||||
if (i)
|
||||
return (i);
|
||||
error = i;
|
||||
}
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1232,6 +1241,9 @@ struct getkerninfo_args {
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
ogetkerninfo(struct proc *p, struct getkerninfo_args *uap)
|
||||
{
|
||||
@ -1239,6 +1251,8 @@ ogetkerninfo(struct proc *p, struct getkerninfo_args *uap)
|
||||
size_t size;
|
||||
u_int needed = 0;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
|
||||
switch (uap->op & 0xff00) {
|
||||
|
||||
case KINFO_RT:
|
||||
@ -1362,14 +1376,17 @@ ogetkerninfo(struct proc *p, struct getkerninfo_args *uap)
|
||||
}
|
||||
|
||||
default:
|
||||
return (EOPNOTSUPP);
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
if (error)
|
||||
return (error);
|
||||
p->p_retval[0] = needed ? needed : size;
|
||||
if (uap->size)
|
||||
error = copyout((caddr_t)&size, (caddr_t)uap->size,
|
||||
sizeof(size));
|
||||
if (error == 0) {
|
||||
p->p_retval[0] = needed ? needed : size;
|
||||
if (uap->size) {
|
||||
error = copyout((caddr_t)&size, (caddr_t)uap->size,
|
||||
sizeof(size));
|
||||
}
|
||||
}
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
#endif /* COMPAT_43 */
|
||||
|
@ -146,6 +146,9 @@ struct clock_gettime_args {
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
clock_gettime(p, uap)
|
||||
@ -156,7 +159,9 @@ clock_gettime(p, uap)
|
||||
|
||||
if (SCARG(uap, clock_id) != CLOCK_REALTIME)
|
||||
return (EINVAL);
|
||||
mtx_lock(&Giant);
|
||||
nanotime(&ats);
|
||||
mtx_unlock(&Giant);
|
||||
return (copyout(&ats, SCARG(uap, tp), sizeof(ats)));
|
||||
}
|
||||
|
||||
@ -167,6 +172,9 @@ struct clock_settime_args {
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
clock_settime(p, uap)
|
||||
@ -177,19 +185,25 @@ clock_settime(p, uap)
|
||||
struct timespec ats;
|
||||
int error;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
if ((error = suser(p)) != 0)
|
||||
return (error);
|
||||
if (SCARG(uap, clock_id) != CLOCK_REALTIME)
|
||||
return (EINVAL);
|
||||
goto done2;
|
||||
if (SCARG(uap, clock_id) != CLOCK_REALTIME) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
if ((error = copyin(SCARG(uap, tp), &ats, sizeof(ats))) != 0)
|
||||
return (error);
|
||||
if (ats.tv_nsec < 0 || ats.tv_nsec >= 1000000000)
|
||||
return (EINVAL);
|
||||
goto done2;
|
||||
if (ats.tv_nsec < 0 || ats.tv_nsec >= 1000000000) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
/* XXX Don't convert nsec->usec and back */
|
||||
TIMESPEC_TO_TIMEVAL(&atv, &ats);
|
||||
if ((error = settime(&atv)))
|
||||
return (error);
|
||||
return (0);
|
||||
error = settime(&atv);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
@ -266,6 +280,9 @@ struct nanosleep_args {
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
nanosleep(p, uap)
|
||||
@ -273,21 +290,30 @@ nanosleep(p, uap)
|
||||
struct nanosleep_args *uap;
|
||||
{
|
||||
struct timespec rmt, rqt;
|
||||
int error, error2;
|
||||
int error;
|
||||
|
||||
error = copyin(SCARG(uap, rqtp), &rqt, sizeof(rqt));
|
||||
if (error)
|
||||
return (error);
|
||||
if (SCARG(uap, rmtp))
|
||||
|
||||
mtx_lock(&Giant);
|
||||
if (SCARG(uap, rmtp)) {
|
||||
if (!useracc((caddr_t)SCARG(uap, rmtp), sizeof(rmt),
|
||||
VM_PROT_WRITE))
|
||||
return (EFAULT);
|
||||
VM_PROT_WRITE)) {
|
||||
error = EFAULT;
|
||||
goto done2;
|
||||
}
|
||||
}
|
||||
error = nanosleep1(p, &rqt, &rmt);
|
||||
if (error && SCARG(uap, rmtp)) {
|
||||
int error2;
|
||||
|
||||
error2 = copyout(&rmt, SCARG(uap, rmtp), sizeof(rmt));
|
||||
if (error2) /* XXX shouldn't happen, did useracc() above */
|
||||
return (error2);
|
||||
error = error2;
|
||||
}
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -297,6 +323,9 @@ struct gettimeofday_args {
|
||||
struct timezone *tzp;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
gettimeofday(p, uap)
|
||||
@ -306,15 +335,20 @@ gettimeofday(p, uap)
|
||||
struct timeval atv;
|
||||
int error = 0;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
if (uap->tp) {
|
||||
microtime(&atv);
|
||||
if ((error = copyout((caddr_t)&atv, (caddr_t)uap->tp,
|
||||
sizeof (atv))))
|
||||
return (error);
|
||||
sizeof (atv)))) {
|
||||
goto done2;
|
||||
}
|
||||
}
|
||||
if (uap->tzp)
|
||||
if (uap->tzp) {
|
||||
error = copyout((caddr_t)&tz, (caddr_t)uap->tzp,
|
||||
sizeof (tz));
|
||||
}
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -324,6 +358,9 @@ struct settimeofday_args {
|
||||
struct timezone *tzp;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
settimeofday(p, uap)
|
||||
@ -332,26 +369,34 @@ settimeofday(p, uap)
|
||||
{
|
||||
struct timeval atv;
|
||||
struct timezone atz;
|
||||
int error;
|
||||
int error = 0;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if ((error = suser(p)))
|
||||
return (error);
|
||||
goto done2;
|
||||
/* Verify all parameters before changing time. */
|
||||
if (uap->tv) {
|
||||
if ((error = copyin((caddr_t)uap->tv, (caddr_t)&atv,
|
||||
sizeof(atv))))
|
||||
return (error);
|
||||
if (atv.tv_usec < 0 || atv.tv_usec >= 1000000)
|
||||
return (EINVAL);
|
||||
sizeof(atv)))) {
|
||||
goto done2;
|
||||
}
|
||||
if (atv.tv_usec < 0 || atv.tv_usec >= 1000000) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
}
|
||||
if (uap->tzp &&
|
||||
(error = copyin((caddr_t)uap->tzp, (caddr_t)&atz, sizeof(atz))))
|
||||
return (error);
|
||||
(error = copyin((caddr_t)uap->tzp, (caddr_t)&atz, sizeof(atz)))) {
|
||||
goto done2;
|
||||
}
|
||||
if (uap->tv && (error = settime(&atv)))
|
||||
return (error);
|
||||
goto done2;
|
||||
if (uap->tzp)
|
||||
tz = atz;
|
||||
return (0);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int tickdelta; /* current clock skew, us. per tick */
|
||||
@ -364,6 +409,9 @@ struct adjtime_args {
|
||||
struct timeval *olddelta;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
adjtime(p, uap)
|
||||
@ -374,11 +422,14 @@ adjtime(p, uap)
|
||||
register long ndelta, ntickdelta, odelta;
|
||||
int s, error;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if ((error = suser(p)))
|
||||
return (error);
|
||||
if ((error =
|
||||
copyin((caddr_t)uap->delta, (caddr_t)&atv, sizeof(struct timeval))))
|
||||
return (error);
|
||||
goto done2;
|
||||
error = copyin((caddr_t)uap->delta, (caddr_t)&atv,
|
||||
sizeof(struct timeval));
|
||||
if (error)
|
||||
goto done2;
|
||||
|
||||
/*
|
||||
* Compute the total correction and the rate at which to apply it.
|
||||
@ -414,7 +465,9 @@ adjtime(p, uap)
|
||||
(void) copyout((caddr_t)&atv, (caddr_t)uap->olddelta,
|
||||
sizeof(struct timeval));
|
||||
}
|
||||
return (0);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -444,6 +497,9 @@ struct getitimer_args {
|
||||
struct itimerval *itv;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
getitimer(p, uap)
|
||||
@ -453,9 +509,13 @@ getitimer(p, uap)
|
||||
struct timeval ctv;
|
||||
struct itimerval aitv;
|
||||
int s;
|
||||
int error;
|
||||
|
||||
if (uap->which > ITIMER_PROF)
|
||||
return (EINVAL);
|
||||
|
||||
mtx_lock(&Giant);
|
||||
|
||||
s = splclock(); /* XXX still needed ? */
|
||||
if (uap->which == ITIMER_REAL) {
|
||||
/*
|
||||
@ -472,11 +532,14 @@ getitimer(p, uap)
|
||||
else
|
||||
timevalsub(&aitv.it_value, &ctv);
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
aitv = p->p_stats->p_timer[uap->which];
|
||||
}
|
||||
splx(s);
|
||||
return (copyout((caddr_t)&aitv, (caddr_t)uap->itv,
|
||||
sizeof (struct itimerval)));
|
||||
error = copyout((caddr_t)&aitv, (caddr_t)uap->itv,
|
||||
sizeof (struct itimerval));
|
||||
mtx_unlock(&Giant);
|
||||
return(error);
|
||||
}
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
@ -485,6 +548,9 @@ struct setitimer_args {
|
||||
struct itimerval *itv, *oitv;
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
setitimer(p, uap)
|
||||
@ -494,7 +560,7 @@ setitimer(p, uap)
|
||||
struct itimerval aitv;
|
||||
struct timeval ctv;
|
||||
register struct itimerval *itvp;
|
||||
int s, error;
|
||||
int s, error = 0;
|
||||
|
||||
if (uap->which > ITIMER_PROF)
|
||||
return (EINVAL);
|
||||
@ -502,17 +568,27 @@ setitimer(p, uap)
|
||||
if (itvp && (error = copyin((caddr_t)itvp, (caddr_t)&aitv,
|
||||
sizeof(struct itimerval))))
|
||||
return (error);
|
||||
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if ((uap->itv = uap->oitv) &&
|
||||
(error = getitimer(p, (struct getitimer_args *)uap)))
|
||||
return (error);
|
||||
if (itvp == 0)
|
||||
return (0);
|
||||
if (itimerfix(&aitv.it_value))
|
||||
return (EINVAL);
|
||||
if (!timevalisset(&aitv.it_value))
|
||||
(error = getitimer(p, (struct getitimer_args *)uap))) {
|
||||
goto done2;
|
||||
}
|
||||
if (itvp == 0) {
|
||||
error = 0;
|
||||
goto done2;
|
||||
}
|
||||
if (itimerfix(&aitv.it_value)) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
if (!timevalisset(&aitv.it_value)) {
|
||||
timevalclear(&aitv.it_interval);
|
||||
else if (itimerfix(&aitv.it_interval))
|
||||
return (EINVAL);
|
||||
} else if (itimerfix(&aitv.it_interval)) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
s = splclock(); /* XXX: still needed ? */
|
||||
if (uap->which == ITIMER_REAL) {
|
||||
if (timevalisset(&p->p_realtimer.it_value))
|
||||
@ -523,10 +599,13 @@ setitimer(p, uap)
|
||||
getmicrouptime(&ctv);
|
||||
timevaladd(&aitv.it_value, &ctv);
|
||||
p->p_realtimer = aitv;
|
||||
} else
|
||||
} else {
|
||||
p->p_stats->p_timer[uap->which] = aitv;
|
||||
}
|
||||
splx(s);
|
||||
return (0);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user