Make rtprio work again.

- add a missing break which caused RTP_SET to always return EINVAL
- break instead of returning if p_can fails so proc_lock is always
  dropped correctly
- only copyin data that is actually needed
- use break instead of goto
- make rtp_to_pri return EINVAL instead of -1 if the values are out
  or range so we don't have to translate
This commit is contained in:
Jake Burkholder 2001-04-29 22:09:26 +00:00
parent 703471ec7f
commit e6af1080c2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=76141

View File

@ -252,35 +252,32 @@ rtprio(curp, uap)
struct rtprio rtp; struct rtprio rtp;
int error; int error;
error = copyin(uap->rtp, &rtp, sizeof(struct rtprio));
if (error)
return (error);
if (uap->pid == 0) { if (uap->pid == 0) {
p = curp; p = curp;
PROC_LOCK(p); PROC_LOCK(p);
} else } else
p = pfind(uap->pid); p = pfind(uap->pid);
if (p == 0) if (p == NULL)
return (ESRCH); return (ESRCH);
switch (uap->function) { switch (uap->function) {
case RTP_LOOKUP: case RTP_LOOKUP:
if ((error = p_can(curp, p, P_CAN_SEE, NULL))) if ((error = p_can(curp, p, P_CAN_SEE, NULL)))
return (error); break;
pri_to_rtp(&p->p_pri, &rtp); pri_to_rtp(&p->p_pri, &rtp);
PROC_UNLOCK(p); error = copyout(&rtp, uap->rtp, sizeof(struct rtprio));
return (copyout(&rtp, uap->rtp, sizeof(struct rtprio))); break;
case RTP_SET: case RTP_SET:
if ((error = p_can(curp, p, P_CAN_SCHED, NULL))) if ((error = p_can(curp, p, P_CAN_SCHED, NULL)) ||
goto out; (error = copyin(uap->rtp, &rtp, sizeof(struct rtprio))))
break;
/* disallow setting rtprio in most cases if not superuser */ /* disallow setting rtprio in most cases if not superuser */
if (suser(curp) != 0) { if (suser(curp) != 0) {
/* can't set someone else's */ /* can't set someone else's */
if (uap->pid) { if (uap->pid) {
error = EPERM; error = EPERM;
goto out; break;
} }
/* can't set realtime priority */ /* can't set realtime priority */
/* /*
@ -295,17 +292,15 @@ rtprio(curp, uap)
#endif #endif
if (rtp.type != RTP_PRIO_NORMAL) { if (rtp.type != RTP_PRIO_NORMAL) {
error = EPERM; error = EPERM;
goto out; break;
} }
} }
if (rtp_to_pri(&rtp, &p->p_pri) == 0) error = rtp_to_pri(&rtp, &p->p_pri);
error = 0; break;
else
error = EINVAL;
default: default:
error = EINVAL; error = EINVAL;
break;
} }
out:
PROC_UNLOCK(p); PROC_UNLOCK(p);
return (error); return (error);
} }
@ -315,7 +310,7 @@ rtp_to_pri(struct rtprio *rtp, struct priority *pri)
{ {
if (rtp->prio > RTP_PRIO_MAX) if (rtp->prio > RTP_PRIO_MAX)
return (-1); return (EINVAL);
switch (RTP_PRIO_BASE(rtp->type)) { switch (RTP_PRIO_BASE(rtp->type)) {
case RTP_PRIO_REALTIME: case RTP_PRIO_REALTIME:
pri->pri_level = PRI_MIN_REALTIME + rtp->prio; pri->pri_level = PRI_MIN_REALTIME + rtp->prio;
@ -327,7 +322,7 @@ rtp_to_pri(struct rtprio *rtp, struct priority *pri)
pri->pri_level = PRI_MIN_IDLE + rtp->prio; pri->pri_level = PRI_MIN_IDLE + rtp->prio;
break; break;
default: default:
return (-1); return (EINVAL);
} }
pri->pri_class = rtp->type; pri->pri_class = rtp->type;
pri->pri_native = pri->pri_level; pri->pri_native = pri->pri_level;