iwn: fix compilation without INVARIANTS
[dragonfly.git] / sys / vfs / procfs / procfs_vnops.c
1 /*
2  * Copyright (c) 1993, 1995 Jan-Simon Pendry
3  * Copyright (c) 1993, 1995
4  *      The Regents of the University of California.  All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * Jan-Simon Pendry.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by the University of
20  *      California, Berkeley and its contributors.
21  * 4. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  *      @(#)procfs_vnops.c      8.18 (Berkeley) 5/21/95
38  *
39  * $FreeBSD: src/sys/miscfs/procfs/procfs_vnops.c,v 1.76.2.7 2002/01/22 17:22:59 nectar Exp $
40  */
41
42 /*
43  * procfs vnode interface
44  */
45
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/time.h>
49 #include <sys/kernel.h>
50 #include <sys/lock.h>
51 #include <sys/fcntl.h>
52 #include <sys/proc.h>
53 #include <sys/priv.h>
54 #include <sys/signalvar.h>
55 #include <sys/vnode.h>
56 #include <sys/uio.h>
57 #include <sys/mount.h>
58 #include <sys/namei.h>
59 #include <sys/dirent.h>
60 #include <sys/malloc.h>
61 #include <sys/reg.h>
62 #include <vm/vm_zone.h>
63 #include <vfs/procfs/procfs.h>
64 #include <sys/pioctl.h>
65
66 #include <sys/spinlock2.h>
67
68 #include <machine/limits.h>
69
70 static int      procfs_access (struct vop_access_args *);
71 static int      procfs_badop (struct vop_generic_args *);
72 static int      procfs_bmap (struct vop_bmap_args *);
73 static int      procfs_close (struct vop_close_args *);
74 static int      procfs_getattr (struct vop_getattr_args *);
75 static int      procfs_inactive (struct vop_inactive_args *);
76 static int      procfs_ioctl (struct vop_ioctl_args *);
77 static int      procfs_lookup (struct vop_old_lookup_args *);
78 static int      procfs_open (struct vop_open_args *);
79 static int      procfs_print (struct vop_print_args *);
80 static int      procfs_readdir (struct vop_readdir_args *);
81 static int      procfs_readlink (struct vop_readlink_args *);
82 static int      procfs_reclaim (struct vop_reclaim_args *);
83 static int      procfs_setattr (struct vop_setattr_args *);
84
85 static int      procfs_readdir_proc(struct vop_readdir_args *);
86 static int      procfs_readdir_root(struct vop_readdir_args *);
87
88 /*
89  * procfs vnode operations.
90  */
91 struct vop_ops procfs_vnode_vops = {
92         .vop_default =          vop_defaultop,
93         .vop_access =           procfs_access,
94         .vop_advlock =          (void *)procfs_badop,
95         .vop_bmap =             procfs_bmap,
96         .vop_close =            procfs_close,
97         .vop_old_create =       (void *)procfs_badop,
98         .vop_getattr =          procfs_getattr,
99         .vop_inactive =         procfs_inactive,
100         .vop_old_link =         (void *)procfs_badop,
101         .vop_old_lookup =       procfs_lookup,
102         .vop_old_mkdir =        (void *)procfs_badop,
103         .vop_old_mknod =        (void *)procfs_badop,
104         .vop_open =             procfs_open,
105         .vop_pathconf =         vop_stdpathconf,
106         .vop_print =            procfs_print,
107         .vop_read =             procfs_rw,
108         .vop_readdir =          procfs_readdir,
109         .vop_readlink =         procfs_readlink,
110         .vop_reclaim =          procfs_reclaim,
111         .vop_old_remove =       (void *)procfs_badop,
112         .vop_old_rename =       (void *)procfs_badop,
113         .vop_old_rmdir =        (void *)procfs_badop,
114         .vop_setattr =          procfs_setattr,
115         .vop_old_symlink =      (void *)procfs_badop,
116         .vop_write =            (void *)procfs_rw,
117         .vop_ioctl =            procfs_ioctl
118 };
119
120
121 /*
122  * This is a list of the valid names in the
123  * process-specific sub-directories.  It is
124  * used in procfs_lookup and procfs_readdir
125  */
126 static struct proc_target {
127         u_char  pt_type;
128         u_char  pt_namlen;
129         char    *pt_name;
130         pfstype pt_pfstype;
131         int     (*pt_valid) (struct lwp *p);
132 } proc_targets[] = {
133 #define N(s) sizeof(s)-1, s
134         /*        name          type            validp */
135         { DT_DIR, N("."),       Pproc,          NULL },
136         { DT_DIR, N(".."),      Proot,          NULL },
137         { DT_REG, N("mem"),     Pmem,           NULL },
138         { DT_REG, N("regs"),    Pregs,          procfs_validregs },
139         { DT_REG, N("fpregs"),  Pfpregs,        procfs_validfpregs },
140         { DT_REG, N("dbregs"),  Pdbregs,        procfs_validdbregs },
141         { DT_REG, N("ctl"),     Pctl,           NULL },
142         { DT_REG, N("status"),  Pstatus,        NULL },
143         { DT_REG, N("note"),    Pnote,          NULL },
144         { DT_REG, N("notepg"),  Pnotepg,        NULL },
145         { DT_REG, N("map"),     Pmap,           procfs_validmap },
146         { DT_REG, N("etype"),   Ptype,          procfs_validtype },
147         { DT_REG, N("cmdline"), Pcmdline,       NULL },
148         { DT_REG, N("rlimit"),  Prlimit,        NULL },
149         { DT_LNK, N("file"),    Pfile,          NULL },
150 #undef N
151 };
152 static const int nproc_targets = NELEM(proc_targets);
153
154 static pid_t atopid (const char *, u_int);
155
156 /*
157  * set things up for doing i/o on
158  * the pfsnode (vp).  (vp) is locked
159  * on entry, and should be left locked
160  * on exit.
161  *
162  * for procfs we don't need to do anything
163  * in particular for i/o.  all that is done
164  * is to support exclusive open on process
165  * memory images.
166  *
167  * procfs_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred,
168  *             struct file *a_fp)
169  */
170 static int
171 procfs_open(struct vop_open_args *ap)
172 {
173         struct pfsnode *pfs = VTOPFS(ap->a_vp);
174         struct proc *p1, *p2;
175         int error;
176
177         p2 = pfs_pfind(pfs->pfs_pid);
178         if (p2 == NULL)
179                 return (ENOENT);
180         if (pfs->pfs_pid && !PRISON_CHECK(ap->a_cred, p2->p_ucred)) {
181                 error = ENOENT;
182                 goto done;
183         }
184
185         switch (pfs->pfs_type) {
186         case Pmem:
187                 if (((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL)) ||
188                     ((pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE))) {
189                         error = EBUSY;
190                         goto done;
191                 }
192
193                 p1 = curproc;
194                 KKASSERT(p1);
195                 /* Can't trace a process that's currently exec'ing. */ 
196                 if ((p2->p_flags & P_INEXEC) != 0) {
197                         error = EAGAIN;
198                         goto done;
199                 }
200                 if (!CHECKIO(p1, p2) || p_trespass(ap->a_cred, p2->p_ucred)) {
201                         error = EPERM;
202                         goto done;
203                 }
204
205                 if (ap->a_mode & FWRITE)
206                         pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL);
207
208                 break;
209
210         default:
211                 break;
212         }
213         error = vop_stdopen(ap);
214 done:
215         pfs_pdone(p2);
216         return error;
217 }
218
219 /*
220  * close the pfsnode (vp) after doing i/o.
221  * (vp) is not locked on entry or exit.
222  *
223  * nothing to do for procfs other than undo
224  * any exclusive open flag (see _open above).
225  *
226  * procfs_close(struct vnode *a_vp, int a_fflag, struct ucred *a_cred)
227  */
228 static int
229 procfs_close(struct vop_close_args *ap)
230 {
231         struct pfsnode *pfs = VTOPFS(ap->a_vp);
232         struct proc *p;
233
234         switch (pfs->pfs_type) {
235         case Pmem:
236                 if ((ap->a_fflag & FWRITE) && (pfs->pfs_flags & O_EXCL))
237                         pfs->pfs_flags &= ~(FWRITE|O_EXCL);
238                 /*
239                  * v_opencount determines the last real close on the vnode.
240                  *
241                  * If this is the last close, then it checks to see if
242                  * the target process has PF_LINGER set in p_pfsflags,
243                  * if this is *not* the case, then the process' stop flags
244                  * are cleared, and the process is woken up.  This is
245                  * to help prevent the case where a process has been
246                  * told to stop on an event, but then the requesting process
247                  * has gone away or forgotten about it.
248                  */
249                 p = NULL;
250                 if ((ap->a_vp->v_opencount < 2)
251                     && ((p = pfs_pfind(pfs->pfs_pid)) != NULL ||
252                         (p = pfs_zpfind(pfs->pfs_pid)) != NULL)
253                     && !(p->p_pfsflags & PF_LINGER)) {
254                         spin_lock(&p->p_spin);
255                         p->p_stops = 0;
256                         p->p_step = 0;
257                         spin_unlock(&p->p_spin);
258                         wakeup(&p->p_stype);
259                         wakeup(&p->p_step);
260                 }
261                 pfs_pdone(p);
262                 break;
263         default:
264                 break;
265         }
266
267         return (vop_stdclose(ap));
268 }
269
270 /*
271  * do an ioctl operation on a pfsnode (vp).
272  * (vp) is not locked on entry or exit.
273  */
274 static int
275 procfs_ioctl(struct vop_ioctl_args *ap)
276 {
277         struct pfsnode *pfs = VTOPFS(ap->a_vp);
278         struct proc *procp;
279         struct proc *p;
280         int error;
281         int signo;
282         struct procfs_status *psp;
283         unsigned char flags;
284
285         procp = pfs_pfind(pfs->pfs_pid);
286         if (procp == NULL)
287                 return ENOTTY;
288         p = curproc;
289         if (p == NULL) {
290                 error = EINVAL;
291                 goto done;
292         }
293
294         /* Can't trace a process that's currently exec'ing. */ 
295         if ((procp->p_flags & P_INEXEC) != 0) {
296                 error = EAGAIN;
297                 goto done;
298         }
299         if (!CHECKIO(p, procp) || p_trespass(ap->a_cred, procp->p_ucred)) {
300                 error = EPERM;
301                 goto done;
302         }
303
304         switch (ap->a_command) {
305         case PIOCBIS:
306           spin_lock(&procp->p_spin);
307           procp->p_stops |= *(unsigned int*)ap->a_data;
308           spin_unlock(&procp->p_spin);
309           break;
310         case PIOCBIC:
311           spin_lock(&procp->p_spin);
312           procp->p_stops &= ~*(unsigned int*)ap->a_data;
313           spin_unlock(&procp->p_spin);
314           break;
315         case PIOCSFL:
316           /*
317            * NFLAGS is "non-suser_xxx flags" -- currently, only
318            * PFS_ISUGID ("ignore set u/g id");
319            */
320 #define NFLAGS  (PF_ISUGID)
321           flags = (unsigned char)*(unsigned int*)ap->a_data;
322           if (flags & NFLAGS && (error = priv_check_cred(ap->a_cred, PRIV_ROOT, 0)))
323             goto done;
324           procp->p_pfsflags = flags;
325           break;
326         case PIOCGFL:
327           *(unsigned int*)ap->a_data = (unsigned int)procp->p_pfsflags;
328           break;
329         case PIOCSTATUS:
330           /*
331            * NOTE: syscall entry deals with stopevents and may run without
332            *       the MP lock.
333            */
334           psp = (struct procfs_status *)ap->a_data;
335           psp->flags = procp->p_pfsflags;
336           psp->events = procp->p_stops;
337           spin_lock(&procp->p_spin);
338           if (procp->p_step) {
339             psp->state = 0;
340             psp->why = procp->p_stype;
341             psp->val = procp->p_xstat;
342             spin_unlock(&procp->p_spin);
343           } else {
344             psp->state = 1;
345             spin_unlock(&procp->p_spin);
346             psp->why = 0;       /* Not defined values */
347             psp->val = 0;       /* Not defined values */
348           }
349           break;
350         case PIOCWAIT:
351           /*
352            * NOTE: syscall entry deals with stopevents and may run without
353            *       the MP lock.
354            */
355           psp = (struct procfs_status *)ap->a_data;
356           spin_lock(&procp->p_spin);
357           while (procp->p_step == 0) {
358             tsleep_interlock(&procp->p_stype, PCATCH);
359             spin_unlock(&procp->p_spin);
360             if (procp->p_stops == 0) {
361                 error = EINVAL;
362                 goto done;
363             }
364             if (procp->p_flags & P_POSTEXIT) {
365                 error = EINVAL;
366                 goto done;
367             }
368             if (procp->p_flags & P_INEXEC) {
369                 error = EAGAIN;
370                 goto done;
371             }
372             error = tsleep(&procp->p_stype, PCATCH | PINTERLOCKED,
373                            "piocwait", 0);
374             if (error)
375               goto done;
376             spin_lock(&procp->p_spin);
377           }
378           spin_unlock(&procp->p_spin);
379           psp->state = 1;       /* It stopped */
380           psp->flags = procp->p_pfsflags;
381           psp->events = procp->p_stops;
382           psp->why = procp->p_stype;    /* why it stopped */
383           psp->val = procp->p_xstat;    /* any extra info */
384           break;
385         case PIOCCONT:  /* Restart a proc */
386           /*
387            * NOTE: syscall entry deals with stopevents and may run without
388            *       the MP lock.  However, the caller is presumably interlocked
389            *       by having waited.
390            */
391           if (procp->p_step == 0) {
392             error = EINVAL;     /* Can only start a stopped process */
393             goto done;
394           }
395           if ((signo = *(int*)ap->a_data) != 0) {
396             if (signo >= NSIG || signo <= 0) {
397               error = EINVAL;
398               goto done;
399             }
400             ksignal(procp, signo);
401           }
402           procp->p_step = 0;
403           wakeup(&procp->p_step);
404           break;
405         default:
406           error = ENOTTY;
407           goto done;
408         }
409         error = 0;
410 done:
411         pfs_pdone(procp);
412         return 0;
413 }
414
415 /*
416  * do block mapping for pfsnode (vp).
417  * since we don't use the buffer cache
418  * for procfs this function should never
419  * be called.  in any case, it's not clear
420  * what part of the kernel ever makes use
421  * of this function.  for sanity, this is the
422  * usual no-op bmap, although returning
423  * (EIO) would be a reasonable alternative.
424  *
425  * XXX mmap assumes buffer cache operation
426  *
427  * procfs_bmap(struct vnode *a_vp, off_t a_loffset,
428  *              off_t *a_doffsetp, int *a_runp, int *a_runb)
429  */
430 static int
431 procfs_bmap(struct vop_bmap_args *ap)
432 {
433         if (ap->a_doffsetp != NULL)
434                 *ap->a_doffsetp = ap->a_loffset;
435         if (ap->a_runp != NULL)
436                 *ap->a_runp = 0;
437         if (ap->a_runb != NULL)
438                 *ap->a_runb = 0;
439         return (0);
440 }
441
442 /*
443  * procfs_inactive is called when the pfsnode
444  * is vrele'd and the reference count goes
445  * to zero.  (vp) will be on the vnode free
446  * list, so to get it back vget() must be
447  * used.
448  *
449  * (vp) is locked on entry, but must be unlocked on exit.
450  *
451  * procfs_inactive(struct vnode *a_vp)
452  */
453 static int
454 procfs_inactive(struct vop_inactive_args *ap)
455 {
456         struct pfsnode *pfs = VTOPFS(ap->a_vp);
457
458         if (pfs->pfs_pid & PFS_DEAD)
459                 vrecycle(ap->a_vp);
460         return (0);
461 }
462
463 /*
464  * _reclaim is called when getnewvnode()
465  * wants to make use of an entry on the vnode
466  * free list.  at this time the filesystem needs
467  * to free any private data and remove the node
468  * from any private lists.
469  *
470  * procfs_reclaim(struct vnode *a_vp)
471  */
472 static int
473 procfs_reclaim(struct vop_reclaim_args *ap)
474 {
475         return (procfs_freevp(ap->a_vp));
476 }
477
478 /*
479  * _print is used for debugging.
480  * just print a readable description
481  * of (vp).
482  *
483  * procfs_print(struct vnode *a_vp)
484  */
485 static int
486 procfs_print(struct vop_print_args *ap)
487 {
488         struct pfsnode *pfs = VTOPFS(ap->a_vp);
489
490         kprintf("tag VT_PROCFS, type %d, pid %ld, mode %x, flags %lx\n",
491             pfs->pfs_type, (long)pfs->pfs_pid, pfs->pfs_mode, pfs->pfs_flags);
492         return (0);
493 }
494
495 /*
496  * generic entry point for unsupported operations
497  */
498 static int
499 procfs_badop(struct vop_generic_args *ap)
500 {
501         return (EIO);
502 }
503
504 /*
505  * Invent attributes for pfsnode (vp) and store
506  * them in (vap).
507  * Directories lengths are returned as zero since
508  * any real length would require the genuine size
509  * to be computed, and nothing cares anyway.
510  *
511  * this is relatively minimal for procfs.
512  *
513  * procfs_getattr(struct vnode *a_vp, struct vattr *a_vap)
514  */
515 static int
516 procfs_getattr(struct vop_getattr_args *ap)
517 {
518         struct pfsnode *pfs = VTOPFS(ap->a_vp);
519         struct vattr *vap = ap->a_vap;
520         struct proc *procp;
521         int error;
522
523         /*
524          * First make sure that the process and its credentials 
525          * still exist.
526          */
527         switch (pfs->pfs_type) {
528         case Proot:
529         case Pcurproc:
530                 procp = NULL;
531                 break;
532         default:
533                 procp = pfs_pfind(pfs->pfs_pid);
534                 if (procp == NULL || procp->p_ucred == NULL) {
535                         error = ENOENT;
536                         goto done;
537                 }
538                 break;
539         }
540
541         error = 0;
542
543         /* start by zeroing out the attributes */
544         VATTR_NULL(vap);
545
546         /* next do all the common fields */
547         vap->va_type = ap->a_vp->v_type;
548         vap->va_mode = pfs->pfs_mode;
549         vap->va_fileid = pfs->pfs_fileno;
550         vap->va_flags = 0;
551         vap->va_blocksize = PAGE_SIZE;
552         vap->va_bytes = vap->va_size = 0;
553         vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0];
554
555         /*
556          * Make all times be current TOD.
557          * It would be possible to get the process start
558          * time from the p_stat structure, but there's
559          * no "file creation" time stamp anyway, and the
560          * p_stat structure is not addressible if u. gets
561          * swapped out for that process.
562          */
563         nanotime(&vap->va_ctime);
564         vap->va_atime = vap->va_mtime = vap->va_ctime;
565
566         /*
567          * If the process has exercised some setuid or setgid
568          * privilege, then rip away read/write permission so
569          * that only root can gain access.
570          */
571         switch (pfs->pfs_type) {
572         case Pctl:
573         case Pregs:
574         case Pfpregs:
575         case Pdbregs:
576         case Pmem:
577                 if (procp->p_flags & P_SUGID) {
578                         vap->va_mode &= ~((VREAD|VWRITE)|
579                                           ((VREAD|VWRITE)>>3)|
580                                           ((VREAD|VWRITE)>>6));
581                 }
582                 break;
583         default:
584                 break;
585         }
586
587         /*
588          * now do the object specific fields
589          *
590          * The size could be set from struct reg, but it's hardly
591          * worth the trouble, and it puts some (potentially) machine
592          * dependent data into this machine-independent code.  If it
593          * becomes important then this function should break out into
594          * a per-file stat function in the corresponding .c file.
595          */
596
597         vap->va_nlink = 1;
598         if (procp) {
599                 if (procp->p_ucred) {
600                         vap->va_uid = procp->p_ucred->cr_uid;
601                         vap->va_gid = procp->p_ucred->cr_gid;
602                 } else {
603                         vap->va_uid = -1;
604                         vap->va_gid = -1;
605                 }
606         }
607
608         switch (pfs->pfs_type) {
609         case Proot:
610                 /*
611                  * Set nlink to 1 to tell fts(3) we don't actually know.
612                  */
613                 vap->va_nlink = 1;
614                 vap->va_uid = 0;
615                 vap->va_gid = 0;
616                 vap->va_size = vap->va_bytes = DEV_BSIZE;
617                 break;
618
619         case Pcurproc: {
620                 char buf[16];           /* should be enough */
621
622                 vap->va_uid = 0;
623                 vap->va_gid = 0;
624                 vap->va_size = ksnprintf(buf, sizeof(buf),
625                                          "%ld", (long)curproc->p_pid);
626                 vap->va_bytes = vap->va_size;
627                 break;
628         }
629
630         case Pproc:
631                 vap->va_nlink = nproc_targets;
632                 vap->va_size = vap->va_bytes = DEV_BSIZE;
633                 break;
634
635         case Pfile: {
636                 char *fullpath, *freepath;
637
638                 if (procp->p_textnch.ncp) {
639                         struct nchandle nch;
640
641                         cache_copy(&procp->p_textnch, &nch);
642                         error = cache_fullpath(procp, &nch, NULL,
643                                                &fullpath, &freepath, 0);
644                         cache_drop(&nch);
645                 } else {
646                         error = EINVAL;
647                 }
648
649                 if (error == 0) {
650                         vap->va_size = strlen(fullpath);
651                         kfree(freepath, M_TEMP);
652                 } else {
653                         vap->va_size = sizeof("unknown") - 1;
654                         error = 0;
655                 }
656                 vap->va_bytes = vap->va_size;
657                 break;
658         }
659
660         case Pmem:
661                 /*
662                  * If we denied owner access earlier, then we have to
663                  * change the owner to root - otherwise 'ps' and friends
664                  * will break even though they are setgid kmem. *SIGH*
665                  */
666                 if (procp->p_flags & P_SUGID)
667                         vap->va_uid = 0;
668                 else if (procp->p_ucred)
669                         vap->va_uid = procp->p_ucred->cr_uid;
670                 else
671                         vap->va_uid = -1;
672                 break;
673
674         case Pregs:
675                 vap->va_bytes = vap->va_size = sizeof(struct reg);
676                 break;
677
678         case Pfpregs:
679                 vap->va_bytes = vap->va_size = sizeof(struct fpreg);
680                 break;
681
682         case Pdbregs:
683                 vap->va_bytes = vap->va_size = sizeof(struct dbreg);
684                 break;
685
686         case Ptype:
687         case Pmap:
688         case Pctl:
689         case Pstatus:
690         case Pnote:
691         case Pnotepg:
692         case Pcmdline:
693         case Prlimit:
694                 break;
695
696         default:
697                 panic("procfs_getattr");
698         }
699 done:
700         pfs_pdone(procp);
701         return (error);
702 }
703
704 /*
705  * procfs_setattr(struct vnode *a_vp, struct vattr *a_vap,
706  *                struct ucred *a_cred)
707  */
708 static int
709 procfs_setattr(struct vop_setattr_args *ap)
710 {
711         if (ap->a_vap->va_flags != VNOVAL)
712                 return (EOPNOTSUPP);
713
714         /*
715          * just fake out attribute setting
716          * it's not good to generate an error
717          * return, otherwise things like creat()
718          * will fail when they try to set the
719          * file length to 0.  worse, this means
720          * that echo $note > /proc/$pid/note will fail.
721          */
722
723         return (0);
724 }
725
726 /*
727  * implement access checking.
728  *
729  * procfs_access(struct vnode *a_vp, int a_mode, struct ucred *a_cred)
730  */
731 static int
732 procfs_access(struct vop_access_args *ap)
733 {
734         struct vattr vattr;
735         int error;
736
737         error = VOP_GETATTR(ap->a_vp, &vattr);
738         if (!error)
739                 error = vop_helper_access(ap, vattr.va_uid, vattr.va_gid, 
740                                 vattr.va_mode, 0);
741         return (error);
742 }
743
744 /*
745  * lookup.  this is incredibly complicated in the general case, however
746  * for most pseudo-filesystems very little needs to be done.
747  *
748  * procfs_lookup(struct vnode *a_dvp, struct vnode **a_vpp,
749  *               struct componentname *a_cnp)
750  */
751 static int
752 procfs_lookup(struct vop_old_lookup_args *ap)
753 {
754         struct componentname *cnp = ap->a_cnp;
755         struct vnode **vpp = ap->a_vpp;
756         struct vnode *dvp = ap->a_dvp;
757         char *pname = cnp->cn_nameptr;
758         /* struct proc *curp = cnp->cn_proc; */
759         struct proc_target *pt;
760         pid_t pid;
761         struct pfsnode *pfs;
762         struct proc *p;
763         struct lwp *lp;
764         int i;
765         int error;
766
767         *vpp = NULL;
768
769         if (cnp->cn_nameiop == NAMEI_DELETE || cnp->cn_nameiop == NAMEI_RENAME)
770                 return (EROFS);
771
772         p = NULL;
773         error = 0;
774         if (cnp->cn_namelen == 1 && *pname == '.') {
775                 *vpp = dvp;
776                 vref(*vpp);
777                 goto out;
778         }
779
780         pfs = VTOPFS(dvp);
781         switch (pfs->pfs_type) {
782         case Proot:
783                 if (cnp->cn_flags & CNP_ISDOTDOT)
784                         return (EIO);
785
786                 if (CNEQ(cnp, "curproc", 7)) {
787                         error = procfs_allocvp(dvp->v_mount, vpp, 0, Pcurproc);
788                         goto out;
789                 }
790
791                 pid = atopid(pname, cnp->cn_namelen);
792                 if (pid == NO_PID)
793                         break;
794
795                 p = pfs_pfind(pid);
796                 if (p == NULL)
797                         break;
798
799                 if (!PRISON_CHECK(ap->a_cnp->cn_cred, p->p_ucred))
800                         break;
801
802                 if (ps_showallprocs == 0 && ap->a_cnp->cn_cred->cr_uid != 0 &&
803                     ap->a_cnp->cn_cred->cr_uid != p->p_ucred->cr_uid)
804                         break;
805
806                 error = procfs_allocvp(dvp->v_mount, vpp, pid, Pproc);
807                 goto out;
808
809         case Pproc:
810                 if (cnp->cn_flags & CNP_ISDOTDOT) {
811                         error = procfs_root(dvp->v_mount, vpp);
812                         goto out;
813                 }
814
815                 p = pfs_pfind(pfs->pfs_pid);
816                 if (p == NULL)
817                         break;
818                 /* XXX lwp */
819                 lp = FIRST_LWP_IN_PROC(p);
820
821                 if (!PRISON_CHECK(ap->a_cnp->cn_cred, p->p_ucred))
822                         break;
823
824                 if (ps_showallprocs == 0 && ap->a_cnp->cn_cred->cr_uid != 0 &&
825                     ap->a_cnp->cn_cred->cr_uid != p->p_ucred->cr_uid)
826                         break;
827
828                 for (pt = proc_targets, i = 0; i < nproc_targets; pt++, i++) {
829                         if (cnp->cn_namelen == pt->pt_namlen &&
830                             bcmp(pt->pt_name, pname, cnp->cn_namelen) == 0 &&
831                             (pt->pt_valid == NULL || (*pt->pt_valid)(lp)))
832                                 goto found;
833                 }
834                 break;
835         found:
836                 error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
837                                         pt->pt_pfstype);
838                 goto out;
839
840         default:
841                 error = ENOTDIR;
842                 goto out;
843         }
844         if (cnp->cn_nameiop == NAMEI_LOOKUP)
845                 error = ENOENT;
846         else
847                 error = EROFS;
848         /*
849          * If no error occured *vpp will hold a referenced locked vnode.
850          * dvp was passed to us locked and *vpp must be returned locked.
851          * If *vpp != dvp then we should unlock dvp if (1) this is not the
852          * last component or (2) CNP_LOCKPARENT is not set.
853          */
854 out:
855         if (error == 0 && *vpp != dvp) {
856                 if ((cnp->cn_flags & CNP_LOCKPARENT) == 0) {
857                         cnp->cn_flags |= CNP_PDIRUNLOCK;
858                         vn_unlock(dvp);
859                 }
860         }
861         pfs_pdone(p);
862         return (error);
863 }
864
865 /*
866  * Does this process have a text file?
867  */
868 int
869 procfs_validfile(struct lwp *lp)
870 {
871         return (procfs_findtextvp(lp->lwp_proc) != NULLVP);
872 }
873
874 /*
875  * readdir() returns directory entries from pfsnode (vp).
876  *
877  * We generate just one directory entry at a time, as it would probably
878  * not pay off to buffer several entries locally to save uiomove calls.
879  *
880  * procfs_readdir(struct vnode *a_vp, struct uio *a_uio, struct ucred *a_cred,
881  *                int *a_eofflag, int *a_ncookies, off_t **a_cookies)
882  */
883 static int
884 procfs_readdir(struct vop_readdir_args *ap)
885 {
886         struct pfsnode *pfs;
887         int error;
888
889         if (ap->a_uio->uio_offset < 0 || ap->a_uio->uio_offset > INT_MAX)
890                 return (EINVAL);
891         if ((error = vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY)) != 0)
892                 return (error);
893         pfs = VTOPFS(ap->a_vp);
894
895         switch (pfs->pfs_type) {
896         case Pproc:
897                 /*
898                  * this is for the process-specific sub-directories.
899                  * all that is needed to is copy out all the entries
900                  * from the procent[] table (top of this file).
901                  */
902                 error = procfs_readdir_proc(ap);
903                 break;
904         case Proot:
905                 /*
906                  * this is for the root of the procfs filesystem
907                  * what is needed is a special entry for "curproc"
908                  * followed by an entry for each process on allproc
909                  */
910                 error = procfs_readdir_root(ap);
911                 break;
912         default:
913                 error = ENOTDIR;
914                 break;
915         }
916
917         vn_unlock(ap->a_vp);
918         return (error);
919 }
920
921 static int
922 procfs_readdir_proc(struct vop_readdir_args *ap)
923 {
924         struct pfsnode *pfs;
925         int error, i, retval;
926         struct proc *p;
927         struct lwp *lp;
928         struct proc_target *pt;
929         struct uio *uio = ap->a_uio;
930
931         pfs = VTOPFS(ap->a_vp);
932         p = pfs_pfind(pfs->pfs_pid);
933         if (p == NULL)
934                 return(0);
935         if (!PRISON_CHECK(ap->a_cred, p->p_ucred)) {
936                 error = 0;
937                 goto done;
938         }
939         /* XXX lwp, not MPSAFE */
940         lp = FIRST_LWP_IN_PROC(p);
941
942         error = 0;
943         i = (int)uio->uio_offset;
944         if (i < 0) {
945                 error = EINVAL;
946                 goto done;
947         }
948
949         for (pt = &proc_targets[i];
950              !error && uio->uio_resid > 0 && i < nproc_targets; pt++, i++) {
951                 if (pt->pt_valid && (*pt->pt_valid)(lp) == 0)
952                         continue;
953
954                 retval = vop_write_dirent(&error, uio,
955                     PROCFS_FILENO(pfs->pfs_pid, pt->pt_pfstype), pt->pt_type,
956                     pt->pt_namlen, pt->pt_name);
957                 if (retval)
958                         break;
959         }
960
961         uio->uio_offset = (off_t)i;
962         error = 0;
963 done:
964         pfs_pdone(p);
965         return error;
966 }
967
968 struct procfs_readdir_root_info {
969         int error;
970         int i;
971         int pcnt;
972         struct uio *uio;
973         struct ucred *cred;
974 };
975
976 static int procfs_readdir_root_callback(struct proc *p, void *data);
977
978 static int
979 procfs_readdir_root(struct vop_readdir_args *ap)
980 {
981         struct procfs_readdir_root_info info;
982         struct uio *uio = ap->a_uio;
983         int res;
984
985         res = 0;
986         info.error = 0;
987         info.i = (int)uio->uio_offset;
988
989         if (info.i < 0)
990                 return (EINVAL);
991
992         info.pcnt = 0;
993         info.uio = uio;
994         info.cred = ap->a_cred;
995         while (info.pcnt < 3) {
996                 res = procfs_readdir_root_callback(NULL, &info);
997                 if (res < 0)
998                         break;
999         }
1000         if (res >= 0)
1001                 allproc_scan(procfs_readdir_root_callback, &info);
1002         uio->uio_offset = (off_t)info.i;
1003
1004         return (info.error);
1005 }
1006
1007 static int
1008 procfs_readdir_root_callback(struct proc *p, void *data)
1009 {
1010         struct procfs_readdir_root_info *info = data;
1011         struct uio *uio;
1012         int retval;
1013         ino_t d_ino;
1014         const char *d_name;
1015         char d_name_pid[20];
1016         size_t d_namlen;
1017         uint8_t d_type;
1018
1019         uio = info->uio;
1020
1021         if (uio->uio_resid <= 0 || info->error)
1022                 return(-1);
1023
1024         switch (info->pcnt) {
1025         case 0:         /* `.' */
1026                 d_ino = PROCFS_FILENO(0, Proot);
1027                 d_name = ".";
1028                 d_namlen = 1;
1029                 d_type = DT_DIR;
1030                 break;
1031         case 1:         /* `..' */
1032                 d_ino = PROCFS_FILENO(0, Proot);
1033                 d_name = "..";
1034                 d_namlen = 2;
1035                 d_type = DT_DIR;
1036                 break;
1037
1038         case 2:
1039                 d_ino = PROCFS_FILENO(0, Pcurproc);
1040                 d_namlen = 7;
1041                 d_name = "curproc";
1042                 d_type = DT_LNK;
1043                 break;
1044
1045
1046         default:
1047                 if (!PRISON_CHECK(info->cred, p->p_ucred))
1048                         return(0);
1049                 if (ps_showallprocs == 0 && 
1050                     info->cred->cr_uid != 0 &&
1051                     info->cred->cr_uid != p->p_ucred->cr_uid) {
1052                         return(0);
1053                 }
1054
1055                 /*
1056                  * Skip entries we have already returned (optimization)
1057                  */
1058                 if (info->pcnt < info->i) {
1059                         ++info->pcnt;
1060                         return(0);
1061                 }
1062
1063                 d_ino = PROCFS_FILENO(p->p_pid, Pproc);
1064                 d_namlen = ksnprintf(d_name_pid, sizeof(d_name_pid),
1065                     "%ld", (long)p->p_pid);
1066                 d_name = d_name_pid;
1067                 d_type = DT_DIR;
1068                 break;
1069         }
1070
1071         /*
1072          * Skip entries we have already returned (optimization)
1073          */
1074         if (info->pcnt < info->i) {
1075                 ++info->pcnt;
1076                 return(0);
1077         }
1078
1079         retval = vop_write_dirent(&info->error, uio,
1080                                   d_ino, d_type, d_namlen, d_name);
1081         if (retval)
1082                 return(-1);
1083         ++info->pcnt;
1084         ++info->i;
1085         return(0);
1086 }
1087
1088 /*
1089  * readlink reads the link of `curproc' or `file'
1090  */
1091 static int
1092 procfs_readlink(struct vop_readlink_args *ap)
1093 {
1094         char buf[16];           /* should be enough */
1095         struct proc *procp;
1096         struct vnode *vp = ap->a_vp;
1097         struct pfsnode *pfs = VTOPFS(vp);
1098         char *fullpath, *freepath;
1099         int error, len;
1100
1101         switch (pfs->pfs_type) {
1102         case Pcurproc:
1103                 if (pfs->pfs_fileno != PROCFS_FILENO(0, Pcurproc))
1104                         return (EINVAL);
1105
1106                 len = ksnprintf(buf, sizeof(buf), "%ld", (long)curproc->p_pid);
1107
1108                 return (uiomove(buf, len, ap->a_uio));
1109         /*
1110          * There _should_ be no way for an entire process to disappear
1111          * from under us...
1112          */
1113         case Pfile:
1114                 procp = pfs_pfind(pfs->pfs_pid);
1115                 if (procp == NULL || procp->p_ucred == NULL) {
1116                         kprintf("procfs_readlink: pid %d disappeared\n",
1117                             pfs->pfs_pid);
1118                         pfs_pdone(procp);
1119                         return (uiomove("unknown", sizeof("unknown") - 1,
1120                                         ap->a_uio));
1121                 }
1122                 if (procp->p_textnch.ncp) {
1123                         struct nchandle nch;
1124
1125                         cache_copy(&procp->p_textnch, &nch);
1126                         error = cache_fullpath(procp, &nch, NULL,
1127                                                &fullpath, &freepath, 0);
1128                         cache_drop(&nch);
1129                 } else {
1130                         error = EINVAL;
1131                 }
1132
1133                 if (error != 0) {
1134                         pfs_pdone(procp);
1135                         return (uiomove("unknown", sizeof("unknown") - 1,
1136                                         ap->a_uio));
1137                 }
1138                 error = uiomove(fullpath, strlen(fullpath), ap->a_uio);
1139                 kfree(freepath, M_TEMP);
1140                 pfs_pdone(procp);
1141                 return (error);
1142         default:
1143                 return (EINVAL);
1144         }
1145 }
1146
1147 /*
1148  * convert decimal ascii to pid_t
1149  */
1150 static pid_t
1151 atopid(const char *b, u_int len)
1152 {
1153         pid_t p = 0;
1154
1155         while (len--) {
1156                 char c = *b++;
1157                 if (c < '0' || c > '9')
1158                         return (NO_PID);
1159                 p = 10 * p + (c - '0');
1160                 if (p > PID_MAX)
1161                         return (NO_PID);
1162         }
1163
1164         return (p);
1165 }
1166