diff --git a/sys/miscfs/fdesc/fdesc_vnops.c b/sys/miscfs/fdesc/fdesc_vnops.c index 3d375580a184..7ca28b3f826b 100644 --- a/sys/miscfs/fdesc/fdesc_vnops.c +++ b/sys/miscfs/fdesc/fdesc_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: fdesc_vnops.c,v 1.24 1994/12/14 18:45:21 mycroft Exp $ */ +/* $NetBSD: fdesc_vnops.c,v 1.25 1995/10/09 11:19:04 mycroft Exp $ */ /* * Copyright (c) 1992, 1993 @@ -503,21 +503,24 @@ fdesc_setattr(ap) return (error); } -#define UIO_MX 16 +#define UIO_MX 32 -static struct dirtmp { - u_long d_fileno; - u_short d_reclen; - u_short d_namlen; - char d_name[8]; -} rootent[] = { - { FD_DEVFD, UIO_MX, 2, "fd" }, - { FD_STDIN, UIO_MX, 5, "stdin" }, - { FD_STDOUT, UIO_MX, 6, "stdout" }, - { FD_STDERR, UIO_MX, 6, "stderr" }, - { FD_CTTY, UIO_MX, 3, "tty" }, - { 0 } +struct fdesc_target { + ino_t ft_fileno; + u_char ft_type; + u_char ft_namlen; + char *ft_name; +} fdesc_targets[] = { +/* NOTE: The name must be less than UIO_MX-16 chars in length */ +#define N(s) sizeof(s)-1, s + { FD_DEVFD, DT_DIR, N("fd") }, + { FD_STDIN, DT_UNKNOWN, N("stdin") }, + { FD_STDOUT, DT_UNKNOWN, N("stdout") }, + { FD_STDERR, DT_UNKNOWN, N("stderr") }, + { FD_CTTY, DT_UNKNOWN, N("tty") }, +#undef N }; +static int nfdesc_targets = sizeof(fdesc_targets) / sizeof(fdesc_targets[0]); int fdesc_readdir(ap) @@ -531,16 +534,13 @@ fdesc_readdir(ap) } */ *ap; { struct uio *uio = ap->a_uio; + struct dirent d; struct filedesc *fdp; + off_t off; int i; int error; - - /* - * We don't allow exporting fdesc mounts, and currently local - * requests do not need cookies. - */ - if (ap->a_ncookies) - panic("fdesc_readdir: not hungry"); + u_long *cookies = ap->a_cookies; + int ncookies = ap->a_ncookies; switch (VTOFDESC(ap->a_vp)->fd_type) { case Fctty: @@ -548,30 +548,27 @@ fdesc_readdir(ap) case Fdesc: return (ENOTDIR); - - default: - break; } fdp = uio->uio_procp->p_fd; + if (uio->uio_resid < UIO_MX) + return (EINVAL); + off = uio->uio_offset; + if (off & (UIO_MX - 1) || off < 0) + return (EINVAL); + + error = 0; + i = off / UIO_MX; + bzero((caddr_t)&d, UIO_MX); + d.d_reclen = UIO_MX; + if (VTOFDESC(ap->a_vp)->fd_type == Froot) { - struct dirent d; - struct dirent *dp = &d; - struct dirtmp *dt; + struct fdesc_target *ft; - i = uio->uio_offset / UIO_MX; - error = 0; - - while (uio->uio_resid > 0) { - dt = &rootent[i]; - if (dt->d_fileno == 0) { - /**eofflagp = 1;*/ - break; - } - i++; - - switch (dt->d_fileno) { + for (ft = &fdesc_targets[i]; + uio->uio_resid >= UIO_MX && i < nfdesc_targets; ft++, i++) { + switch (ft->ft_fileno) { case FD_CTTY: if (cttyvp(uio->uio_procp) == NULL) continue; @@ -580,53 +577,53 @@ fdesc_readdir(ap) case FD_STDIN: case FD_STDOUT: case FD_STDERR: - if ((dt->d_fileno-FD_STDIN) >= fdp->fd_nfiles) + if ((ft->ft_fileno - FD_STDIN) >= fdp->fd_nfiles) continue; - if (fdp->fd_ofiles[dt->d_fileno-FD_STDIN] == NULL) + if (fdp->fd_ofiles[ft->ft_fileno - FD_STDIN] == NULL) continue; break; } - bzero((caddr_t) dp, UIO_MX); - dp->d_fileno = dt->d_fileno; - dp->d_namlen = dt->d_namlen; - dp->d_type = DT_UNKNOWN; - dp->d_reclen = dt->d_reclen; - bcopy(dt->d_name, dp->d_name, dp->d_namlen+1); - error = uiomove((caddr_t) dp, UIO_MX, uio); - if (error) + + d.d_fileno = ft->ft_fileno; + d.d_namlen = ft->ft_namlen; + bcopy(ft->ft_name, d.d_name, ft->ft_namlen + 1); + d.d_type = ft->ft_type; + + if (error = uiomove((caddr_t)&d, UIO_MX, uio)) break; + if (ncookies-- > 0) + *cookies++ = (i + 1) * UIO_MX; + } + } else { + for (; i - 2 < fdp->fd_nfiles && uio->uio_resid >= UIO_MX; + i++) { + switch (i) { + case 0: + case 1: + d.d_fileno = FD_ROOT; /* XXX */ + d.d_namlen = i + 1; + bcopy("..", d.d_name, d.d_namlen); + d.d_name[i + 1] = '\0'; + d.d_type = DT_DIR; + break; + + default: + if (fdp->fd_ofiles[i - 2] == NULL) + continue; + d.d_fileno = i - 2 + FD_STDIN; + d.d_namlen = sprintf(d.d_name, "%d", i - 2); + d.d_type = DT_UNKNOWN; + break; + } + + if (error = uiomove((caddr_t)&d, UIO_MX, uio)) + break; + if (ncookies-- > 0) + *cookies++ = (i + 1) * UIO_MX; } - uio->uio_offset = i * UIO_MX; - return (error); } - i = uio->uio_offset / UIO_MX; - error = 0; - while (uio->uio_resid > 0) { - if (i >= fdp->fd_nfiles) - break; - - if (fdp->fd_ofiles[i] != NULL) { - struct dirent d; - struct dirent *dp = &d; - - bzero((caddr_t) dp, UIO_MX); - - dp->d_namlen = sprintf(dp->d_name, "%d", i); - dp->d_reclen = UIO_MX; - dp->d_type = DT_UNKNOWN; - dp->d_fileno = i + FD_STDIN; - /* - * And ship to userland - */ - error = uiomove((caddr_t) dp, UIO_MX, uio); - if (error) - break; - } - i++; - } - - uio->uio_offset = i * UIO_MX; + uio->uio_offset = (i + 1) * UIO_MX; return (error); } diff --git a/sys/miscfs/kernfs/kernfs_vnops.c b/sys/miscfs/kernfs/kernfs_vnops.c index e4b42be1f768..6acb1a6a2f8d 100644 --- a/sys/miscfs/kernfs/kernfs_vnops.c +++ b/sys/miscfs/kernfs/kernfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: kernfs_vnops.c,v 1.36 1995/04/15 01:56:43 cgd Exp $ */ +/* $NetBSD: kernfs_vnops.c,v 1.37 1995/10/09 11:18:59 mycroft Exp $ */ /* * Copyright (c) 1992, 1993 @@ -489,26 +489,30 @@ kernfs_readdir(ap) } */ *ap; { struct uio *uio = ap->a_uio; - struct kern_target *kt; struct dirent d; + struct kern_target *kt; + off_t off; int i; int error; + u_long *cookies = ap->a_cookies; + int ncookies = ap->a_ncookies; if (ap->a_vp->v_type != VDIR) return (ENOTDIR); - /* - * We don't allow exporting kernfs mounts, and currently local - * requests do not need cookies. - */ - if (ap->a_ncookies != NULL) - panic("kernfs_readdir: not hungry"); + if (uio->uio_resid < UIO_MX) + return (EINVAL); + off = uio->uio_offset; + if (off & (UIO_MX - 1) || off < 0) + return (EINVAL); - i = uio->uio_offset / UIO_MX; error = 0; + i = off / UIO_MX; + bzero((caddr_t)&d, UIO_MX); + d.d_reclen = UIO_MX; + for (kt = &kern_targets[i]; uio->uio_resid >= UIO_MX && i < nkern_targets; kt++, i++) { - struct dirent *dp = &d; #ifdef KERNFS_DIAGNOSTIC printf("kernfs_readdir: i = %d\n", i); #endif @@ -521,29 +525,18 @@ kernfs_readdir(ap) continue; } - bzero((caddr_t)dp, UIO_MX); - dp->d_namlen = kt->kt_namlen; - bcopy(kt->kt_name, dp->d_name, kt->kt_namlen+1); + d.d_fileno = i + 3; + d.d_namlen = kt->kt_namlen; + bcopy(kt->kt_name, d.d_name, kt->kt_namlen + 1); + d.d_type = kt->kt_type; -#ifdef KERNFS_DIAGNOSTIC - printf("kernfs_readdir: name = %s, len = %d\n", - dp->d_name, dp->d_namlen); -#endif - /* - * Fill in the remaining fields - */ - dp->d_reclen = UIO_MX; - dp->d_fileno = i + 3; - dp->d_type = kt->kt_type; - /* - * And ship to userland - */ - if (error = uiomove((caddr_t)dp, UIO_MX, uio)) + if (error = uiomove((caddr_t)&d, UIO_MX, uio)) break; + if (ncookies-- > 0) + *cookies++ = (i + 1) * UIO_MX; } - uio->uio_offset = i * UIO_MX; - + uio->uio_offset = (i + 1) * UIO_MX; return (error); } diff --git a/sys/miscfs/procfs/procfs.h b/sys/miscfs/procfs/procfs.h index e876a07a9c58..37ef12e6f0da 100644 --- a/sys/miscfs/procfs/procfs.h +++ b/sys/miscfs/procfs/procfs.h @@ -1,4 +1,4 @@ -/* $NetBSD: procfs.h,v 1.13 1995/03/29 22:08:30 briggs Exp $ */ +/* $NetBSD: procfs.h,v 1.14 1995/10/09 11:18:51 mycroft Exp $ */ /* * Copyright (c) 1993 Jan-Simon Pendry @@ -80,19 +80,8 @@ struct pfsnode { ((cnp)->cn_namelen == (len) && \ (bcmp((s), (cnp)->cn_nameptr, (len)) == 0)) -/* - * Format of a directory entry in /proc, ... - * This must map onto struct dirent (see ) - */ -#define PROCFS_NAMELEN 8 -struct pfsdent { - u_int32_t d_fileno; - u_int16_t d_reclen; - u_int8_t d_type; - u_int8_t d_namlen; - char d_name[PROCFS_NAMELEN]; -}; -#define UIO_MX sizeof(struct pfsdent) +#define UIO_MX 32 + #define PROCFS_FILENO(pid, type) \ (((type) < Pproc) ? \ ((type) + 2) : \ diff --git a/sys/miscfs/procfs/procfs_vnops.c b/sys/miscfs/procfs/procfs_vnops.c index 5fc16d9b469f..79c563fb6bd6 100644 --- a/sys/miscfs/procfs/procfs_vnops.c +++ b/sys/miscfs/procfs/procfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: procfs_vnops.c,v 1.33 1995/04/15 01:56:51 cgd Exp $ */ +/* $NetBSD: procfs_vnops.c,v 1.34 1995/10/09 11:18:55 mycroft Exp $ */ /* * Copyright (c) 1993 Jan-Simon Pendry @@ -642,7 +642,7 @@ procfs_validfile(p) * readdir returns directory entries from pfsnode (vp). * * the strategy here with procfs is to generate a single - * directory entry at a time (struct pfsdent) and then + * directory entry at a time (struct dirent) and then * copy that out to userland using uiomove. a more efficent * though more complex implementation, would try to minimize * the number of calls to uiomove(). for procfs, this is @@ -661,32 +661,26 @@ procfs_readdir(ap) } */ *ap; { struct uio *uio = ap->a_uio; - struct pfsdent d; - struct pfsdent *dp = &d; + struct dirent d; struct pfsnode *pfs; - int error; - int count; + off_t off; int i; - - /* - * We don't allow exporting procfs mounts, and currently local - * requests do not need cookies. - */ - if (ap->a_ncookies) - panic("procfs_readdir: not hungry"); + int error; + u_long *cookies = ap->a_cookies; + int ncookies = ap->a_ncookies; pfs = VTOPFS(ap->a_vp); if (uio->uio_resid < UIO_MX) return (EINVAL); - if (uio->uio_offset & (UIO_MX-1)) - return (EINVAL); - if (uio->uio_offset < 0) + off = uio->uio_offset; + if (off & (UIO_MX - 1) || off < 0) return (EINVAL); error = 0; - count = 0; - i = uio->uio_offset / UIO_MX; + i = off / UIO_MX; + bzero((caddr_t)&d, UIO_MX); + d.d_reclen = UIO_MX; switch (pfs->pfs_type) { /* @@ -707,18 +701,19 @@ procfs_readdir(ap) if (pt->pt_valid && (*pt->pt_valid)(p) == 0) continue; - dp->d_reclen = UIO_MX; - dp->d_fileno = PROCFS_FILENO(pfs->pfs_pid, pt->pt_pfstype); - dp->d_namlen = pt->pt_namlen; - bcopy(pt->pt_name, dp->d_name, pt->pt_namlen + 1); - dp->d_type = pt->pt_type; + d.d_fileno = PROCFS_FILENO(pfs->pfs_pid, pt->pt_pfstype); + d.d_namlen = pt->pt_namlen; + bcopy(pt->pt_name, d.d_name, pt->pt_namlen + 1); + d.d_type = pt->pt_type; - if (error = uiomove((caddr_t)dp, UIO_MX, uio)) + if (error = uiomove((caddr_t)&d, UIO_MX, uio)) break; + if (ncookies-- > 0) + *cookies++ = (i + 1) * UIO_MX; } break; - } + } /* * this is for the root of the procfs filesystem @@ -733,29 +728,28 @@ procfs_readdir(ap) #ifdef PROCFS_ZOMBIE int doingzomb = 0; #endif - int pcnt = 0; + int pcnt = i; volatile struct proc *p = allproc.lh_first; + if (pcnt > 3) + pcnt = 3; again: for (; p && uio->uio_resid >= UIO_MX; i++, pcnt++) { - bzero((char *) dp, UIO_MX); - dp->d_reclen = UIO_MX; - switch (i) { case 0: /* `.' */ case 1: /* `..' */ - dp->d_fileno = PROCFS_FILENO(0, Proot); - dp->d_namlen = i + 1; - bcopy("..", dp->d_name, dp->d_namlen); - dp->d_name[i + 1] = '\0'; - dp->d_type = DT_DIR; + d.d_fileno = PROCFS_FILENO(0, Proot); + d.d_namlen = i + 1; + bcopy("..", d.d_name, d.d_namlen); + d.d_name[i + 1] = '\0'; + d.d_type = DT_DIR; break; case 2: - dp->d_fileno = PROCFS_FILENO(0, Pcurproc); - dp->d_namlen = 7; - bcopy("curproc", dp->d_name, 8); - dp->d_type = DT_LNK; + d.d_fileno = PROCFS_FILENO(0, Pcurproc); + d.d_namlen = 7; + bcopy("curproc", d.d_name, 8); + d.d_type = DT_LNK; break; default: @@ -765,16 +759,18 @@ procfs_readdir(ap) if (!p) goto done; } - dp->d_fileno = PROCFS_FILENO(p->p_pid, Pproc); - dp->d_namlen = sprintf(dp->d_name, "%ld", + d.d_fileno = PROCFS_FILENO(p->p_pid, Pproc); + d.d_namlen = sprintf(d.d_name, "%ld", (long)p->p_pid); - dp->d_type = DT_REG; + d.d_type = DT_REG; p = p->p_list.le_next; break; } - if (error = uiomove((caddr_t)dp, UIO_MX, uio)) + if (error = uiomove((caddr_t)&d, UIO_MX, uio)) break; + if (ncookies-- > 0) + *cookies++ = (i + 1) * UIO_MX; } done: @@ -788,15 +784,14 @@ procfs_readdir(ap) break; - } + } default: error = ENOTDIR; break; } - uio->uio_offset = i * UIO_MX; - + uio->uio_offset = (i + 1) * UIO_MX; return (error); }