1994-05-27 05:00:24 +00:00
|
|
|
/*-
|
2017-11-20 19:49:47 +00:00
|
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
*
|
1994-05-27 05:00:24 +00:00
|
|
|
* Copyright (c) 1989, 1992, 1993
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
|
|
|
*
|
|
|
|
* This code is derived from software developed by the Computer Systems
|
|
|
|
* Engineering group at Lawrence Berkeley Laboratory under DARPA contract
|
|
|
|
* BG 91-66 and contributed to Berkeley.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
2017-02-28 23:42:47 +00:00
|
|
|
* 3. Neither the name of the University nor the names of its contributors
|
1994-05-27 05:00:24 +00:00
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
2002-09-16 08:22:57 +00:00
|
|
|
#include <sys/cdefs.h>
|
|
|
|
__FBSDID("$FreeBSD$");
|
2018-05-22 15:52:22 +00:00
|
|
|
__SCCSID("@(#)kvm_proc.c 8.3 (Berkeley) 9/23/93");
|
1994-05-27 05:00:24 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Proc traversal interface for kvm. ps and w are (probably) the exclusive
|
|
|
|
* users of this code, so we've factored it out into a separate module.
|
|
|
|
* Thus, we keep this grunge out of the other kvm applications (i.e.,
|
|
|
|
* most other applications are interested only in open/close/read/nlist).
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sys/param.h>
|
2005-03-20 10:37:56 +00:00
|
|
|
#define _WANT_UCRED /* make ucred.h give us 'struct ucred' */
|
2002-08-16 07:01:43 +00:00
|
|
|
#include <sys/ucred.h>
|
2005-03-20 10:37:56 +00:00
|
|
|
#include <sys/queue.h>
|
|
|
|
#include <sys/_lock.h>
|
|
|
|
#include <sys/_mutex.h>
|
|
|
|
#include <sys/_task.h>
|
MFp4:
Bring in updated jail support from bz_jail branch.
This enhances the current jail implementation to permit multiple
addresses per jail. In addtion to IPv4, IPv6 is supported as well.
Due to updated checks it is even possible to have jails without
an IP address at all, which basically gives one a chroot with
restricted process view, no networking,..
SCTP support was updated and supports IPv6 in jails as well.
Cpuset support permits jails to be bound to specific processor
sets after creation.
Jails can have an unrestricted (no duplicate protection, etc.) name
in addition to the hostname. The jail name cannot be changed from
within a jail and is considered to be used for management purposes
or as audit-token in the future.
DDB 'show jails' command was added to aid debugging.
Proper compat support permits 32bit jail binaries to be used on 64bit
systems to manage jails. Also backward compatibility was preserved where
possible: for jail v1 syscalls, as well as with user space management
utilities.
Both jail as well as prison version were updated for the new features.
A gap was intentionally left as the intermediate versions had been
used by various patches floating around the last years.
Bump __FreeBSD_version for the afore mentioned and in kernel changes.
Special thanks to:
- Pawel Jakub Dawidek (pjd) for his multi-IPv4 patches
and Olivier Houchard (cognet) for initial single-IPv6 patches.
- Jeff Roberson (jeff) and Randall Stewart (rrs) for their
help, ideas and review on cpuset and SCTP support.
- Robert Watson (rwatson) for lots and lots of help, discussions,
suggestions and review of most of the patch at various stages.
- John Baldwin (jhb) for his help.
- Simon L. Nielsen (simon) as early adopter testing changes
on cluster machines as well as all the testers and people
who provided feedback the last months on freebsd-jail and
other channels.
- My employer, CK Software GmbH, for the support so I could work on this.
Reviewed by: (see above)
MFC after: 3 months (this is just so that I get the mail)
X-MFC Before: 7.2-RELEASE if possible
2008-11-29 14:32:14 +00:00
|
|
|
#include <sys/cpuset.h>
|
1994-05-27 05:00:24 +00:00
|
|
|
#include <sys/user.h>
|
|
|
|
#include <sys/proc.h>
|
MFp4:
Bring in updated jail support from bz_jail branch.
This enhances the current jail implementation to permit multiple
addresses per jail. In addtion to IPv4, IPv6 is supported as well.
Due to updated checks it is even possible to have jails without
an IP address at all, which basically gives one a chroot with
restricted process view, no networking,..
SCTP support was updated and supports IPv6 in jails as well.
Cpuset support permits jails to be bound to specific processor
sets after creation.
Jails can have an unrestricted (no duplicate protection, etc.) name
in addition to the hostname. The jail name cannot be changed from
within a jail and is considered to be used for management purposes
or as audit-token in the future.
DDB 'show jails' command was added to aid debugging.
Proper compat support permits 32bit jail binaries to be used on 64bit
systems to manage jails. Also backward compatibility was preserved where
possible: for jail v1 syscalls, as well as with user space management
utilities.
Both jail as well as prison version were updated for the new features.
A gap was intentionally left as the intermediate versions had been
used by various patches floating around the last years.
Bump __FreeBSD_version for the afore mentioned and in kernel changes.
Special thanks to:
- Pawel Jakub Dawidek (pjd) for his multi-IPv4 patches
and Olivier Houchard (cognet) for initial single-IPv6 patches.
- Jeff Roberson (jeff) and Randall Stewart (rrs) for their
help, ideas and review on cpuset and SCTP support.
- Robert Watson (rwatson) for lots and lots of help, discussions,
suggestions and review of most of the patch at various stages.
- John Baldwin (jhb) for his help.
- Simon L. Nielsen (simon) as early adopter testing changes
on cluster machines as well as all the testers and people
who provided feedback the last months on freebsd-jail and
other channels.
- My employer, CK Software GmbH, for the support so I could work on this.
Reviewed by: (see above)
MFC after: 3 months (this is just so that I get the mail)
X-MFC Before: 7.2-RELEASE if possible
2008-11-29 14:32:14 +00:00
|
|
|
#define _WANT_PRISON /* make jail.h give us 'struct prison' */
|
|
|
|
#include <sys/jail.h>
|
1994-05-27 05:00:24 +00:00
|
|
|
#include <sys/exec.h>
|
|
|
|
#include <sys/stat.h>
|
2004-06-19 14:08:10 +00:00
|
|
|
#include <sys/sysent.h>
|
1994-05-27 05:00:24 +00:00
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <sys/tty.h>
|
1994-08-11 13:38:23 +00:00
|
|
|
#include <sys/file.h>
|
2004-10-11 21:56:27 +00:00
|
|
|
#include <sys/conf.h>
|
2015-07-18 09:02:50 +00:00
|
|
|
#define _WANT_KW_EXITCODE
|
|
|
|
#include <sys/wait.h>
|
1996-07-12 18:57:58 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2019-09-22 13:56:27 +00:00
|
|
|
#include <stdbool.h>
|
1994-05-27 05:00:24 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <nlist.h>
|
|
|
|
#include <kvm.h>
|
|
|
|
|
|
|
|
#include <sys/sysctl.h>
|
|
|
|
|
|
|
|
#include <limits.h>
|
1995-12-09 04:42:51 +00:00
|
|
|
#include <memory.h>
|
1994-05-27 05:00:24 +00:00
|
|
|
#include <paths.h>
|
|
|
|
|
|
|
|
#include "kvm_private.h"
|
|
|
|
|
|
|
|
#define KREAD(kd, addr, obj) \
|
|
|
|
(kvm_read(kd, addr, (char *)(obj), sizeof(*obj)) != sizeof(*obj))
|
|
|
|
|
2007-09-21 04:11:34 +00:00
|
|
|
static int ticks;
|
|
|
|
static int hz;
|
2011-01-23 11:08:36 +00:00
|
|
|
static uint64_t cpu_tick_frequency;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* From sys/kern/kern_tc.c. Depends on cpu_tick_frequency, which is
|
|
|
|
* read/initialized before this function is ever called.
|
|
|
|
*/
|
|
|
|
static uint64_t
|
|
|
|
cputick2usec(uint64_t tick)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (cpu_tick_frequency == 0)
|
|
|
|
return (0);
|
|
|
|
if (tick > 18446744073709551) /* floor(2^64 / 1000) */
|
|
|
|
return (tick / (cpu_tick_frequency / 1000000));
|
|
|
|
else if (tick > 18446744073709) /* floor(2^64 / 1000000) */
|
|
|
|
return ((tick * 1000) / (cpu_tick_frequency / 1000));
|
|
|
|
else
|
|
|
|
return ((tick * 1000000) / cpu_tick_frequency);
|
|
|
|
}
|
2007-09-21 04:11:34 +00:00
|
|
|
|
1994-05-27 05:00:24 +00:00
|
|
|
/*
|
|
|
|
* Read proc's from memory file into buffer bp, which has space to hold
|
|
|
|
* at most maxcnt procs.
|
|
|
|
*/
|
|
|
|
static int
|
2011-01-23 11:08:28 +00:00
|
|
|
kvm_proclist(kvm_t *kd, int what, int arg, struct proc *p,
|
|
|
|
struct kinfo_proc *bp, int maxcnt)
|
1994-05-27 05:00:24 +00:00
|
|
|
{
|
2002-03-21 23:39:28 +00:00
|
|
|
int cnt = 0;
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
struct kinfo_proc kinfo_proc, *kp;
|
1994-05-27 05:00:24 +00:00
|
|
|
struct pgrp pgrp;
|
|
|
|
struct session sess;
|
2004-10-11 21:56:27 +00:00
|
|
|
struct cdev t_cdev;
|
1994-05-27 05:00:24 +00:00
|
|
|
struct tty tty;
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
struct vmspace vmspace;
|
2003-05-14 15:01:20 +00:00
|
|
|
struct sigacts sigacts;
|
2011-01-23 11:08:28 +00:00
|
|
|
#if 0
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
struct pstats pstats;
|
2011-01-23 11:08:28 +00:00
|
|
|
#endif
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
struct ucred ucred;
|
2005-03-20 10:37:56 +00:00
|
|
|
struct prison pr;
|
2002-09-11 08:13:56 +00:00
|
|
|
struct thread mtd;
|
1994-05-27 05:00:24 +00:00
|
|
|
struct proc proc;
|
1997-06-25 20:56:48 +00:00
|
|
|
struct proc pproc;
|
2004-06-19 14:08:10 +00:00
|
|
|
struct sysentvec sysent;
|
|
|
|
char svname[KI_EMULNAMELEN];
|
2019-09-22 13:56:27 +00:00
|
|
|
struct thread *td = NULL;
|
|
|
|
bool first_thread;
|
1994-05-27 05:00:24 +00:00
|
|
|
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp = &kinfo_proc;
|
|
|
|
kp->ki_structsize = sizeof(kinfo_proc);
|
2007-10-26 08:00:41 +00:00
|
|
|
/*
|
2019-09-22 13:56:27 +00:00
|
|
|
* Loop on the processes, then threads within the process if requested.
|
2007-10-26 08:00:41 +00:00
|
|
|
*/
|
2019-09-22 13:56:27 +00:00
|
|
|
if (what == KERN_PROC_ALL)
|
|
|
|
what |= KERN_PROC_INC_THREAD;
|
2000-12-30 21:52:34 +00:00
|
|
|
for (; cnt < maxcnt && p != NULL; p = LIST_NEXT(&proc, p_list)) {
|
2001-08-24 09:43:44 +00:00
|
|
|
memset(kp, 0, sizeof *kp);
|
1994-05-27 05:00:24 +00:00
|
|
|
if (KREAD(kd, (u_long)p, &proc)) {
|
2011-01-23 11:08:28 +00:00
|
|
|
_kvm_err(kd, kd->program, "can't read proc at %p", p);
|
1994-05-27 05:00:24 +00:00
|
|
|
return (-1);
|
|
|
|
}
|
2012-10-06 20:12:24 +00:00
|
|
|
if (proc.p_state == PRS_NEW)
|
|
|
|
continue;
|
o Merge contents of struct pcred into struct ucred. Specifically, add the
real uid, saved uid, real gid, and saved gid to ucred, as well as the
pcred->pc_uidinfo, which was associated with the real uid, only rename
it to cr_ruidinfo so as not to conflict with cr_uidinfo, which
corresponds to the effective uid.
o Remove p_cred from struct proc; add p_ucred to struct proc, replacing
original macro that pointed.
p->p_ucred to p->p_cred->pc_ucred.
o Universally update code so that it makes use of ucred instead of pcred,
p->p_ucred instead of p->p_pcred, cr_ruidinfo instead of p_uidinfo,
cr_{r,sv}{u,g}id instead of p_*, etc.
o Remove pcred0 and its initialization from init_main.c; initialize
cr_ruidinfo there.
o Restruction many credential modification chunks to always crdup while
we figure out locking and optimizations; generally speaking, this
means moving to a structure like this:
newcred = crdup(oldcred);
...
p->p_ucred = newcred;
crfree(oldcred);
It's not race-free, but better than nothing. There are also races
in sys_process.c, all inter-process authorization, fork, exec, and
exit.
o Remove sigio->sio_ruid since sigio->sio_ucred now contains the ruid;
remove comments indicating that the old arrangement was a problem.
o Restructure exec1() a little to use newcred/oldcred arrangement, and
use improved uid management primitives.
o Clean up exit1() so as to do less work in credential cleanup due to
pcred removal.
o Clean up fork1() so as to do less work in credential cleanup and
allocation.
o Clean up ktrcanset() to take into account changes, and move to using
suser_xxx() instead of performing a direct uid==0 comparision.
o Improve commenting in various kern_prot.c credential modification
calls to better document current behavior. In a couple of places,
current behavior is a little questionable and we need to check
POSIX.1 to make sure it's "right". More commenting work still
remains to be done.
o Update credential management calls, such as crfree(), to take into
account new ruidinfo reference.
o Modify or add the following uid and gid helper routines:
change_euid()
change_egid()
change_ruid()
change_rgid()
change_svuid()
change_svgid()
In each case, the call now acts on a credential not a process, and as
such no longer requires more complicated process locking/etc. They
now assume the caller will do any necessary allocation of an
exclusive credential reference. Each is commented to document its
reference requirements.
o CANSIGIO() is simplified to require only credentials, not processes
and pcreds.
o Remove lots of (p_pcred==NULL) checks.
o Add an XXX to authorization code in nfs_lock.c, since it's
questionable, and needs to be considered carefully.
o Simplify posix4 authorization code to require only credentials, not
processes and pcreds. Note that this authorization, as well as
CANSIGIO(), needs to be updated to use the p_cansignal() and
p_cansched() centralized authorization routines, as they currently
do not take into account some desirable restrictions that are handled
by the centralized routines, as well as being inconsistent with other
similar authorization instances.
o Update libkvm to take these changes into account.
Obtained from: TrustedBSD Project
Reviewed by: green, bde, jhb, freebsd-arch, freebsd-audit
2001-05-25 16:59:11 +00:00
|
|
|
if (KREAD(kd, (u_long)proc.p_ucred, &ucred) == 0) {
|
|
|
|
kp->ki_ruid = ucred.cr_ruid;
|
|
|
|
kp->ki_svuid = ucred.cr_svuid;
|
|
|
|
kp->ki_rgid = ucred.cr_rgid;
|
|
|
|
kp->ki_svgid = ucred.cr_svgid;
|
2009-07-24 15:03:10 +00:00
|
|
|
kp->ki_cr_flags = ucred.cr_flags;
|
|
|
|
if (ucred.cr_ngroups > KI_NGROUPS) {
|
|
|
|
kp->ki_ngroups = KI_NGROUPS;
|
|
|
|
kp->ki_cr_flags |= KI_CRF_GRP_OVERFLOW;
|
2009-12-10 21:16:16 +00:00
|
|
|
} else
|
2009-07-24 15:03:10 +00:00
|
|
|
kp->ki_ngroups = ucred.cr_ngroups;
|
2009-09-08 19:37:59 +00:00
|
|
|
kvm_read(kd, (u_long)ucred.cr_groups, kp->ki_groups,
|
2009-07-24 15:03:10 +00:00
|
|
|
kp->ki_ngroups * sizeof(gid_t));
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp->ki_uid = ucred.cr_uid;
|
2005-03-20 10:37:56 +00:00
|
|
|
if (ucred.cr_prison != NULL) {
|
|
|
|
if (KREAD(kd, (u_long)ucred.cr_prison, &pr)) {
|
|
|
|
_kvm_err(kd, kd->program,
|
2011-01-23 11:08:28 +00:00
|
|
|
"can't read prison at %p",
|
2005-03-20 10:37:56 +00:00
|
|
|
ucred.cr_prison);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
kp->ki_jid = pr.pr_id;
|
|
|
|
}
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
}
|
1994-05-27 05:00:24 +00:00
|
|
|
|
2004-02-22 17:57:10 +00:00
|
|
|
switch(what & ~KERN_PROC_INC_THREAD) {
|
1995-05-30 05:51:47 +00:00
|
|
|
|
2004-06-19 14:08:10 +00:00
|
|
|
case KERN_PROC_GID:
|
|
|
|
if (kp->ki_groups[0] != (gid_t)arg)
|
|
|
|
continue;
|
|
|
|
break;
|
|
|
|
|
1994-05-27 05:00:24 +00:00
|
|
|
case KERN_PROC_PID:
|
|
|
|
if (proc.p_pid != (pid_t)arg)
|
|
|
|
continue;
|
|
|
|
break;
|
|
|
|
|
2004-06-19 14:08:10 +00:00
|
|
|
case KERN_PROC_RGID:
|
|
|
|
if (kp->ki_rgid != (gid_t)arg)
|
|
|
|
continue;
|
|
|
|
break;
|
|
|
|
|
1994-05-27 05:00:24 +00:00
|
|
|
case KERN_PROC_UID:
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
if (kp->ki_uid != (uid_t)arg)
|
1994-05-27 05:00:24 +00:00
|
|
|
continue;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KERN_PROC_RUID:
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
if (kp->ki_ruid != (uid_t)arg)
|
1994-05-27 05:00:24 +00:00
|
|
|
continue;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* We're going to add another proc to the set. If this
|
|
|
|
* will overflow the buffer, assume the reason is because
|
|
|
|
* nprocs (or the proc list) is corrupt and declare an error.
|
|
|
|
*/
|
|
|
|
if (cnt >= maxcnt) {
|
|
|
|
_kvm_err(kd, kd->program, "nprocs corrupt");
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
/*
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
* gather kinfo_proc
|
1994-05-27 05:00:24 +00:00
|
|
|
*/
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp->ki_paddr = p;
|
2004-11-20 02:28:26 +00:00
|
|
|
kp->ki_addr = 0; /* XXX uarea */
|
2001-09-12 08:38:13 +00:00
|
|
|
/* kp->ki_kstack = proc.p_thread.td_kstack; XXXKSE */
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp->ki_args = proc.p_args;
|
2019-09-22 13:56:27 +00:00
|
|
|
kp->ki_numthreads = proc.p_numthreads;
|
2021-05-22 12:43:57 +00:00
|
|
|
kp->ki_tracep = NULL; /* XXXKIB do not expose ktr_io_params */
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp->ki_textvp = proc.p_textvp;
|
|
|
|
kp->ki_fd = proc.p_fd;
|
2020-11-17 21:14:13 +00:00
|
|
|
kp->ki_pd = proc.p_pd;
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp->ki_vmspace = proc.p_vmspace;
|
2003-05-14 15:01:20 +00:00
|
|
|
if (proc.p_sigacts != NULL) {
|
|
|
|
if (KREAD(kd, (u_long)proc.p_sigacts, &sigacts)) {
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
_kvm_err(kd, kd->program,
|
2011-01-23 11:08:28 +00:00
|
|
|
"can't read sigacts at %p", proc.p_sigacts);
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
return (-1);
|
|
|
|
}
|
2003-05-14 15:01:20 +00:00
|
|
|
kp->ki_sigignore = sigacts.ps_sigignore;
|
|
|
|
kp->ki_sigcatch = sigacts.ps_sigcatch;
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
}
|
2007-06-01 04:14:57 +00:00
|
|
|
#if 0
|
2007-09-17 05:31:39 +00:00
|
|
|
if ((proc.p_flag & P_INMEM) && proc.p_stats != NULL) {
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
if (KREAD(kd, (u_long)proc.p_stats, &pstats)) {
|
|
|
|
_kvm_err(kd, kd->program,
|
|
|
|
"can't read stats at %x", proc.p_stats);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
kp->ki_start = pstats.p_start;
|
2004-10-06 17:10:56 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX: The times here are probably zero and need
|
|
|
|
* to be calculated from the raw data in p_rux and
|
|
|
|
* p_crux.
|
|
|
|
*/
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp->ki_rusage = pstats.p_ru;
|
2004-06-19 14:08:10 +00:00
|
|
|
kp->ki_childstime = pstats.p_cru.ru_stime;
|
|
|
|
kp->ki_childutime = pstats.p_cru.ru_utime;
|
|
|
|
/* Some callers want child-times in a single value */
|
|
|
|
timeradd(&kp->ki_childstime, &kp->ki_childutime,
|
|
|
|
&kp->ki_childtime);
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
}
|
2007-06-01 04:14:57 +00:00
|
|
|
#endif
|
1997-06-25 20:56:48 +00:00
|
|
|
if (proc.p_oppid)
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp->ki_ppid = proc.p_oppid;
|
1997-06-25 20:56:48 +00:00
|
|
|
else if (proc.p_pptr) {
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
if (KREAD(kd, (u_long)proc.p_pptr, &pproc)) {
|
|
|
|
_kvm_err(kd, kd->program,
|
2011-01-23 11:08:28 +00:00
|
|
|
"can't read pproc at %p", proc.p_pptr);
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
kp->ki_ppid = pproc.p_pid;
|
2015-11-26 19:42:10 +00:00
|
|
|
} else
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp->ki_ppid = 0;
|
2001-08-24 09:43:44 +00:00
|
|
|
if (proc.p_pgrp == NULL)
|
|
|
|
goto nopgrp;
|
|
|
|
if (KREAD(kd, (u_long)proc.p_pgrp, &pgrp)) {
|
2011-01-23 11:08:28 +00:00
|
|
|
_kvm_err(kd, kd->program, "can't read pgrp at %p",
|
2001-08-24 09:43:44 +00:00
|
|
|
proc.p_pgrp);
|
|
|
|
return (-1);
|
|
|
|
}
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp->ki_pgid = pgrp.pg_id;
|
2020-12-29 00:41:56 +00:00
|
|
|
kp->ki_jobc = -1; /* Or calculate? Arguably not. */
|
1994-05-27 05:00:24 +00:00
|
|
|
if (KREAD(kd, (u_long)pgrp.pg_session, &sess)) {
|
2011-01-23 11:08:28 +00:00
|
|
|
_kvm_err(kd, kd->program, "can't read session at %p",
|
1994-05-27 05:00:24 +00:00
|
|
|
pgrp.pg_session);
|
|
|
|
return (-1);
|
|
|
|
}
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp->ki_sid = sess.s_sid;
|
|
|
|
(void)memcpy(kp->ki_login, sess.s_login,
|
|
|
|
sizeof(kp->ki_login));
|
1994-05-27 05:00:24 +00:00
|
|
|
if ((proc.p_flag & P_CONTROLT) && sess.s_ttyp != NULL) {
|
|
|
|
if (KREAD(kd, (u_long)sess.s_ttyp, &tty)) {
|
|
|
|
_kvm_err(kd, kd->program,
|
2011-01-23 11:08:28 +00:00
|
|
|
"can't read tty at %p", sess.s_ttyp);
|
1994-05-27 05:00:24 +00:00
|
|
|
return (-1);
|
|
|
|
}
|
2004-10-11 21:56:27 +00:00
|
|
|
if (tty.t_dev != NULL) {
|
|
|
|
if (KREAD(kd, (u_long)tty.t_dev, &t_cdev)) {
|
|
|
|
_kvm_err(kd, kd->program,
|
2011-01-23 11:08:28 +00:00
|
|
|
"can't read cdev at %p",
|
2004-10-11 21:56:27 +00:00
|
|
|
tty.t_dev);
|
|
|
|
return (-1);
|
|
|
|
}
|
2005-03-15 14:26:14 +00:00
|
|
|
#if 0
|
2004-10-11 21:56:27 +00:00
|
|
|
kp->ki_tdev = t_cdev.si_udev;
|
2005-03-15 14:26:14 +00:00
|
|
|
#else
|
2005-06-24 00:37:04 +00:00
|
|
|
kp->ki_tdev = NODEV;
|
2005-03-15 14:26:14 +00:00
|
|
|
#endif
|
2004-10-11 21:56:27 +00:00
|
|
|
}
|
1994-05-27 05:00:24 +00:00
|
|
|
if (tty.t_pgrp != NULL) {
|
|
|
|
if (KREAD(kd, (u_long)tty.t_pgrp, &pgrp)) {
|
|
|
|
_kvm_err(kd, kd->program,
|
2011-01-23 11:08:28 +00:00
|
|
|
"can't read tpgrp at %p",
|
1994-05-27 05:00:24 +00:00
|
|
|
tty.t_pgrp);
|
|
|
|
return (-1);
|
|
|
|
}
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp->ki_tpgid = pgrp.pg_id;
|
1994-05-27 05:00:24 +00:00
|
|
|
} else
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp->ki_tpgid = -1;
|
|
|
|
if (tty.t_session != NULL) {
|
|
|
|
if (KREAD(kd, (u_long)tty.t_session, &sess)) {
|
|
|
|
_kvm_err(kd, kd->program,
|
2011-01-23 11:08:28 +00:00
|
|
|
"can't read session at %p",
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
tty.t_session);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
kp->ki_tsid = sess.s_sid;
|
|
|
|
}
|
2001-08-24 09:43:44 +00:00
|
|
|
} else {
|
|
|
|
nopgrp:
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp->ki_tdev = NODEV;
|
2001-08-24 09:43:44 +00:00
|
|
|
}
|
1994-05-27 05:00:24 +00:00
|
|
|
|
|
|
|
(void)kvm_read(kd, (u_long)proc.p_vmspace,
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
(char *)&vmspace, sizeof(vmspace));
|
|
|
|
kp->ki_size = vmspace.vm_map.size;
|
2010-06-18 01:17:16 +00:00
|
|
|
/*
|
|
|
|
* Approximate the kernel's method of calculating
|
|
|
|
* this field.
|
|
|
|
*/
|
|
|
|
#define pmap_resident_count(pm) ((pm)->pm_stats.resident_count)
|
2015-11-26 19:42:10 +00:00
|
|
|
kp->ki_rssize = pmap_resident_count(&vmspace.vm_pmap);
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp->ki_swrss = vmspace.vm_swrss;
|
|
|
|
kp->ki_tsize = vmspace.vm_tsize;
|
|
|
|
kp->ki_dsize = vmspace.vm_dsize;
|
|
|
|
kp->ki_ssize = vmspace.vm_ssize;
|
1994-05-27 05:00:24 +00:00
|
|
|
|
2004-02-22 17:57:10 +00:00
|
|
|
switch (what & ~KERN_PROC_INC_THREAD) {
|
1994-05-27 05:00:24 +00:00
|
|
|
|
|
|
|
case KERN_PROC_PGRP:
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
if (kp->ki_pgid != (pid_t)arg)
|
1994-05-27 05:00:24 +00:00
|
|
|
continue;
|
|
|
|
break;
|
|
|
|
|
2004-06-19 14:08:10 +00:00
|
|
|
case KERN_PROC_SESSION:
|
|
|
|
if (kp->ki_sid != (pid_t)arg)
|
|
|
|
continue;
|
|
|
|
break;
|
|
|
|
|
1994-05-27 05:00:24 +00:00
|
|
|
case KERN_PROC_TTY:
|
1995-05-30 05:51:47 +00:00
|
|
|
if ((proc.p_flag & P_CONTROLT) == 0 ||
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp->ki_tdev != (dev_t)arg)
|
1994-05-27 05:00:24 +00:00
|
|
|
continue;
|
|
|
|
break;
|
|
|
|
}
|
2004-06-23 21:31:43 +00:00
|
|
|
if (proc.p_comm[0] != 0)
|
|
|
|
strlcpy(kp->ki_comm, proc.p_comm, MAXCOMLEN);
|
2004-06-19 14:08:10 +00:00
|
|
|
(void)kvm_read(kd, (u_long)proc.p_sysent, (char *)&sysent,
|
|
|
|
sizeof(sysent));
|
|
|
|
(void)kvm_read(kd, (u_long)sysent.sv_name, (char *)&svname,
|
|
|
|
sizeof(svname));
|
|
|
|
if (svname[0] != 0)
|
|
|
|
strlcpy(kp->ki_emul, svname, KI_EMULNAMELEN);
|
2011-01-23 11:08:36 +00:00
|
|
|
kp->ki_runtime = cputick2usec(proc.p_rux.rux_runtime);
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp->ki_pid = proc.p_pid;
|
2015-07-18 09:02:50 +00:00
|
|
|
kp->ki_xstat = KW_EXITCODE(proc.p_xexit, proc.p_xsig);
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
kp->ki_acflag = proc.p_acflag;
|
2002-09-15 23:52:25 +00:00
|
|
|
kp->ki_lock = proc.p_lock;
|
2019-09-22 13:56:27 +00:00
|
|
|
kp->ki_tdev_freebsd11 = kp->ki_tdev; /* truncate */
|
|
|
|
|
|
|
|
/* Per-thread items; iterate as appropriate. */
|
|
|
|
td = TAILQ_FIRST(&proc.p_threads);
|
|
|
|
for (first_thread = true; cnt < maxcnt && td != NULL &&
|
|
|
|
(first_thread || (what & KERN_PROC_INC_THREAD));
|
|
|
|
first_thread = false) {
|
|
|
|
if (proc.p_state != PRS_ZOMBIE) {
|
|
|
|
if (KREAD(kd, (u_long)td, &mtd)) {
|
|
|
|
_kvm_err(kd, kd->program,
|
|
|
|
"can't read thread at %p", td);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
if (what & KERN_PROC_INC_THREAD)
|
|
|
|
td = TAILQ_NEXT(&mtd, td_plist);
|
|
|
|
} else
|
|
|
|
td = NULL;
|
|
|
|
if ((proc.p_state != PRS_ZOMBIE) && mtd.td_wmesg)
|
|
|
|
(void)kvm_read(kd, (u_long)mtd.td_wmesg,
|
|
|
|
kp->ki_wmesg, WMESGLEN);
|
|
|
|
else
|
|
|
|
memset(kp->ki_wmesg, 0, WMESGLEN);
|
|
|
|
if (proc.p_pgrp == NULL) {
|
|
|
|
kp->ki_kiflag = 0;
|
|
|
|
} else {
|
|
|
|
kp->ki_kiflag = sess.s_ttyvp ? KI_CTTY : 0;
|
|
|
|
if (sess.s_leader == p)
|
|
|
|
kp->ki_kiflag |= KI_SLEADER;
|
|
|
|
}
|
|
|
|
if ((proc.p_state != PRS_ZOMBIE) &&
|
|
|
|
(mtd.td_blocked != 0)) {
|
|
|
|
kp->ki_kiflag |= KI_LOCKBLOCK;
|
|
|
|
if (mtd.td_lockname)
|
|
|
|
(void)kvm_read(kd,
|
|
|
|
(u_long)mtd.td_lockname,
|
|
|
|
kp->ki_lockname, LOCKNAMELEN);
|
|
|
|
else
|
|
|
|
memset(kp->ki_lockname, 0,
|
|
|
|
LOCKNAMELEN);
|
|
|
|
kp->ki_lockname[LOCKNAMELEN] = 0;
|
|
|
|
} else
|
|
|
|
kp->ki_kiflag &= ~KI_LOCKBLOCK;
|
|
|
|
kp->ki_siglist = proc.p_siglist;
|
|
|
|
if (proc.p_state != PRS_ZOMBIE) {
|
|
|
|
SIGSETOR(kp->ki_siglist, mtd.td_siglist);
|
|
|
|
kp->ki_sigmask = mtd.td_sigmask;
|
|
|
|
kp->ki_swtime = (ticks - proc.p_swtick) / hz;
|
|
|
|
kp->ki_flag = proc.p_flag;
|
|
|
|
kp->ki_sflag = 0;
|
|
|
|
kp->ki_nice = proc.p_nice;
|
|
|
|
kp->ki_traceflag = proc.p_traceflag;
|
|
|
|
if (proc.p_state == PRS_NORMAL) {
|
|
|
|
if (TD_ON_RUNQ(&mtd) ||
|
|
|
|
TD_CAN_RUN(&mtd) ||
|
|
|
|
TD_IS_RUNNING(&mtd)) {
|
|
|
|
kp->ki_stat = SRUN;
|
2021-02-18 10:25:10 +00:00
|
|
|
} else if (TD_GET_STATE(&mtd) ==
|
2019-09-22 13:56:27 +00:00
|
|
|
TDS_INHIBITED) {
|
|
|
|
if (P_SHOULDSTOP(&proc)) {
|
|
|
|
kp->ki_stat = SSTOP;
|
|
|
|
} else if (
|
|
|
|
TD_IS_SLEEPING(&mtd)) {
|
|
|
|
kp->ki_stat = SSLEEP;
|
|
|
|
} else if (TD_ON_LOCK(&mtd)) {
|
|
|
|
kp->ki_stat = SLOCK;
|
|
|
|
} else {
|
|
|
|
kp->ki_stat = SWAIT;
|
|
|
|
}
|
2002-09-11 08:13:56 +00:00
|
|
|
}
|
2019-09-22 13:56:27 +00:00
|
|
|
} else {
|
|
|
|
kp->ki_stat = SIDL;
|
2002-06-30 08:11:30 +00:00
|
|
|
}
|
2019-09-22 13:56:27 +00:00
|
|
|
/* Stuff from the thread */
|
|
|
|
kp->ki_pri.pri_level = mtd.td_priority;
|
|
|
|
kp->ki_pri.pri_native = mtd.td_base_pri;
|
|
|
|
kp->ki_lastcpu = mtd.td_lastcpu;
|
|
|
|
kp->ki_wchan = mtd.td_wchan;
|
|
|
|
kp->ki_oncpu = mtd.td_oncpu;
|
|
|
|
if (mtd.td_name[0] != '\0')
|
|
|
|
strlcpy(kp->ki_tdname, mtd.td_name,
|
|
|
|
sizeof(kp->ki_tdname));
|
|
|
|
else
|
|
|
|
memset(kp->ki_tdname, 0,
|
|
|
|
sizeof(kp->ki_tdname));
|
|
|
|
kp->ki_pctcpu = 0;
|
|
|
|
kp->ki_rqindex = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Note: legacy fields; wraps at NO_CPU_OLD
|
|
|
|
* or the old max CPU value as appropriate
|
|
|
|
*/
|
|
|
|
if (mtd.td_lastcpu == NOCPU)
|
|
|
|
kp->ki_lastcpu_old = NOCPU_OLD;
|
|
|
|
else if (mtd.td_lastcpu > MAXCPU_OLD)
|
|
|
|
kp->ki_lastcpu_old = MAXCPU_OLD;
|
|
|
|
else
|
|
|
|
kp->ki_lastcpu_old = mtd.td_lastcpu;
|
|
|
|
|
|
|
|
if (mtd.td_oncpu == NOCPU)
|
|
|
|
kp->ki_oncpu_old = NOCPU_OLD;
|
|
|
|
else if (mtd.td_oncpu > MAXCPU_OLD)
|
|
|
|
kp->ki_oncpu_old = MAXCPU_OLD;
|
|
|
|
else
|
|
|
|
kp->ki_oncpu_old = mtd.td_oncpu;
|
|
|
|
kp->ki_tid = mtd.td_tid;
|
Part 1 of KSE-III
The ability to schedule multiple threads per process
(one one cpu) by making ALL system calls optionally asynchronous.
to come: ia64 and power-pc patches, patches for gdb, test program (in tools)
Reviewed by: Almost everyone who counts
(at various times, peter, jhb, matt, alfred, mini, bernd,
and a cast of thousands)
NOTE: this is still Beta code, and contains lots of debugging stuff.
expect slight instability in signals..
2002-06-29 17:26:22 +00:00
|
|
|
} else {
|
2019-09-22 13:56:27 +00:00
|
|
|
memset(&kp->ki_sigmask, 0,
|
|
|
|
sizeof(kp->ki_sigmask));
|
|
|
|
kp->ki_stat = SZOMB;
|
|
|
|
kp->ki_tid = 0;
|
Part 1 of KSE-III
The ability to schedule multiple threads per process
(one one cpu) by making ALL system calls optionally asynchronous.
to come: ia64 and power-pc patches, patches for gdb, test program (in tools)
Reviewed by: Almost everyone who counts
(at various times, peter, jhb, matt, alfred, mini, bernd,
and a cast of thousands)
NOTE: this is still Beta code, and contains lots of debugging stuff.
expect slight instability in signals..
2002-06-29 17:26:22 +00:00
|
|
|
}
|
2014-10-18 19:36:11 +00:00
|
|
|
|
2019-09-22 13:56:27 +00:00
|
|
|
bcopy(&kinfo_proc, bp, sizeof(kinfo_proc));
|
|
|
|
++bp;
|
|
|
|
++cnt;
|
Part 1 of KSE-III
The ability to schedule multiple threads per process
(one one cpu) by making ALL system calls optionally asynchronous.
to come: ia64 and power-pc patches, patches for gdb, test program (in tools)
Reviewed by: Almost everyone who counts
(at various times, peter, jhb, matt, alfred, mini, bernd,
and a cast of thousands)
NOTE: this is still Beta code, and contains lots of debugging stuff.
expect slight instability in signals..
2002-06-29 17:26:22 +00:00
|
|
|
}
|
1994-05-27 05:00:24 +00:00
|
|
|
}
|
|
|
|
return (cnt);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Build proc info array by reading in proc list from a crash dump.
|
|
|
|
* Return number of procs read. maxcnt is the max we will read.
|
|
|
|
*/
|
|
|
|
static int
|
2011-01-23 11:08:28 +00:00
|
|
|
kvm_deadprocs(kvm_t *kd, int what, int arg, u_long a_allproc,
|
|
|
|
u_long a_zombproc, int maxcnt)
|
1994-05-27 05:00:24 +00:00
|
|
|
{
|
2002-03-21 23:39:28 +00:00
|
|
|
struct kinfo_proc *bp = kd->procbase;
|
2019-09-22 13:56:27 +00:00
|
|
|
int acnt, zcnt = 0;
|
1994-05-27 05:00:24 +00:00
|
|
|
struct proc *p;
|
|
|
|
|
|
|
|
if (KREAD(kd, a_allproc, &p)) {
|
|
|
|
_kvm_err(kd, kd->program, "cannot read allproc");
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
acnt = kvm_proclist(kd, what, arg, p, bp, maxcnt);
|
|
|
|
if (acnt < 0)
|
|
|
|
return (acnt);
|
|
|
|
|
2019-09-22 13:56:27 +00:00
|
|
|
if (a_zombproc != 0) {
|
|
|
|
if (KREAD(kd, a_zombproc, &p)) {
|
|
|
|
_kvm_err(kd, kd->program, "cannot read zombproc");
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
zcnt = kvm_proclist(kd, what, arg, p, bp + acnt, maxcnt - acnt);
|
|
|
|
if (zcnt < 0)
|
|
|
|
zcnt = 0;
|
1994-05-27 05:00:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return (acnt + zcnt);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct kinfo_proc *
|
2011-01-23 11:08:28 +00:00
|
|
|
kvm_getprocs(kvm_t *kd, int op, int arg, int *cnt)
|
1994-05-27 05:00:24 +00:00
|
|
|
{
|
1998-08-25 07:52:33 +00:00
|
|
|
int mib[4], st, nprocs;
|
2012-02-01 18:02:13 +00:00
|
|
|
size_t size, osize;
|
2004-02-22 17:57:10 +00:00
|
|
|
int temp_op;
|
1994-05-27 05:00:24 +00:00
|
|
|
|
|
|
|
if (kd->procbase != 0) {
|
|
|
|
free((void *)kd->procbase);
|
1995-05-30 05:51:47 +00:00
|
|
|
/*
|
1994-05-27 05:00:24 +00:00
|
|
|
* Clear this pointer in case this call fails. Otherwise,
|
|
|
|
* kvm_close() will free it again.
|
|
|
|
*/
|
|
|
|
kd->procbase = 0;
|
|
|
|
}
|
|
|
|
if (ISALIVE(kd)) {
|
|
|
|
size = 0;
|
|
|
|
mib[0] = CTL_KERN;
|
|
|
|
mib[1] = KERN_PROC;
|
|
|
|
mib[2] = op;
|
|
|
|
mib[3] = arg;
|
2004-02-22 17:57:10 +00:00
|
|
|
temp_op = op & ~KERN_PROC_INC_THREAD;
|
|
|
|
st = sysctl(mib,
|
|
|
|
temp_op == KERN_PROC_ALL || temp_op == KERN_PROC_PROC ?
|
2003-09-27 08:14:37 +00:00
|
|
|
3 : 4, NULL, &size, NULL, 0);
|
1994-05-27 05:00:24 +00:00
|
|
|
if (st == -1) {
|
|
|
|
_kvm_syserr(kd, kd->program, "kvm_getprocs");
|
|
|
|
return (0);
|
|
|
|
}
|
2002-04-07 04:47:58 +00:00
|
|
|
/*
|
|
|
|
* We can't continue with a size of 0 because we pass
|
|
|
|
* it to realloc() (via _kvm_realloc()), and passing 0
|
|
|
|
* to realloc() results in undefined behavior.
|
|
|
|
*/
|
|
|
|
if (size == 0) {
|
|
|
|
/*
|
|
|
|
* XXX: We should probably return an invalid,
|
|
|
|
* but non-NULL, pointer here so any client
|
|
|
|
* program trying to dereference it will
|
|
|
|
* crash. However, _kvm_freeprocs() calls
|
|
|
|
* free() on kd->procbase if it isn't NULL,
|
|
|
|
* and free()'ing a junk pointer isn't good.
|
|
|
|
* Then again, _kvm_freeprocs() isn't used
|
|
|
|
* anywhere . . .
|
|
|
|
*/
|
|
|
|
kd->procbase = _kvm_malloc(kd, 1);
|
|
|
|
goto liveout;
|
|
|
|
}
|
1998-10-12 20:36:33 +00:00
|
|
|
do {
|
|
|
|
size += size / 10;
|
|
|
|
kd->procbase = (struct kinfo_proc *)
|
1998-12-16 18:31:51 +00:00
|
|
|
_kvm_realloc(kd, kd->procbase, size);
|
2016-04-22 18:05:34 +00:00
|
|
|
if (kd->procbase == NULL)
|
1998-10-12 20:36:33 +00:00
|
|
|
return (0);
|
2012-02-01 18:02:13 +00:00
|
|
|
osize = size;
|
2004-02-22 17:57:10 +00:00
|
|
|
st = sysctl(mib, temp_op == KERN_PROC_ALL ||
|
|
|
|
temp_op == KERN_PROC_PROC ? 3 : 4,
|
1998-12-16 18:31:51 +00:00
|
|
|
kd->procbase, &size, NULL, 0);
|
2012-02-01 18:02:13 +00:00
|
|
|
} while (st == -1 && errno == ENOMEM && size == osize);
|
1994-05-27 05:00:24 +00:00
|
|
|
if (st == -1) {
|
|
|
|
_kvm_syserr(kd, kd->program, "kvm_getprocs");
|
|
|
|
return (0);
|
|
|
|
}
|
2002-04-07 04:47:58 +00:00
|
|
|
/*
|
|
|
|
* We have to check the size again because sysctl()
|
|
|
|
* may "round up" oldlenp if oldp is NULL; hence it
|
|
|
|
* might've told us that there was data to get when
|
|
|
|
* there really isn't any.
|
|
|
|
*/
|
2001-05-01 10:34:15 +00:00
|
|
|
if (size > 0 &&
|
|
|
|
kd->procbase->ki_structsize != sizeof(struct kinfo_proc)) {
|
1994-05-27 05:00:24 +00:00
|
|
|
_kvm_err(kd, kd->program,
|
2011-01-23 11:08:28 +00:00
|
|
|
"kinfo_proc size mismatch (expected %zu, got %d)",
|
Change the proc information returned from the kernel so that it
no longer contains kernel specific data structures, but rather
only scalar values and structures that are already part of the
kernel/user interface, specifically rusage and rtprio. It no
longer contains proc, session, pcred, ucred, procsig, vmspace,
pstats, mtx, sigiolst, klist, callout, pasleep, or mdproc. If
any of these changed in size, ps, w, fstat, gcore, systat, and
top would all stop working. The new structure has over 200 bytes
of unassigned space for future values to be added, yet is nearly
100 bytes smaller per entry than the structure that it replaced.
2000-12-12 07:25:57 +00:00
|
|
|
sizeof(struct kinfo_proc),
|
|
|
|
kd->procbase->ki_structsize);
|
1994-05-27 05:00:24 +00:00
|
|
|
return (0);
|
|
|
|
}
|
2002-04-07 04:47:58 +00:00
|
|
|
liveout:
|
2001-05-03 11:26:46 +00:00
|
|
|
nprocs = size == 0 ? 0 : size / kd->procbase->ki_structsize;
|
1994-05-27 05:00:24 +00:00
|
|
|
} else {
|
2019-09-22 13:56:27 +00:00
|
|
|
struct nlist nl[6], *p;
|
|
|
|
struct nlist nlz[2];
|
1994-05-27 05:00:24 +00:00
|
|
|
|
|
|
|
nl[0].n_name = "_nprocs";
|
|
|
|
nl[1].n_name = "_allproc";
|
2019-09-22 13:56:27 +00:00
|
|
|
nl[2].n_name = "_ticks";
|
|
|
|
nl[3].n_name = "_hz";
|
|
|
|
nl[4].n_name = "_cpu_tick_frequency";
|
|
|
|
nl[5].n_name = 0;
|
|
|
|
|
|
|
|
nlz[0].n_name = "_zombproc";
|
|
|
|
nlz[1].n_name = 0;
|
1994-05-27 05:00:24 +00:00
|
|
|
|
2015-11-27 18:58:26 +00:00
|
|
|
if (!kd->arch->ka_native(kd)) {
|
|
|
|
_kvm_err(kd, kd->program,
|
|
|
|
"cannot read procs from non-native core");
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
1994-05-27 05:00:24 +00:00
|
|
|
if (kvm_nlist(kd, nl) != 0) {
|
|
|
|
for (p = nl; p->n_type != 0; ++p)
|
|
|
|
;
|
|
|
|
_kvm_err(kd, kd->program,
|
|
|
|
"%s: no such symbol", p->n_name);
|
|
|
|
return (0);
|
|
|
|
}
|
2019-09-22 13:56:27 +00:00
|
|
|
(void) kvm_nlist(kd, nlz); /* attempt to get zombproc */
|
1994-05-27 05:00:24 +00:00
|
|
|
if (KREAD(kd, nl[0].n_value, &nprocs)) {
|
|
|
|
_kvm_err(kd, kd->program, "can't read nprocs");
|
|
|
|
return (0);
|
|
|
|
}
|
2019-09-22 13:56:27 +00:00
|
|
|
/*
|
|
|
|
* If returning all threads, we don't know how many that
|
|
|
|
* might be. Presume that there are, on average, no more
|
|
|
|
* than 10 threads per process.
|
|
|
|
*/
|
|
|
|
if (op == KERN_PROC_ALL || (op & KERN_PROC_INC_THREAD))
|
|
|
|
nprocs *= 10; /* XXX */
|
|
|
|
if (KREAD(kd, nl[2].n_value, &ticks)) {
|
2007-09-21 04:11:34 +00:00
|
|
|
_kvm_err(kd, kd->program, "can't read ticks");
|
|
|
|
return (0);
|
|
|
|
}
|
2019-09-22 13:56:27 +00:00
|
|
|
if (KREAD(kd, nl[3].n_value, &hz)) {
|
2007-09-21 04:11:34 +00:00
|
|
|
_kvm_err(kd, kd->program, "can't read hz");
|
|
|
|
return (0);
|
|
|
|
}
|
2019-09-22 13:56:27 +00:00
|
|
|
if (KREAD(kd, nl[4].n_value, &cpu_tick_frequency)) {
|
2011-01-23 11:08:36 +00:00
|
|
|
_kvm_err(kd, kd->program,
|
|
|
|
"can't read cpu_tick_frequency");
|
|
|
|
return (0);
|
|
|
|
}
|
1994-05-27 05:00:24 +00:00
|
|
|
size = nprocs * sizeof(struct kinfo_proc);
|
|
|
|
kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size);
|
2016-04-22 18:05:34 +00:00
|
|
|
if (kd->procbase == NULL)
|
1994-05-27 05:00:24 +00:00
|
|
|
return (0);
|
|
|
|
|
|
|
|
nprocs = kvm_deadprocs(kd, op, arg, nl[1].n_value,
|
2019-09-22 13:56:27 +00:00
|
|
|
nlz[0].n_value, nprocs);
|
2012-10-06 20:16:04 +00:00
|
|
|
if (nprocs <= 0) {
|
|
|
|
_kvm_freeprocs(kd);
|
|
|
|
nprocs = 0;
|
|
|
|
}
|
1994-05-27 05:00:24 +00:00
|
|
|
#ifdef notdef
|
2012-10-06 20:16:04 +00:00
|
|
|
else {
|
|
|
|
size = nprocs * sizeof(struct kinfo_proc);
|
|
|
|
kd->procbase = realloc(kd->procbase, size);
|
|
|
|
}
|
1994-05-27 05:00:24 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
*cnt = nprocs;
|
|
|
|
return (kd->procbase);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2011-01-23 11:08:28 +00:00
|
|
|
_kvm_freeprocs(kvm_t *kd)
|
1994-05-27 05:00:24 +00:00
|
|
|
{
|
2016-04-22 18:05:34 +00:00
|
|
|
|
|
|
|
free(kd->procbase);
|
|
|
|
kd->procbase = NULL;
|
1994-05-27 05:00:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
2011-01-23 11:08:28 +00:00
|
|
|
_kvm_realloc(kvm_t *kd, void *p, size_t n)
|
1994-05-27 05:00:24 +00:00
|
|
|
{
|
2016-04-22 18:05:34 +00:00
|
|
|
void *np;
|
1994-05-27 05:00:24 +00:00
|
|
|
|
2016-04-22 18:05:34 +00:00
|
|
|
np = reallocf(p, n);
|
|
|
|
if (np == NULL)
|
1994-05-27 05:00:24 +00:00
|
|
|
_kvm_err(kd, kd->program, "out of memory");
|
|
|
|
return (np);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2011-11-22 21:12:28 +00:00
|
|
|
* Get the command args or environment.
|
1994-05-27 05:00:24 +00:00
|
|
|
*/
|
|
|
|
static char **
|
2011-11-22 21:12:28 +00:00
|
|
|
kvm_argv(kvm_t *kd, const struct kinfo_proc *kp, int env, int nchr)
|
1994-05-27 05:00:24 +00:00
|
|
|
{
|
1999-11-16 20:31:58 +00:00
|
|
|
int oid[4];
|
2000-03-27 00:33:45 +00:00
|
|
|
int i;
|
|
|
|
size_t bufsz;
|
2011-11-22 21:12:28 +00:00
|
|
|
static int buflen;
|
1999-11-16 20:31:58 +00:00
|
|
|
static char *buf, *p;
|
|
|
|
static char **bufp;
|
|
|
|
static int argc;
|
2016-04-30 09:13:26 +00:00
|
|
|
char **nbufp;
|
1999-11-16 20:31:58 +00:00
|
|
|
|
1999-12-27 07:14:58 +00:00
|
|
|
if (!ISALIVE(kd)) {
|
|
|
|
_kvm_err(kd, kd->program,
|
|
|
|
"cannot read user space from dead kernel");
|
2016-04-22 18:05:34 +00:00
|
|
|
return (NULL);
|
1999-12-27 07:14:58 +00:00
|
|
|
}
|
|
|
|
|
2011-11-22 21:12:28 +00:00
|
|
|
if (nchr == 0 || nchr > ARG_MAX)
|
|
|
|
nchr = ARG_MAX;
|
|
|
|
if (buflen == 0) {
|
|
|
|
buf = malloc(nchr);
|
|
|
|
if (buf == NULL) {
|
|
|
|
_kvm_err(kd, kd->program, "cannot allocate memory");
|
2016-04-22 18:05:34 +00:00
|
|
|
return (NULL);
|
2011-11-22 21:12:28 +00:00
|
|
|
}
|
|
|
|
argc = 32;
|
|
|
|
bufp = malloc(sizeof(char *) * argc);
|
2016-04-30 09:13:26 +00:00
|
|
|
if (bufp == NULL) {
|
|
|
|
free(buf);
|
|
|
|
buf = NULL;
|
|
|
|
_kvm_err(kd, kd->program, "cannot allocate memory");
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
buflen = nchr;
|
2011-11-22 21:12:28 +00:00
|
|
|
} else if (nchr > buflen) {
|
|
|
|
p = realloc(buf, nchr);
|
|
|
|
if (p != NULL) {
|
|
|
|
buf = p;
|
|
|
|
buflen = nchr;
|
1999-11-16 20:31:58 +00:00
|
|
|
}
|
|
|
|
}
|
2012-01-15 18:51:07 +00:00
|
|
|
oid[0] = CTL_KERN;
|
|
|
|
oid[1] = KERN_PROC;
|
|
|
|
oid[2] = env ? KERN_PROC_ENV : KERN_PROC_ARGS;
|
|
|
|
oid[3] = kp->ki_pid;
|
|
|
|
bufsz = buflen;
|
|
|
|
if (sysctl(oid, 4, buf, &bufsz, 0, 0) == -1) {
|
|
|
|
/*
|
|
|
|
* If the supplied buf is too short to hold the requested
|
|
|
|
* value the sysctl returns with ENOMEM. The buf is filled
|
|
|
|
* with the truncated value and the returned bufsz is equal
|
|
|
|
* to the requested len.
|
|
|
|
*/
|
|
|
|
if (errno != ENOMEM || bufsz != (size_t)buflen)
|
2016-04-22 18:05:34 +00:00
|
|
|
return (NULL);
|
2012-01-15 18:51:07 +00:00
|
|
|
buf[bufsz - 1] = '\0';
|
|
|
|
errno = 0;
|
2016-04-22 18:05:34 +00:00
|
|
|
} else if (bufsz == 0)
|
|
|
|
return (NULL);
|
2012-01-15 18:51:07 +00:00
|
|
|
i = 0;
|
|
|
|
p = buf;
|
|
|
|
do {
|
|
|
|
bufp[i++] = p;
|
|
|
|
p += strlen(p) + 1;
|
|
|
|
if (i >= argc) {
|
|
|
|
argc += argc;
|
2016-04-30 09:13:26 +00:00
|
|
|
nbufp = realloc(bufp, sizeof(char *) * argc);
|
|
|
|
if (nbufp == NULL)
|
|
|
|
return (NULL);
|
|
|
|
bufp = nbufp;
|
2012-01-15 18:51:07 +00:00
|
|
|
}
|
|
|
|
} while (p < buf + bufsz);
|
|
|
|
bufp[i++] = 0;
|
|
|
|
return (bufp);
|
1994-05-27 05:00:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char **
|
2011-11-22 21:12:28 +00:00
|
|
|
kvm_getargv(kvm_t *kd, const struct kinfo_proc *kp, int nchr)
|
1994-05-27 05:00:24 +00:00
|
|
|
{
|
2011-11-22 21:12:28 +00:00
|
|
|
return (kvm_argv(kd, kp, 0, nchr));
|
1994-05-27 05:00:24 +00:00
|
|
|
}
|
|
|
|
|
2011-11-22 21:12:28 +00:00
|
|
|
char **
|
|
|
|
kvm_getenvv(kvm_t *kd, const struct kinfo_proc *kp, int nchr)
|
1994-05-27 05:00:24 +00:00
|
|
|
{
|
2011-11-22 21:12:28 +00:00
|
|
|
return (kvm_argv(kd, kp, 1, nchr));
|
1994-05-27 05:00:24 +00:00
|
|
|
}
|