The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/kern_proc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by the University of
   16  *      California, Berkeley and its contributors.
   17  * 4. Neither the name of the University nor the names of its contributors
   18  *    may be used to endorse or promote products derived from this software
   19  *    without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   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.7 (Berkeley) 2/14/95
   34  * $FreeBSD: src/sys/kern/kern_proc.c,v 1.22.2.2 1999/09/05 08:15:00 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>
   43 #include <sys/acct.h>
   44 #include <sys/wait.h>
   45 #include <sys/file.h>
   46 #include <ufs/ufs/quota.h>
   47 #include <sys/uio.h>
   48 #include <sys/malloc.h>
   49 #include <sys/mbuf.h>
   50 #include <sys/ioctl.h>
   51 #include <sys/tty.h>
   52 #include <sys/signalvar.h>
   53 #include <vm/vm.h>
   54 #include <vm/vm_param.h>
   55 #include <vm/vm_prot.h>
   56 #include <vm/lock.h>
   57 #include <vm/pmap.h>
   58 #include <vm/vm_map.h>
   59 #include <sys/user.h>
   60 
   61 struct prochd qs[NQS];          /* as good a place as any... */
   62 struct prochd rtqs[NQS];        /* Space for REALTIME queues too */
   63 struct prochd idqs[NQS];        /* Space for IDLE queues too */
   64 
   65 static void pgdelete    __P((struct pgrp *));
   66 
   67 /*
   68  * Structure associated with user cacheing.
   69  */
   70 struct uidinfo {
   71         LIST_ENTRY(uidinfo) ui_hash;
   72         uid_t   ui_uid;
   73         long    ui_proccnt;
   74 };
   75 #define UIHASH(uid)     (&uihashtbl[(uid) & uihash])
   76 LIST_HEAD(uihashhead, uidinfo) *uihashtbl;
   77 static u_long uihash;           /* size of hash table - 1 */
   78 
   79 static void     orphanpg __P((struct pgrp *pg));
   80 
   81 /*
   82  * Other process lists
   83  */
   84 struct pidhashhead *pidhashtbl;
   85 u_long pidhash;
   86 struct pgrphashhead *pgrphashtbl;
   87 u_long pgrphash;
   88 struct proclist allproc;
   89 struct proclist zombproc;
   90 
   91 /*
   92  * Initialize global process hashing structures.
   93  */
   94 void
   95 procinit()
   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);
  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  */
  109 int
  110 chgproccnt(uid, diff)
  111         uid_t   uid;
  112         int     diff;
  113 {
  114         register struct uidinfo *uip;
  115         register struct uihashhead *uipp;
  116 
  117         uipp = UIHASH(uid);
  118         for (uip = uipp->lh_first; uip != 0; uip = uip->ui_hash.le_next)
  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");
  127                 LIST_REMOVE(uip, ui_hash);
  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);
  137         LIST_INSERT_HEAD(uipp, uip, ui_hash);
  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  */
  146 int
  147 inferior(p)
  148         register struct proc *p;
  149 {
  150 
  151         for (; p != curproc; p = p->p_pptr)
  152                 if (p->p_pid == 0)
  153                         return (0);
  154         return (1);
  155 }
  156 
  157 /*
  158  * Locate a process by number
  159  */
  160 struct proc *
  161 pfind(pid)
  162         register pid_t pid;
  163 {
  164         register struct proc *p;
  165 
  166         for (p = PIDHASH(pid)->lh_first; p != 0; p = p->p_hash.le_next)
  167                 if (p->p_pid == pid)
  168                         return (p);
  169         return (NULL);
  170 }
  171 
  172 /*
  173  * Locate a process group by number
  174  */
  175 struct pgrp *
  176 pgfind(pgid)
  177         register pid_t pgid;
  178 {
  179         register struct pgrp *pgrp;
  180 
  181         for (pgrp = PGRPHASH(pgid)->lh_first; pgrp != 0;
  182              pgrp = pgrp->pg_hash.le_next)
  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  */
  191 int
  192 enterpgrp(p, pgid, mksess)
  193         register struct proc *p;
  194         pid_t pgid;
  195         int mksess;
  196 {
  197         register struct pgrp *pgrp = pgfind(pgid);
  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,
  216                     M_WAITOK);
  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),
  226                             M_SESSION, M_WAITOK);
  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;
  244                 LIST_INIT(&pgrp->pg_members);
  245                 LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash);
  246                 pgrp->pg_jobc = 0;
  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 
  258         LIST_REMOVE(p, p_pglist);
  259         if (p->p_pgrp->pg_members.lh_first == 0)
  260                 pgdelete(p->p_pgrp);
  261         p->p_pgrp = pgrp;
  262         LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist);
  263         return (0);
  264 }
  265 
  266 /*
  267  * remove process from process group
  268  */
  269 int
  270 leavepgrp(p)
  271         register struct proc *p;
  272 {
  273 
  274         LIST_REMOVE(p, p_pglist);
  275         if (p->p_pgrp->pg_members.lh_first == 0)
  276                 pgdelete(p->p_pgrp);
  277         p->p_pgrp = 0;
  278         return (0);
  279 }
  280 
  281 /*
  282  * delete a process group
  283  */
  284 static void
  285 pgdelete(pgrp)
  286         register struct pgrp *pgrp;
  287 {
  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;
  292         LIST_REMOVE(pgrp, pg_hash);
  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"
  301  * the group for terminal job control (those with a parent in a different
  302  * process group of the same session).  If that count reaches zero, the
  303  * process group becomes orphaned.  Check both the specified process'
  304  * process group and that of its children.
  305  * entering == 0 => p is leaving specified group.
  306  * entering == 1 => p is entering specified group.
  307  */
  308 void
  309 fixjobc(p, pgrp, entering)
  310         register struct proc *p;
  311         register struct pgrp *pgrp;
  312         int entering;
  313 {
  314         register struct pgrp *hispgrp;
  315         register struct session *mysession = pgrp->pg_session;
  316 
  317         /*
  318          * Check p's parent to see whether p qualifies its own process
  319          * group; if so, adjust count for p's process group.
  320          */
  321         if ((hispgrp = p->p_pptr->p_pgrp) != pgrp &&
  322             hispgrp->pg_session == mysession)
  323                 if (entering)
  324                         pgrp->pg_jobc++;
  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          */
  333         for (p = p->p_children.lh_first; p != 0; p = p->p_sibling.le_next)
  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 }
  342 
  343 /*
  344  * A process group has become orphaned;
  345  * if there are any stopped processes in the group,
  346  * hang-up all process in that group.
  347  */
  348 static void
  349 orphanpg(pg)
  350         struct pgrp *pg;
  351 {
  352         register struct proc *p;
  353 
  354         for (p = pg->pg_members.lh_first; p != 0; p = p->p_pglist.le_next) {
  355                 if (p->p_stat == SSTOP) {
  356                         for (p = pg->pg_members.lh_first; p != 0;
  357                             p = p->p_pglist.le_next) {
  358                                 psignal(p, SIGHUP);
  359                                 psignal(p, SIGCONT);
  360                         }
  361                         return;
  362                 }
  363         }
  364 }
  365 
  366 #include "opt_ddb.h"
  367 #ifdef DDB
  368 #include <ddb/ddb.h>
  369 
  370 DB_SHOW_COMMAND(pgrpdump, pgrpdump)
  371 {
  372         register struct pgrp *pgrp;
  373         register struct proc *p;
  374         register i;
  375 
  376         for (i = 0; i <= pgrphash; i++) {
  377                 if (pgrp = pgrphashtbl[i].lh_first) {
  378                         printf("\tindx %d\n", i);
  379                         for (; pgrp != 0; pgrp = pgrp->pg_hash.le_next) {
  380                                 printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n",
  381                                     pgrp, pgrp->pg_id, pgrp->pg_session,
  382                                     pgrp->pg_session->s_count,
  383                                     pgrp->pg_members.lh_first);
  384                                 for (p = pgrp->pg_members.lh_first; p != 0;
  385                                     p = p->p_pglist.le_next) {
  386                                         printf("\t\tpid %d addr %x pgrp %x\n", 
  387                                             p->p_pid, p, p->p_pgrp);
  388                                 }
  389                         }
  390                 }
  391         }
  392 }
  393 #endif /* DDB */
  394 
  395 /*
  396  * Fill in an eproc structure for the specified process.
  397  */
  398 void
  399 fill_eproc(p, ep)
  400         register struct proc *p;
  401         register struct eproc *ep;
  402 {
  403         register struct tty *tp;
  404 
  405         bzero(ep, sizeof(*ep));
  406 
  407         ep->e_paddr = p;
  408         if (p->p_cred) {
  409                 ep->e_pcred = *p->p_cred;
  410                 if (p->p_ucred)
  411                         ep->e_ucred = *p->p_ucred;
  412         }
  413         if (p->p_stat != SIDL && p->p_stat != SZOMB && p->p_vmspace != NULL) {
  414                 register struct vmspace *vm = p->p_vmspace;
  415 
  416 #ifdef pmap_resident_count
  417                 ep->e_vm.vm_rssize = pmap_resident_count(&vm->vm_pmap); /*XXX*/
  418 #else
  419                 ep->e_vm.vm_rssize = vm->vm_rssize;
  420 #endif
  421                 ep->e_vm.vm_tsize = vm->vm_tsize;
  422                 ep->e_vm.vm_dsize = vm->vm_dsize;
  423                 ep->e_vm.vm_ssize = vm->vm_ssize;
  424                 ep->e_vm.vm_taddr = vm->vm_taddr;
  425                 ep->e_vm.vm_daddr = vm->vm_daddr;
  426                 ep->e_vm.vm_minsaddr = vm->vm_minsaddr;
  427                 ep->e_vm.vm_maxsaddr = vm->vm_maxsaddr;
  428 #ifndef sparc
  429                 ep->e_vm.vm_pmap = vm->vm_pmap;
  430 #endif
  431         }
  432         if (p->p_pptr)
  433                 ep->e_ppid = p->p_pptr->p_pid;
  434         if (p->p_pgrp) {
  435                 ep->e_pgid = p->p_pgrp->pg_id;
  436                 ep->e_jobc = p->p_pgrp->pg_jobc;
  437                 ep->e_sess = p->p_pgrp->pg_session;
  438 
  439                 if (ep->e_sess) {
  440                         bcopy(ep->e_sess->s_login, ep->e_login, sizeof(ep->e_login));
  441                         if (ep->e_sess->s_ttyvp)
  442                                 ep->e_flag = EPROC_CTTY;
  443                         if (p->p_session && SESS_LEADER(p))
  444                                 ep->e_flag |= EPROC_SLEADER;
  445                 }
  446         }
  447         if ((p->p_flag & P_CONTROLT) &&
  448             (ep->e_sess != NULL) &&
  449             ((tp = ep->e_sess->s_ttyp) != NULL)) {
  450                 ep->e_tdev = tp->t_dev;
  451                 ep->e_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
  452                 ep->e_tsess = tp->t_session;
  453         } else
  454                 ep->e_tdev = NODEV;
  455         if (p->p_wmesg) {
  456                 strncpy(ep->e_wmesg, p->p_wmesg, WMESGLEN);
  457                 ep->e_wmesg[WMESGLEN] = 0;
  458         }
  459 }
  460 
  461 static struct proc *
  462 zpfind(pid_t pid)
  463 {
  464         struct proc *p;
  465 
  466         for (p = zombproc.lh_first; p != 0; p = p->p_list.le_next)
  467                 if (p->p_pid == pid)
  468                         return (p);
  469         return (NULL);
  470 }
  471 
  472 
  473 static int
  474 sysctl_out_proc(struct proc *p, struct sysctl_req *req, int doingzomb)
  475 {
  476         struct eproc eproc;
  477         int error;
  478         pid_t pid = p->p_pid;
  479 
  480         fill_eproc(p, &eproc);
  481         error = SYSCTL_OUT(req,(caddr_t)p, sizeof(struct proc));
  482         if (error)
  483                 return (error);
  484         error = SYSCTL_OUT(req,(caddr_t)&eproc, sizeof(eproc));
  485         if (error)
  486                 return (error);
  487         if (!doingzomb && pid && (pfind(pid) != p))
  488                 return EAGAIN;
  489         if (doingzomb && zpfind(pid) != p)
  490                 return EAGAIN;
  491         return (0);
  492 }
  493 
  494 static int
  495 sysctl_kern_proc SYSCTL_HANDLER_ARGS
  496 {
  497         int *name = (int*) arg1;
  498         u_int namelen = arg2;
  499         struct proc *p;
  500         int doingzomb;
  501         int error = 0;
  502 
  503         if (oidp->oid_number == KERN_PROC_PID) {
  504                 if (namelen != 1) 
  505                         return (EINVAL);
  506                 p = pfind((pid_t)name[0]);
  507                 if (!p)
  508                         return (0);
  509                 error = sysctl_out_proc(p, req, 0);
  510                 return (error);
  511         }
  512         if (oidp->oid_number == KERN_PROC_ALL && !namelen)
  513                 ;
  514         else if (oidp->oid_number != KERN_PROC_ALL && namelen == 1)
  515                 ;
  516         else
  517                 return (EINVAL);
  518         
  519         if (!req->oldptr) {
  520                 /* overestimate by 5 procs */
  521                 error = SYSCTL_OUT(req, 0, sizeof (struct kinfo_proc) * 5);
  522                 if (error)
  523                         return (error);
  524         }
  525         for (doingzomb=0 ; doingzomb < 2 ; doingzomb++) {
  526                 if (!doingzomb)
  527                         p = allproc.lh_first;
  528                 else
  529                         p = zombproc.lh_first;
  530                 for (; p != 0; p = p->p_list.le_next) {
  531                         /*
  532                          * Skip embryonic processes.
  533                          */
  534                         if (p->p_stat == SIDL)
  535                                 continue;
  536                         /*
  537                          * TODO - make more efficient (see notes below).
  538                          * do by session.
  539                          */
  540                         switch (oidp->oid_number) {
  541 
  542                         case KERN_PROC_PGRP:
  543                                 /* could do this by traversing pgrp */
  544                                 if (p->p_pgrp == NULL || 
  545                                     p->p_pgrp->pg_id != (pid_t)name[0])
  546                                         continue;
  547                                 break;
  548 
  549                         case KERN_PROC_TTY:
  550                                 if ((p->p_flag & P_CONTROLT) == 0 ||
  551                                     p->p_session == NULL ||
  552                                     p->p_session->s_ttyp == NULL ||
  553                                     p->p_session->s_ttyp->t_dev != (dev_t)name[0])
  554                                         continue;
  555                                 break;
  556 
  557                         case KERN_PROC_UID:
  558                                 if (p->p_ucred == NULL || 
  559                                     p->p_ucred->cr_uid != (uid_t)name[0])
  560                                         continue;
  561                                 break;
  562 
  563                         case KERN_PROC_RUID:
  564                                 if (p->p_ucred == NULL || 
  565                                     p->p_cred->p_ruid != (uid_t)name[0])
  566                                         continue;
  567                                 break;
  568                         }
  569 
  570                         error = sysctl_out_proc(p, req, doingzomb);
  571                         if (error)
  572                                 return (error);
  573                 }
  574         }
  575         return (0);
  576 }
  577 
  578 
  579 SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD,  0, "Process table");
  580 
  581 SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT,
  582         0, 0, sysctl_kern_proc, "S,proc", "");
  583 
  584 SYSCTL_NODE(_kern_proc, KERN_PROC_PGRP, pgrp, CTLFLAG_RD, 
  585         sysctl_kern_proc, "Process table");
  586 
  587 SYSCTL_NODE(_kern_proc, KERN_PROC_TTY, tty, CTLFLAG_RD, 
  588         sysctl_kern_proc, "Process table");
  589 
  590 SYSCTL_NODE(_kern_proc, KERN_PROC_UID, uid, CTLFLAG_RD, 
  591         sysctl_kern_proc, "Process table");
  592 
  593 SYSCTL_NODE(_kern_proc, KERN_PROC_RUID, ruid, CTLFLAG_RD, 
  594         sysctl_kern_proc, "Process table");
  595 
  596 SYSCTL_NODE(_kern_proc, KERN_PROC_PID, pid, CTLFLAG_RD, 
  597         sysctl_kern_proc, "Process table");

Cache object: c1abb3ce77ffeec50f3a3ecf54c2db9d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.