kern_proc.c (13154) | kern_proc.c (14529) |
---|---|
1/* 2 * Copyright (c) 1982, 1986, 1989, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * | 1/* 2 * Copyright (c) 1982, 1986, 1989, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * |
33 * @(#)kern_proc.c 8.4 (Berkeley) 1/4/94 34 * $Id: kern_proc.c,v 1.14 1995/12/14 08:31:30 phk Exp $ | 33 * @(#)kern_proc.c 8.7 (Berkeley) 2/14/95 34 * $Id: kern_proc.c,v 1.15 1996/01/01 17:01:03 peter Exp $ |
35 */ 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/kernel.h> 40#include <sys/sysctl.h> 41#include <sys/proc.h> 42#include <sys/buf.h> --- 14 unchanged lines hidden (view full) --- 57#include <vm/pmap.h> 58#include <vm/vm_map.h> 59#include <sys/user.h> 60 61struct prochd qs[NQS]; /* as good a place as any... */ 62struct prochd rtqs[NQS]; /* Space for REALTIME queues too */ 63struct prochd idqs[NQS]; /* Space for IDLE queues too */ 64 | 35 */ 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/kernel.h> 40#include <sys/sysctl.h> 41#include <sys/proc.h> 42#include <sys/buf.h> --- 14 unchanged lines hidden (view full) --- 57#include <vm/pmap.h> 58#include <vm/vm_map.h> 59#include <sys/user.h> 60 61struct prochd qs[NQS]; /* as good a place as any... */ 62struct prochd rtqs[NQS]; /* Space for REALTIME queues too */ 63struct prochd idqs[NQS]; /* Space for IDLE queues too */ 64 |
65volatile struct proc *allproc; /* all processes */ 66struct proc *zombproc; /* just zombies */ 67 | |
68static void pgdelete __P((struct pgrp *)); 69 70/* 71 * Structure associated with user cacheing. 72 */ | 65static void pgdelete __P((struct pgrp *)); 66 67/* 68 * Structure associated with user cacheing. 69 */ |
73static struct uidinfo { 74 struct uidinfo *ui_next; 75 struct uidinfo **ui_prev; | 70struct uidinfo { 71 LIST_ENTRY(uidinfo) ui_hash; |
76 uid_t ui_uid; 77 long ui_proccnt; | 72 uid_t ui_uid; 73 long ui_proccnt; |
78} **uihashtbl; 79static u_long uihash; /* size of hash table - 1 */ 80#define UIHASH(uid) ((uid) & uihash) | 74}; 75#define UIHASH(uid) (&uihashtbl[(uid) & uihash]) 76LIST_HEAD(uihashhead, uidinfo) *uihashtbl; 77static u_long uihash; /* size of hash table - 1 */ |
81 82static void orphanpg __P((struct pgrp *pg)); 83 84/* | 78 79static void orphanpg __P((struct pgrp *pg)); 80 81/* |
85 * Allocate a hash table. | 82 * Other process lists |
86 */ | 83 */ |
84struct pidhashhead *pidhashtbl; 85u_long pidhash; 86struct pgrphashhead *pgrphashtbl; 87u_long pgrphash; 88struct proclist allproc; 89struct proclist zombproc; 90 91/* 92 * Initialize global process hashing structures. 93 */ |
|
87void | 94void |
88usrinfoinit() | 95procinit() |
89{ 90 | 96{ 97 |
98 LIST_INIT(&allproc); 99 LIST_INIT(&zombproc); 100 pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash); 101 pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash); |
|
91 uihashtbl = hashinit(maxproc / 16, M_PROC, &uihash); 92} 93 94/* 95 * Change the count associated with number of processes 96 * a given user is using. 97 */ 98int 99chgproccnt(uid, diff) 100 uid_t uid; 101 int diff; 102{ | 102 uihashtbl = hashinit(maxproc / 16, M_PROC, &uihash); 103} 104 105/* 106 * Change the count associated with number of processes 107 * a given user is using. 108 */ 109int 110chgproccnt(uid, diff) 111 uid_t uid; 112 int diff; 113{ |
103 register struct uidinfo **uipp, *uip, *uiq; | 114 register struct uidinfo *uip; 115 register struct uihashhead *uipp; |
104 | 116 |
105 uipp = &uihashtbl[UIHASH(uid)]; 106 for (uip = *uipp; uip; uip = uip->ui_next) | 117 uipp = UIHASH(uid); 118 for (uip = uipp->lh_first; uip != 0; uip = uip->ui_hash.le_next) |
107 if (uip->ui_uid == uid) 108 break; 109 if (uip) { 110 uip->ui_proccnt += diff; 111 if (uip->ui_proccnt > 0) 112 return (uip->ui_proccnt); 113 if (uip->ui_proccnt < 0) 114 panic("chgproccnt: procs < 0"); | 119 if (uip->ui_uid == uid) 120 break; 121 if (uip) { 122 uip->ui_proccnt += diff; 123 if (uip->ui_proccnt > 0) 124 return (uip->ui_proccnt); 125 if (uip->ui_proccnt < 0) 126 panic("chgproccnt: procs < 0"); |
115 if ((uiq = uip->ui_next)) 116 uiq->ui_prev = uip->ui_prev; 117 *uip->ui_prev = uiq; | 127 LIST_REMOVE(uip, ui_hash); |
118 FREE(uip, M_PROC); 119 return (0); 120 } 121 if (diff <= 0) { 122 if (diff == 0) 123 return(0); 124 panic("chgproccnt: lost user"); 125 } 126 MALLOC(uip, struct uidinfo *, sizeof(*uip), M_PROC, M_WAITOK); | 128 FREE(uip, M_PROC); 129 return (0); 130 } 131 if (diff <= 0) { 132 if (diff == 0) 133 return(0); 134 panic("chgproccnt: lost user"); 135 } 136 MALLOC(uip, struct uidinfo *, sizeof(*uip), M_PROC, M_WAITOK); |
127 if ((uiq = *uipp)) 128 uiq->ui_prev = &uip->ui_next; 129 uip->ui_next = uiq; 130 uip->ui_prev = uipp; 131 *uipp = uip; | 137 LIST_INSERT_HEAD(uipp, uip, ui_hash); |
132 uip->ui_uid = uid; 133 uip->ui_proccnt = diff; 134 return (diff); 135} 136 137/* 138 * Is p an inferior of the current process? 139 */ --- 12 unchanged lines hidden (view full) --- 152 * Locate a process by number 153 */ 154struct proc * 155pfind(pid) 156 register pid_t pid; 157{ 158 register struct proc *p; 159 | 138 uip->ui_uid = uid; 139 uip->ui_proccnt = diff; 140 return (diff); 141} 142 143/* 144 * Is p an inferior of the current process? 145 */ --- 12 unchanged lines hidden (view full) --- 158 * Locate a process by number 159 */ 160struct proc * 161pfind(pid) 162 register pid_t pid; 163{ 164 register struct proc *p; 165 |
160 for (p = pidhash[PIDHASH(pid)]; p != NULL; p = p->p_hash) | 166 for (p = PIDHASH(pid)->lh_first; p != 0; p = p->p_hash.le_next) |
161 if (p->p_pid == pid) 162 return (p); 163 return (NULL); 164} 165 166/* 167 * Locate a process group by number 168 */ 169struct pgrp * 170pgfind(pgid) 171 register pid_t pgid; 172{ 173 register struct pgrp *pgrp; 174 | 167 if (p->p_pid == pid) 168 return (p); 169 return (NULL); 170} 171 172/* 173 * Locate a process group by number 174 */ 175struct pgrp * 176pgfind(pgid) 177 register pid_t pgid; 178{ 179 register struct pgrp *pgrp; 180 |
175 for (pgrp = pgrphash[PIDHASH(pgid)]; 176 pgrp != NULL; pgrp = pgrp->pg_hforw) | 181 for (pgrp = PGRPHASH(pgid)->lh_first; pgrp != 0; 182 pgrp = pgrp->pg_hash.le_next) |
177 if (pgrp->pg_id == pgid) 178 return (pgrp); 179 return (NULL); 180} 181 182/* 183 * Move p to a new or existing process group (and session) 184 */ 185int 186enterpgrp(p, pgid, mksess) 187 register struct proc *p; 188 pid_t pgid; 189 int mksess; 190{ 191 register struct pgrp *pgrp = pgfind(pgid); | 183 if (pgrp->pg_id == pgid) 184 return (pgrp); 185 return (NULL); 186} 187 188/* 189 * Move p to a new or existing process group (and session) 190 */ 191int 192enterpgrp(p, pgid, mksess) 193 register struct proc *p; 194 pid_t pgid; 195 int mksess; 196{ 197 register struct pgrp *pgrp = pgfind(pgid); |
192 register struct proc **pp; 193 int n; | |
194 195#ifdef DIAGNOSTIC 196 if (pgrp != NULL && mksess) /* firewalls */ 197 panic("enterpgrp: setsid into non-empty pgrp"); 198 if (SESS_LEADER(p)) 199 panic("enterpgrp: session leader attempted setpgrp"); 200#endif 201 if (pgrp == NULL) { 202 pid_t savepid = p->p_pid; 203 struct proc *np; 204 /* 205 * new process group 206 */ 207#ifdef DIAGNOSTIC 208 if (p->p_pid != pgid) 209 panic("enterpgrp: new pgrp and pid != pgid"); 210#endif 211 MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, | 198 199#ifdef DIAGNOSTIC 200 if (pgrp != NULL && mksess) /* firewalls */ 201 panic("enterpgrp: setsid into non-empty pgrp"); 202 if (SESS_LEADER(p)) 203 panic("enterpgrp: session leader attempted setpgrp"); 204#endif 205 if (pgrp == NULL) { 206 pid_t savepid = p->p_pid; 207 struct proc *np; 208 /* 209 * new process group 210 */ 211#ifdef DIAGNOSTIC 212 if (p->p_pid != pgid) 213 panic("enterpgrp: new pgrp and pid != pgid"); 214#endif 215 MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, |
212 M_WAITOK); | 216 M_WAITOK); |
213 if ((np = pfind(savepid)) == NULL || np != p) 214 return (ESRCH); 215 if (mksess) { 216 register struct session *sess; 217 218 /* 219 * new session 220 */ 221 MALLOC(sess, struct session *, sizeof(struct session), | 217 if ((np = pfind(savepid)) == NULL || np != p) 218 return (ESRCH); 219 if (mksess) { 220 register struct session *sess; 221 222 /* 223 * new session 224 */ 225 MALLOC(sess, struct session *, sizeof(struct session), |
222 M_SESSION, M_WAITOK); | 226 M_SESSION, M_WAITOK); |
223 sess->s_leader = p; 224 sess->s_count = 1; 225 sess->s_ttyvp = NULL; 226 sess->s_ttyp = NULL; 227 bcopy(p->p_session->s_login, sess->s_login, 228 sizeof(sess->s_login)); 229 p->p_flag &= ~P_CONTROLT; 230 pgrp->pg_session = sess; 231#ifdef DIAGNOSTIC 232 if (p != curproc) 233 panic("enterpgrp: mksession and p != curproc"); 234#endif 235 } else { 236 pgrp->pg_session = p->p_session; 237 pgrp->pg_session->s_count++; 238 } 239 pgrp->pg_id = pgid; | 227 sess->s_leader = p; 228 sess->s_count = 1; 229 sess->s_ttyvp = NULL; 230 sess->s_ttyp = NULL; 231 bcopy(p->p_session->s_login, sess->s_login, 232 sizeof(sess->s_login)); 233 p->p_flag &= ~P_CONTROLT; 234 pgrp->pg_session = sess; 235#ifdef DIAGNOSTIC 236 if (p != curproc) 237 panic("enterpgrp: mksession and p != curproc"); 238#endif 239 } else { 240 pgrp->pg_session = p->p_session; 241 pgrp->pg_session->s_count++; 242 } 243 pgrp->pg_id = pgid; |
240 pgrp->pg_hforw = pgrphash[n = PIDHASH(pgid)]; 241 pgrphash[n] = pgrp; | 244 LIST_INIT(&pgrp->pg_members); 245 LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash); |
242 pgrp->pg_jobc = 0; | 246 pgrp->pg_jobc = 0; |
243 pgrp->pg_mem = NULL; | |
244 } else if (pgrp == p->p_pgrp) 245 return (0); 246 247 /* 248 * Adjust eligibility of affected pgrps to participate in job control. 249 * Increment eligibility counts before decrementing, otherwise we 250 * could reach 0 spuriously during the first call. 251 */ 252 fixjobc(p, pgrp, 1); 253 fixjobc(p, p->p_pgrp, 0); 254 | 247 } else if (pgrp == p->p_pgrp) 248 return (0); 249 250 /* 251 * Adjust eligibility of affected pgrps to participate in job control. 252 * Increment eligibility counts before decrementing, otherwise we 253 * could reach 0 spuriously during the first call. 254 */ 255 fixjobc(p, pgrp, 1); 256 fixjobc(p, p->p_pgrp, 0); 257 |
255 /* 256 * unlink p from old process group 257 */ 258 for (pp = &p->p_pgrp->pg_mem; *pp; pp = &(*pp)->p_pgrpnxt) { 259 if (*pp == p) { 260 *pp = p->p_pgrpnxt; 261 break; 262 } 263 } 264#ifdef DIAGNOSTIC 265 if (pp == NULL) 266 panic("enterpgrp: can't find p on old pgrp"); 267#endif 268 /* 269 * delete old if empty 270 */ 271 if (p->p_pgrp->pg_mem == 0) | 258 LIST_REMOVE(p, p_pglist); 259 if (p->p_pgrp->pg_members.lh_first == 0) |
272 pgdelete(p->p_pgrp); | 260 pgdelete(p->p_pgrp); |
273 /* 274 * link into new one 275 */ | |
276 p->p_pgrp = pgrp; | 261 p->p_pgrp = pgrp; |
277 p->p_pgrpnxt = pgrp->pg_mem; 278 pgrp->pg_mem = p; | 262 LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist); |
279 return (0); 280} 281 282/* 283 * remove process from process group 284 */ 285int 286leavepgrp(p) 287 register struct proc *p; 288{ | 263 return (0); 264} 265 266/* 267 * remove process from process group 268 */ 269int 270leavepgrp(p) 271 register struct proc *p; 272{ |
289 register struct proc **pp = &p->p_pgrp->pg_mem; | |
290 | 273 |
291 for (; *pp; pp = &(*pp)->p_pgrpnxt) { 292 if (*pp == p) { 293 *pp = p->p_pgrpnxt; 294 break; 295 } 296 } 297#ifdef DIAGNOSTIC 298 if (pp == NULL) 299 panic("leavepgrp: can't find p in pgrp"); 300#endif 301 if (!p->p_pgrp->pg_mem) | 274 LIST_REMOVE(p, p_pglist); 275 if (p->p_pgrp->pg_members.lh_first == 0) |
302 pgdelete(p->p_pgrp); 303 p->p_pgrp = 0; 304 return (0); 305} 306 307/* 308 * delete a process group 309 */ 310static void 311pgdelete(pgrp) 312 register struct pgrp *pgrp; 313{ | 276 pgdelete(p->p_pgrp); 277 p->p_pgrp = 0; 278 return (0); 279} 280 281/* 282 * delete a process group 283 */ 284static void 285pgdelete(pgrp) 286 register struct pgrp *pgrp; 287{ |
314 register struct pgrp **pgp = &pgrphash[PIDHASH(pgrp->pg_id)]; | |
315 316 if (pgrp->pg_session->s_ttyp != NULL && 317 pgrp->pg_session->s_ttyp->t_pgrp == pgrp) 318 pgrp->pg_session->s_ttyp->t_pgrp = NULL; | 288 289 if (pgrp->pg_session->s_ttyp != NULL && 290 pgrp->pg_session->s_ttyp->t_pgrp == pgrp) 291 pgrp->pg_session->s_ttyp->t_pgrp = NULL; |
319 for (; *pgp; pgp = &(*pgp)->pg_hforw) { 320 if (*pgp == pgrp) { 321 *pgp = pgrp->pg_hforw; 322 break; 323 } 324 } 325#ifdef DIAGNOSTIC 326 if (pgp == NULL) 327 panic("pgdelete: can't find pgrp on hash chain"); 328#endif | 292 LIST_REMOVE(pgrp, pg_hash); |
329 if (--pgrp->pg_session->s_count == 0) 330 FREE(pgrp->pg_session, M_SESSION); 331 FREE(pgrp, M_PGRP); 332} 333 334/* 335 * Adjust pgrp jobc counters when specified process changes process group. 336 * We count the number of processes in each process group that "qualify" --- 24 unchanged lines hidden (view full) --- 361 else if (--pgrp->pg_jobc == 0) 362 orphanpg(pgrp); 363 364 /* 365 * Check this process' children to see whether they qualify 366 * their process groups; if so, adjust counts for children's 367 * process groups. 368 */ | 293 if (--pgrp->pg_session->s_count == 0) 294 FREE(pgrp->pg_session, M_SESSION); 295 FREE(pgrp, M_PGRP); 296} 297 298/* 299 * Adjust pgrp jobc counters when specified process changes process group. 300 * We count the number of processes in each process group that "qualify" --- 24 unchanged lines hidden (view full) --- 325 else if (--pgrp->pg_jobc == 0) 326 orphanpg(pgrp); 327 328 /* 329 * Check this process' children to see whether they qualify 330 * their process groups; if so, adjust counts for children's 331 * process groups. 332 */ |
369 for (p = p->p_cptr; p; p = p->p_osptr) | 333 for (p = p->p_children.lh_first; p != 0; p = p->p_sibling.le_next) |
370 if ((hispgrp = p->p_pgrp) != pgrp && 371 hispgrp->pg_session == mysession && 372 p->p_stat != SZOMB) 373 if (entering) 374 hispgrp->pg_jobc++; 375 else if (--hispgrp->pg_jobc == 0) 376 orphanpg(hispgrp); 377} --- 4 unchanged lines hidden (view full) --- 382 * hang-up all process in that group. 383 */ 384static void 385orphanpg(pg) 386 struct pgrp *pg; 387{ 388 register struct proc *p; 389 | 334 if ((hispgrp = p->p_pgrp) != pgrp && 335 hispgrp->pg_session == mysession && 336 p->p_stat != SZOMB) 337 if (entering) 338 hispgrp->pg_jobc++; 339 else if (--hispgrp->pg_jobc == 0) 340 orphanpg(hispgrp); 341} --- 4 unchanged lines hidden (view full) --- 346 * hang-up all process in that group. 347 */ 348static void 349orphanpg(pg) 350 struct pgrp *pg; 351{ 352 register struct proc *p; 353 |
390 for (p = pg->pg_mem; p; p = p->p_pgrpnxt) { | 354 for (p = pg->pg_members.lh_first; p != 0; p = p->p_pglist.le_next) { |
391 if (p->p_stat == SSTOP) { | 355 if (p->p_stat == SSTOP) { |
392 for (p = pg->pg_mem; p; p = p->p_pgrpnxt) { | 356 for (p = pg->pg_members.lh_first; p != 0; 357 p = p->p_pglist.le_next) { |
393 psignal(p, SIGHUP); 394 psignal(p, SIGCONT); 395 } 396 return; 397 } 398 } 399} 400 | 358 psignal(p, SIGHUP); 359 psignal(p, SIGCONT); 360 } 361 return; 362 } 363 } 364} 365 |
401#ifdef debug 402/* DEBUG */ | 366#ifdef DEBUG |
403pgrpdump() 404{ 405 register struct pgrp *pgrp; 406 register struct proc *p; 407 register i; 408 | 367pgrpdump() 368{ 369 register struct pgrp *pgrp; 370 register struct proc *p; 371 register i; 372 |
409 for (i=0; i<PIDHSZ; i++) { 410 if (pgrphash[i]) { 411 printf("\tindx %d\n", i); 412 for (pgrp=pgrphash[i]; pgrp; pgrp=pgrp->pg_hforw) { 413 printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n", 414 pgrp, pgrp->pg_id, pgrp->pg_session, 415 pgrp->pg_session->s_count, pgrp->pg_mem); 416 for (p=pgrp->pg_mem; p; p=p->p_pgrpnxt) { 417 printf("\t\tpid %d addr %x pgrp %x\n", 418 p->p_pid, p, p->p_pgrp); 419 } 420 } 421 | 373 for (i = 0; i <= pgrphash; i++) { 374 if (pgrp = pgrphashtbl[i].lh_first) { 375 printf("\tindx %d\n", i); 376 for (; pgrp != 0; pgrp = pgrp->pg_hash.le_next) { 377 printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n", 378 pgrp, pgrp->pg_id, pgrp->pg_session, 379 pgrp->pg_session->s_count, 380 pgrp->pg_members.lh_first); 381 for (p = pgrp->pg_members.lh_first; p != 0; 382 p = p->p_pglist.le_next) { 383 printf("\t\tpid %d addr %x pgrp %x\n", 384 p->p_pid, p, p->p_pgrp); 385 } 386 } |
422 } 423 } 424} | 387 } 388 } 389} |
425#endif /* debug */ | 390#endif /* DEBUG */ |
426 427/* 428 * Fill in an eproc structure for the specified process. 429 */ 430void 431fill_eproc(p, ep) 432 register struct proc *p; 433 register struct eproc *ep; --- 65 unchanged lines hidden (view full) --- 499 if (!req->oldptr) { 500 /* 501 * try over estimating by 5 procs 502 */ 503 error = SYSCTL_OUT(req, 0, sizeof (struct kinfo_proc) * 5); 504 if (error) 505 return (error); 506 } | 391 392/* 393 * Fill in an eproc structure for the specified process. 394 */ 395void 396fill_eproc(p, ep) 397 register struct proc *p; 398 register struct eproc *ep; --- 65 unchanged lines hidden (view full) --- 464 if (!req->oldptr) { 465 /* 466 * try over estimating by 5 procs 467 */ 468 error = SYSCTL_OUT(req, 0, sizeof (struct kinfo_proc) * 5); 469 if (error) 470 return (error); 471 } |
507 p = (struct proc *)allproc; | 472 p = allproc.lh_first; |
508 doingzomb = 0; 509again: | 473 doingzomb = 0; 474again: |
510 for (; p != NULL; p = p->p_next) { | 475 for (; p != 0; p = p->p_list.le_next) { |
511 /* 512 * Skip embryonic processes. 513 */ 514 if (p->p_stat == SIDL) 515 continue; 516 /* 517 * TODO - make more efficient (see notes below). 518 * do by session. --- 35 unchanged lines hidden (view full) --- 554 error = SYSCTL_OUT(req,(caddr_t)p, sizeof(struct proc)); 555 if (error) 556 return (error); 557 error = SYSCTL_OUT(req,(caddr_t)&eproc, sizeof(eproc)); 558 if (error) 559 return (error); 560 } 561 if (doingzomb == 0) { | 476 /* 477 * Skip embryonic processes. 478 */ 479 if (p->p_stat == SIDL) 480 continue; 481 /* 482 * TODO - make more efficient (see notes below). 483 * do by session. --- 35 unchanged lines hidden (view full) --- 519 error = SYSCTL_OUT(req,(caddr_t)p, sizeof(struct proc)); 520 if (error) 521 return (error); 522 error = SYSCTL_OUT(req,(caddr_t)&eproc, sizeof(eproc)); 523 if (error) 524 return (error); 525 } 526 if (doingzomb == 0) { |
562 p = zombproc; | 527 p = zombproc.lh_first; |
563 doingzomb++; 564 goto again; 565 } 566 return (0); 567} 568 569SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD, 570 sysctl_kern_proc, "Process table"); | 528 doingzomb++; 529 goto again; 530 } 531 return (0); 532} 533 534SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD, 535 sysctl_kern_proc, "Process table"); |