summaryrefslogtreecommitdiff
path: root/sys/kern/kern_resource.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2004-02-06 19:30:12 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2004-02-06 19:30:12 +0000
commitf4daf0561901f85d3b3f4a9ee58d837785cc5c4a (patch)
treefb9be6eea579b8f27591b3019ace250f5d2309d7 /sys/kern/kern_resource.c
parent99b6e02ba667095e524bb3f4a0224ac8b832fbbf (diff)
Notes
Diffstat (limited to 'sys/kern/kern_resource.c')
-rw-r--r--sys/kern/kern_resource.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index 370a59049283..36084018c84a 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -489,8 +489,18 @@ ogetrlimit(td, uap)
PROC_LOCK(p);
lim_rlimit(p, uap->which, &rl);
PROC_UNLOCK(p);
- olim.rlim_cur = rl.rlim_cur == -1 ? 0x7fffffff : rl.rlim_cur;
- olim.rlim_max = rl.rlim_max == -1 ? 0x7fffffff : rl.rlim_max;
+
+ /*
+ * XXX would be more correct to convert only RLIM_INFINITY to the
+ * old RLIM_INFINITY and fail with EOVERFLOW for other larger
+ * values. Most 64->32 and 32->16 conversions, including not
+ * unimportant ones of uids are even more broken than what we
+ * do here (they blindly truncate). We don't do this correctly
+ * here since we have little experience with EOVERFLOW yet.
+ * Elsewhere, getuid() can't fail...
+ */
+ olim.rlim_cur = rl.rlim_cur > 0x7fffffff ? 0x7fffffff : rl.rlim_cur;
+ olim.rlim_max = rl.rlim_max > 0x7fffffff ? 0x7fffffff : rl.rlim_max;
error = copyout(&olim, uap->rlp, sizeof(olim));
return (error);
}
@@ -712,9 +722,8 @@ calcru(p, up, sp, ip)
tu = (u_int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
ptu = p->p_uu + p->p_su + p->p_iu;
if (tu < ptu || (int64_t)tu < 0) {
- /* XXX no %qd in kernel. Truncate. */
- printf("calcru: negative time of %ld usec for pid %d (%s)\n",
- (long)tu, p->p_pid, p->p_comm);
+ printf("calcru: negative time of %jd usec for pid %d (%s)\n",
+ (intmax_t)tu, p->p_pid, p->p_comm);
tu = ptu;
}
@@ -773,35 +782,33 @@ getrusage(td, uap)
register struct thread *td;
register struct getrusage_args *uap;
{
- struct proc *p = td->td_proc;
- register struct rusage *rup;
- int error = 0;
-
- mtx_lock(&Giant);
+ struct rusage ru;
+ struct proc *p;
+ p = td->td_proc;
switch (uap->who) {
+
case RUSAGE_SELF:
- rup = &p->p_stats->p_ru;
+ mtx_lock(&Giant);
mtx_lock_spin(&sched_lock);
- calcru(p, &rup->ru_utime, &rup->ru_stime, NULL);
+ calcru(p, &p->p_stats->p_ru.ru_utime, &p->p_stats->p_ru.ru_stime,
+ NULL);
mtx_unlock_spin(&sched_lock);
+ ru = p->p_stats->p_ru;
+ mtx_unlock(&Giant);
break;
case RUSAGE_CHILDREN:
- rup = &p->p_stats->p_cru;
+ mtx_lock(&Giant);
+ ru = p->p_stats->p_cru;
+ mtx_unlock(&Giant);
break;
default:
- rup = NULL;
- error = EINVAL;
+ return (EINVAL);
break;
}
- mtx_unlock(&Giant);
- if (error == 0) {
- /* XXX Unlocked access to p_stats->p_ru or p_cru. */
- error = copyout(rup, uap->rusage, sizeof (struct rusage));
- }
- return(error);
+ return (copyout(&ru, uap->rusage, sizeof(struct rusage)));
}
void