Add support for cookies, mostly from Greg Hudson.
This commit is contained in:
parent
b216bead49
commit
bcaf2bca34
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) : \
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user