Add support for cookies, mostly from Greg Hudson.

This commit is contained in:
mycroft 1995-10-09 11:18:51 +00:00
parent b216bead49
commit bcaf2bca34
4 changed files with 140 additions and 166 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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 <dirent.h>)
*/
#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) : \

View File

@ -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);
}