| /* |
| * dnode.c - FreeBSD node functions for lsof |
| */ |
| |
| |
| /* |
| * Copyright 1994 Purdue Research Foundation, West Lafayette, Indiana |
| * 47907. All rights reserved. |
| * |
| * Written by Victor A. Abell |
| * |
| * This software is not subject to any license of the American Telephone |
| * and Telegraph Company or the Regents of the University of California. |
| * |
| * Permission is granted to anyone to use this software for any purpose on |
| * any computer system, and to alter it and redistribute it freely, subject |
| * to the following restrictions: |
| * |
| * 1. Neither the authors nor Purdue University are responsible for any |
| * consequences of the use of this software. |
| * |
| * 2. The origin of this software must not be misrepresented, either by |
| * explicit claim or by omission. Credit to the authors and Purdue |
| * University must appear in documentation and sources. |
| * |
| * 3. Altered versions must be plainly marked as such, and must not be |
| * misrepresented as being the original software. |
| * |
| * 4. This notice may not be removed or altered. |
| */ |
| |
| #ifndef lint |
| static char copyright[] = |
| "@(#) Copyright 1994 Purdue Research Foundation.\nAll rights reserved.\n"; |
| static char *rcsid = "$Id: dnode.c,v 1.41 2011/08/07 22:51:28 abe Exp $"; |
| #endif |
| |
| |
| #include "lsof.h" |
| |
| #if defined(HAS_LOCKF_ENTRY) |
| #include "./lockf_owner.h" |
| #endif /* defined(HAS_LOCKF_ENTRY) */ |
| |
| #if defined(HAS_ZFS) |
| #include "dzfs.h" |
| #endif /* defined(HAS_ZFS) */ |
| |
| |
| #if defined(HASFDESCFS) && HASFDESCFS==1 |
| _PROTOTYPE(static int lkup_dev_tty,(dev_t *dr, INODETYPE *ir)); |
| #endif /* defined(HASFDESCFS) && HASFDESCFS==1 */ |
| |
| _PROTOTYPE(static void get_lock_state,(KA_T f)); |
| |
| |
| /* |
| * get_lock_state() -- get the lock state |
| */ |
| |
| static void |
| get_lock_state(f) |
| KA_T f; /* inode's lock pointer */ |
| { |
| struct lockf lf; /* lockf structure */ |
| int lt; /* lock type */ |
| |
| #if defined(HAS_LOCKF_ENTRY) |
| struct lockf_entry le; /* lock_entry structure */ |
| KA_T lef, lep; /* lock_entry pointers */ |
| struct lock_owner lo; /* lock owner structure */ |
| |
| if (!f || kread(f, (char *)&lf, sizeof(lf))) |
| return; |
| if (!(lef = (KA_T)lf.ls_active.lh_first)) |
| return; |
| lep = lef; |
| do { |
| if (kread(lep, (char *)&le, sizeof(le))) |
| return; |
| if (!le.lf_owner |
| || kread((KA_T)le.lf_owner, (char *)&lo, sizeof(lo))) |
| continue; |
| if (lo.lo_pid == (pid_t)Lp->pid) { |
| if (le.lf_start == (off_t)0 |
| && le.lf_end == 0x7fffffffffffffffLL) |
| lt = 1; |
| else |
| lt = 0; |
| if (le.lf_type == F_RDLCK) |
| Lf->lock = lt ? 'R' : 'r'; |
| else if (le.lf_type == F_WRLCK) |
| Lf->lock = lt ? 'W' : 'w'; |
| else if (le.lf_type == (F_RDLCK | F_WRLCK)) |
| Lf->lock = 'u'; |
| return; |
| } |
| } while ((lep = (KA_T)le.lf_link.le_next) && (lep != lef)); |
| #else /* !defined(HAS_LOCKF_ENTRY) */ |
| |
| unsigned char l; /* lock status */ |
| KA_T lfp; /* lockf structure pointer */ |
| |
| if ((lfp = f)) { |
| |
| /* |
| * Determine the lock state. |
| */ |
| do { |
| if (kread(lfp, (char *)&lf, sizeof(lf))) |
| break; |
| l = 0; |
| switch (lf.lf_flags & (F_FLOCK|F_POSIX)) { |
| case F_FLOCK: |
| if (Cfp && (struct file *)lf.lf_id == Cfp) |
| l = 1; |
| break; |
| case F_POSIX: |
| |
| # if defined(P_ADDR) |
| if ((KA_T)lf.lf_id == Kpa) |
| l = 1; |
| # endif /* defined(P_ADDR) */ |
| |
| break; |
| } |
| if (!l) |
| continue; |
| if (lf.lf_start == (off_t)0 |
| && lf.lf_end == 0xffffffffffffffffLL) |
| lt = 1; |
| else |
| lt = 0; |
| if (lf.lf_type == F_RDLCK) |
| Lf->lock = lt ? 'R' : 'r'; |
| else if (lf.lf_type == F_WRLCK) |
| Lf->lock = lt ? 'W' : 'w'; |
| else if (lf.lf_type == (F_RDLCK | F_WRLCK)) |
| Lf->lock = 'u'; |
| break; |
| } while ((lfp = (KA_T)lf.lf_next) && (lfp != f)); |
| } |
| #endif /* defined(HAS_LOCKF_ENTRY) */ |
| |
| } |
| |
| |
| #if FREEBSDV>=2000 |
| # if defined(HASPROCFS) |
| _PROTOTYPE(static void getmemsz,(pid_t pid)); |
| |
| |
| /* |
| * getmemsz() - get memory size of a /proc/<n>/mem entry |
| */ |
| |
| static void |
| getmemsz(pid) |
| pid_t pid; |
| { |
| int n; |
| struct kinfo_proc *p; |
| struct vmspace vm; |
| |
| for (n = 0, p = P; n < Np; n++, p++) { |
| if (p->P_PID == pid) { |
| if (!p->P_VMSPACE |
| || kread((KA_T)p->P_VMSPACE, (char *)&vm, sizeof(vm))) |
| return; |
| Lf->sz = (SZOFFTYPE)ctob(vm.vm_tsize+vm.vm_dsize+vm.vm_ssize); |
| Lf->sz_def = 1; |
| return; |
| } |
| } |
| } |
| # endif /* defined(HASPROCFS) */ |
| #endif /* FREEBSDV>=2000 */ |
| |
| |
| #if defined(HASFDESCFS) && HASFDESCFS==1 |
| /* |
| * lkup_dev_tty() - look up /dev/tty |
| */ |
| |
| static int |
| lkup_dev_tty(dr, ir) |
| dev_t *dr; /* place to return device number */ |
| INODETYPE *ir; /* place to return inode number */ |
| { |
| int i; |
| |
| readdev(0); |
| |
| # if defined(HASDCACHE) |
| |
| lkup_dev_tty_again: |
| |
| # endif /* defined(HASDCACHE) */ |
| |
| for (i = 0; i < Ndev; i++) { |
| if (strcmp(Devtp[i].name, "/dev/tty") == 0) { |
| |
| # if defined(HASDCACHE) |
| if (DCunsafe && !Devtp[i].v && !vfy_dev(&Devtp[i])) |
| goto lkup_dev_tty_again; |
| # endif /* defined(HASDCACHE) */ |
| |
| *dr = Devtp[i].rdev; |
| *ir = Devtp[i].inode; |
| return(1); |
| } |
| } |
| |
| # if defined(HASDCACHE) |
| if (DCunsafe) { |
| (void) rereaddev(); |
| goto lkup_dev_tty_again; |
| } |
| # endif /* defined(HASDCACHE) */ |
| |
| return(-1); |
| } |
| #endif /* defined(HASFDESCFS) && HASFDESCFS==1 */ |
| |
| |
| #if defined(HASKQUEUE) |
| /* |
| * process_kqueue() -- process kqueue file |
| * |
| * Strictly speaking this function should appear in dfile.c, because it is |
| * a file processing function. However, the Net and Open BSD sources don't |
| * require a dfile.c, so this is the next best location for the function. |
| */ |
| |
| void |
| process_kqueue(ka) |
| KA_T ka; /* kqueue file structure address */ |
| { |
| struct kqueue kq; /* kqueue structure */ |
| |
| (void) snpf(Lf->type, sizeof(Lf->type), "KQUEUE"); |
| enter_dev_ch(print_kptr(ka, (char *)NULL, 0)); |
| if (!ka || kread(ka, (char *)&kq, sizeof(kq))) |
| return; |
| (void) snpf(Namech, Namechl, "count=%d, state=%#x", kq.kq_count, |
| kq.kq_state); |
| enter_nm(Namech); |
| } |
| #endif /* defined(HASKQUEUE) */ |
| |
| |
| /* |
| * process_node() - process vnode |
| */ |
| |
| void |
| process_node(va) |
| KA_T va; /* vnode kernel space address */ |
| { |
| dev_t dev, rdev; |
| unsigned char devs; |
| unsigned char rdevs; |
| char dev_ch[32], *ep; |
| struct inode *i; |
| struct nfsnode *n; |
| size_t sz; |
| char *ty; |
| enum vtype type; |
| struct vnode *v, vb; |
| struct l_vfs *vfs; |
| |
| #if FREEBSDV>=2000 |
| struct inode ib; |
| struct nfsnode nb; |
| # if FREEBSDV>=4000 |
| # if FREEBSDV<5000 |
| struct specinfo si; |
| # else /* FREEBSDV>=5000 */ |
| # if !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) |
| struct cdev si; |
| # endif /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ |
| # endif /* FREEBSDV<5000 */ |
| # endif /* FREEBSDV>=4000 */ |
| #endif /* FREEBSDV>=2000 */ |
| |
| #if FREEBSDV<5000 |
| struct mfsnode *m; |
| # if FREEBSDV>=2000 |
| struct mfsnode mb; |
| # endif /* FREEBSDV>=2000 */ |
| #endif /* FREEBSDV<5000 */ |
| |
| #if defined(HAS9660FS) |
| dev_t iso_dev; |
| int iso_dev_def, iso_stat; |
| INODETYPE iso_ino; |
| long iso_links; |
| SZOFFTYPE iso_sz; |
| #endif /* defined(HAS9660FS) */ |
| |
| #if defined(HASFDESCFS) |
| struct fdescnode *f; |
| |
| # if HASFDESCFS==1 |
| static dev_t f_tty_dev; |
| static INODETYPE f_tty_ino; |
| static int f_tty_s = 0; |
| # endif /* HASFDESCFS==1 */ |
| |
| # if FREEBSDV>=2000 |
| struct fdescnode fb; |
| # endif /* FREEBSDV>=2000 */ |
| |
| #endif /* defined(HASFDESCFS) */ |
| |
| #if FREEBSDV>=5000 |
| # if defined(HAS_UFS1_2) |
| int ufst; |
| struct ufsmount um; |
| struct ufs1_dinode d1; |
| struct ufs2_dinode d2; |
| # endif /* !defined(HAS_UFS1_2) */ |
| |
| # if !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) |
| struct cdev cd; |
| # endif /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ |
| |
| int cds; |
| struct devfs_dirent de; |
| struct devfs_dirent *d; |
| char vtbuf[32]; |
| char *vtbp; |
| enum vtagtype { VT_DEVFS, VT_FDESC, VT_ISOFS, VT_PSEUDOFS, VT_NFS, |
| VT_NULL, VT_UFS, VT_ZFS, VT_UNKNOWN |
| }; |
| #endif /* FREEBSDV>=5000 */ |
| |
| #if defined(HASNULLFS) |
| # if !defined(HASPRINTDEV) |
| char dbuf[32]; |
| # endif /* !defined(HASPRINTDEV) */ |
| char *dp, *np, tbuf[1024]; |
| struct null_node nu; |
| int sc = 0; |
| #endif /* defined(HASNULLFS) */ |
| |
| #if defined(HASPROCFS) |
| struct pfsnode *p; |
| struct procfsid *pfi; |
| static int pgsz = -1; |
| struct vmspace vm; |
| |
| # if FREEBSDV>=2000 |
| struct pfsnode pb; |
| # endif /* FREEBSDV>=2000 */ |
| #endif /* defined(HASPROCFS) */ |
| |
| #if defined(HASPSEUDOFS) |
| struct pfs_node pn; |
| struct pfs_node *pnp; |
| #endif /* defined(HASPSEUDOFS) */ |
| |
| #if defined(HAS_ZFS) |
| zfs_info_t *z = (zfs_info_t *)NULL; |
| zfs_info_t zi; |
| char *zm = (char *)NULL; |
| #else /* !defined(HAS_ZFS) */ |
| static unsigned char zw = 0; |
| #endif /* HAS_VFS */ |
| |
| enum vtagtype vtag; /* placed here to use the |
| * artificial vtagtype |
| * definition required for |
| * FREEBSDV>=5000 */ |
| |
| #if defined(HASNULLFS) |
| |
| process_overlaid_node: |
| |
| if (++sc > 1024) { |
| (void) snpf(Namech, Namechl, "too many overlaid nodes"); |
| enter_nm(Namech); |
| return; |
| } |
| #endif /* defined(HASNULLFS) */ |
| |
| /* |
| * Initialize miscellaneous variables. This is done so that processing an |
| * overlaid node will be a fresh start. |
| */ |
| devs = rdevs = 0; |
| i = (struct inode *)NULL; |
| n = (struct nfsnode *)NULL; |
| Namech[0] = '\0'; |
| |
| #if defined(HAS9660FS) |
| iso_dev_def = iso_stat = 0; |
| #endif /* defined(HAS9660FS) */ |
| |
| #if defined(HASFDESCFS) |
| f = (struct fdescnode *)NULL; |
| #endif /* defined(HASFDESCFS) */ |
| |
| #if FREEBSDV<5000 |
| m = (struct mfsnode *)NULL; |
| #else /* FREEBSDV>=5000 */ |
| cds = 0; |
| d = (struct devfs_dirent *)NULL; |
| # if defined(HAS_UFS1_2) |
| ufst = 0; |
| # endif /* !defined(HAS_UFS1_2) */ |
| #endif /* FREEBSDV<5000 */ |
| |
| #if defined(HASPROCFS) |
| p = (struct pfsnode *)NULL; |
| #endif /* defined(HASPROCFS) */ |
| |
| #if defined(HASPSEUDOFS) |
| pnp = (struct pfs_node *)NULL; |
| #endif /* defined(HASPSEUDOFS) */ |
| |
| #if defined(HAS_ZFS) |
| z = (zfs_info_t *)NULL; |
| zm = (char *)NULL; |
| #endif /* defined(HAS_ZFS) */ |
| |
| /* |
| * Read the vnode. |
| */ |
| if ( ! va) { |
| enter_nm("no vnode address"); |
| return; |
| } |
| v = &vb; |
| if (readvnode(va, v)) { |
| enter_nm(Namech); |
| return; |
| } |
| |
| #if defined(HASNCACHE) |
| Lf->na = va; |
| # if defined(HASNCVPID) |
| Lf->id = v->v_id; |
| # endif /* defined(HASNCVPID) */ |
| #endif /* defined(HASNCACHE) */ |
| |
| #if defined(HASFSTRUCT) |
| Lf->fna = va; |
| Lf->fsv |= FSV_NI; |
| #endif /* defined(HASFSTRUCT) */ |
| |
| /* |
| * Get the vnode type. |
| */ |
| if (!v->v_mount) |
| vfs = (struct l_vfs *)NULL; |
| else { |
| vfs = readvfs((KA_T)v->v_mount); |
| if (vfs) { |
| |
| #if defined(MOUNT_NONE) |
| switch (vfs->type) { |
| case MOUNT_NFS: |
| Ntype = N_NFS; |
| break; |
| |
| # if defined(HASPROCFS) |
| case MOUNT_PROCFS: |
| Ntype = N_PROC; |
| break; |
| # endif /* defined(HASPROCFS) */ |
| } |
| #else /* !defined(MOUNT_NONE) */ |
| if (strcasecmp(vfs->typnm, "nfs") == 0) |
| Ntype = N_NFS; |
| |
| # if defined(HASPROCFS) |
| else if (strcasecmp(vfs->typnm, "procfs") == 0) |
| Ntype = N_PROC; |
| # endif /* defined(HASPROCFS) */ |
| |
| # if defined(HASPSEUDOFS) |
| else if (strcasecmp(vfs->typnm, "pseudofs") == 0) |
| Ntype = N_PSEU; |
| # endif /* defined(HASPSEUDOFS) */ |
| #endif /* defined(MOUNT_NONE) */ |
| |
| } |
| } |
| if (Ntype == N_REGLR) { |
| switch (v->v_type) { |
| case VFIFO: |
| Ntype = N_FIFO; |
| break; |
| default: |
| break; |
| } |
| } |
| |
| #if FREEBSDV>=5000 |
| /* |
| * For FreeBSD 5 and above VCHR and VBLK vnodes get the v_rdev structure. |
| */ |
| if (((v->v_type == VCHR) || (v->v_type == VBLK)) |
| && v->v_rdev |
| |
| # if !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) |
| && !kread((KA_T)v->v_rdev, (char *)&cd, sizeof(cd)) |
| # endif /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ |
| |
| ) { |
| cds = 1; |
| } |
| #endif /* FREEBSDV>=5000 */ |
| |
| /* |
| * Define the specific node pointer. |
| */ |
| |
| #if FREEBSDV>=5000 |
| /* |
| * Get the pseudo vnode tag type for FreeBSD >= 5. |
| */ |
| vtag = VT_UNKNOWN; |
| if (v->v_tag && !kread((KA_T)v->v_tag, (char *)&vtbuf, sizeof(vtbuf))) |
| { |
| vtbuf[sizeof(vtbuf) - 1] = '\0'; |
| vtbp = vtbuf; |
| if (!strcmp(vtbuf, "ufs")) |
| vtag = VT_UFS; |
| else if (!strcmp(vtbuf, "zfs")) { |
| |
| #if !defined(HAS_ZFS) |
| if (!Fwarn && !zw) { |
| (void) fprintf(stderr, |
| "%s: WARNING: no ZFS support has been defined.\n", |
| Pn); |
| (void) fprintf(stderr, |
| " See 00FAQ for more information.\n"); |
| zw = 1; |
| } |
| #else /* defined(HAS_ZFS) */ |
| vtag = VT_ZFS; |
| #endif /* !defined(HAS_ZFS) */ |
| |
| } else if (!strcmp(vtbuf, "devfs")) |
| vtag = VT_DEVFS; |
| else if (!strcmp(vtbuf, "nfs")) |
| vtag = VT_NFS; |
| else if (!strcmp(vtbuf, "isofs")) |
| vtag = VT_ISOFS; |
| else if (!strcmp(vtbuf, "pseudofs")) |
| vtag = VT_PSEUDOFS; |
| else if (!strcmp(vtbuf, "null")) |
| vtag = VT_NULL; |
| else if (!strcmp(vtbuf, "fdesc")) |
| vtag = VT_FDESC; |
| } else |
| vtbp = "(unknown)"; |
| #else /* FREEBSDV<5000 */ |
| vtag = v->v_tag; |
| #endif /* FREEBSDV>=5000 */ |
| |
| switch (vtag) { |
| |
| #if FREEBSDV>=5000 |
| case VT_DEVFS: |
| if (!v->v_data |
| || kread((KA_T)v->v_data, (char *)&de, sizeof(de))) |
| { |
| (void) snpf(Namech, Namechl, "no devfs node: %s", |
| print_kptr((KA_T)v->v_data, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| d = &de; |
| if (v->v_type == VDIR) { |
| if (!d->de_dir |
| || kread((KA_T)d->de_dir, (char *)&de, sizeof(de))) { |
| (void) snpf(Namech, Namechl, "no devfs dir node: %s", |
| print_kptr((KA_T)d->de_dir, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| } |
| break; |
| #endif /* FREEBSDV>=5000 */ |
| |
| #if defined(HASFDESCFS) |
| case VT_FDESC: |
| |
| # if FREEBSDV<2000 |
| f = (struct fdescnode *)v->v_data; |
| # else /* FREEBSDV>=2000 */ |
| if (kread((KA_T)v->v_data, (char *)&fb, sizeof(fb)) != 0) { |
| (void) snpf(Namech, Namechl, "can't read fdescnode at: %s", |
| print_kptr((KA_T)v->v_data, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| f = &fb; |
| break; |
| # endif /* FREEBSDV<2000 */ |
| #endif /* defined(HASFDESCFS) */ |
| |
| #if defined(HAS9660FS) |
| case VT_ISOFS: |
| if (read_iso_node(v, &iso_dev, &iso_dev_def, &iso_ino, &iso_links, |
| &iso_sz)) |
| { |
| (void) snpf(Namech, Namechl, "no iso node: %s", |
| print_kptr((KA_T)v->v_data, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| iso_stat = 1; |
| break; |
| #endif /* defined(HAS9660FS) */ |
| |
| #if FREEBSDV<5000 |
| case VT_MFS: |
| |
| # if FREEBSDV<2000 |
| m = (struct mfsnode *)v->v_data; |
| # else /* FREEBSDV>=2000 */ |
| if (!v->v_data |
| || kread((KA_T)v->v_data, (char *)&mb, sizeof(mb))) { |
| (void) snpf(Namech, Namechl, "no mfs node: %s", |
| print_kptr((KA_T)v->v_data, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| m = &mb; |
| # endif /* FREEBSDV<2000 */ |
| #endif /* FREEBSDV<5000 */ |
| |
| break; |
| case VT_NFS: |
| |
| #if FREEBSDV<2000 |
| n = (struct nfsnode *)v->v_data; |
| #else /* FREEBSDV>=2000 */ |
| if (!v->v_data |
| || kread((KA_T)v->v_data, (char *)&nb, sizeof(nb))) { |
| (void) snpf(Namech, Namechl, "no nfs node: %s", |
| print_kptr((KA_T)v->v_data, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| n = &nb; |
| #endif /* FREEBSDV<2000 */ |
| |
| break; |
| |
| #if defined(HASNULLFS) |
| case VT_NULL: |
| if (sc == 1) { |
| |
| /* |
| * If this is the first null_node, enter a name addition containing |
| * the mounted-on directory, the file system name, and the device |
| * number. |
| */ |
| if (vfs && (vfs->dir || vfs->fsname || vfs->fsid.val[0])) { |
| if (vfs->fsid.val[0]) { |
| |
| #if defined(HASPRINTDEV) |
| dp = HASPRINTDEV(Lf, &dev); |
| #else /* !defined(HASPRINTDEV) */ |
| (void) snpf(dbuf, sizeof(dbuf) - 1, "%d,%d", |
| GET_MAJ_DEV(dev), GET_MIN_DEV(dev)); |
| dbuf[sizeof(dbuf) - 1] = '\0'; |
| dp = dbuf; |
| #endif /* defined(HASPRINTDEV) */ |
| |
| } else |
| dp = (char *)NULL; |
| (void) snpf(tbuf, sizeof(tbuf) - 1, |
| "(nullfs%s%s%s%s%s%s%s)", |
| (vfs && vfs->fsname) ? " " : "", |
| (vfs && vfs->fsname) ? vfs->fsname : "", |
| (vfs && vfs->dir) ? " on " : "", |
| (vfs && vfs->dir) ? vfs->dir : "", |
| (dp && vfs && vfs->dir) ? " (" : "", |
| (dp && vfs && vfs->dir) ? dp : "", |
| (dp && vfs && vfs->dir) ? ")" : ""); |
| tbuf[sizeof(tbuf) - 1] = '\0'; |
| np = tbuf; |
| } else |
| np = "(nullfs)"; |
| (void) add_nma(np, (int)strlen(np)); |
| } |
| if (!v->v_data |
| || kread((KA_T)v->v_data, (char *)&nu, sizeof(nu))) { |
| (void) snpf(Namech, Namechl, "can't read null_node at: %s", |
| print_kptr((KA_T)v->v_data, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| if (!nu.null_lowervp) { |
| (void) snpf(Namech, Namechl, "null_node overlays nothing"); |
| enter_nm(Namech); |
| return; |
| } |
| va = (KA_T)nu.null_lowervp; |
| goto process_overlaid_node; |
| #endif /* defined(HASNULLFS) */ |
| |
| #if defined(HASPROCFS) |
| case VT_PROCFS: |
| |
| # if FREEBSDV<2000 |
| p = (struct pfsnode *)v->v_data; |
| # else /* FREEBSDV>=2000 */ |
| if (!v->v_data |
| || kread((KA_T)v->v_data, (char *)&pb, sizeof(pb))) { |
| (void) snpf(Namech, Namechl, "no pfs node: %s", |
| print_kptr((KA_T)v->v_data, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| p = &pb; |
| # endif /* FREEBSDV<2000 */ |
| |
| break; |
| #endif /* defined(HASPROCFS) */ |
| |
| #if defined(HASPSEUDOFS) |
| case VT_PSEUDOFS: |
| if (!v->v_data |
| || kread((KA_T)v->v_data, (char *)&pn, sizeof(pn))) { |
| (void) snpf(Namech, Namechl, "no pfs_node: %s", |
| print_kptr((KA_T)v->v_data, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| pnp = &pn; |
| break; |
| #endif /* defined(HASPSEUDOFS) */ |
| |
| case VT_UFS: |
| |
| #if FREEBSDV<2000 |
| i = (struct inode *)v->v_data; |
| #else /* FREEBSDV>=2000 */ |
| if (!v->v_data |
| || kread((KA_T)v->v_data, (char *)&ib, sizeof(ib))) { |
| (void) snpf(Namech, Namechl, "no ufs node: %s", |
| print_kptr((KA_T)v->v_data, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| i = &ib; |
| |
| # if defined(HAS_UFS1_2) |
| if (i->i_ump && !kread((KA_T)i->i_ump, (char *)&um, sizeof(um))) { |
| if (um.um_fstype == UFS1) { |
| if (i->i_din1 |
| && !kread((KA_T)i->i_din1, (char *)&d1, sizeof(d1))) |
| ufst = 1; |
| } else { |
| if (i->i_din2 |
| && !kread((KA_T)i->i_din2, (char *)&d2, sizeof(d2))) |
| ufst = 2; |
| } |
| } |
| # endif /* defined(HAS_UFS1_2) */ |
| #endif /* FREEBSDV<2000 */ |
| |
| #if defined(HAS_V_LOCKF) |
| if (v->v_lockf) |
| (void) get_lock_state((KA_T)v->v_lockf); |
| #else /* !defined(HAS_V_LOCKF) */ |
| if (i->i_lockf) |
| (void) get_lock_state((KA_T)i->i_lockf); |
| #endif /* defined(HAS_V_LOCKF) */ |
| |
| break; |
| |
| #if defined(HAS_ZFS) |
| case VT_ZFS: |
| if (!v->v_data |
| || (zm = readzfsnode((KA_T)v->v_data, &zi, |
| ((v->v_vflag & VV_ROOT) ? 1 : 0))) |
| ) { |
| (void) snpf(Namech, Namechl, "%s: %s", zm, |
| print_kptr((KA_T)v->v_data, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| z = &zi; |
| |
| #if defined(HAS_V_LOCKF) |
| if (v->v_lockf) |
| (void) get_lock_state((KA_T)v->v_lockf); |
| #else /* !defined(HAS_V_LOCKF) */ |
| if (z->lockf) |
| (void) get_lock_state((KA_T)z->lockf); |
| #endif /* defined(HAS_V_LOCKF) */ |
| |
| break; |
| #endif /* defined(HAS_ZFS) */ |
| |
| default: |
| if (v->v_type == VBAD || v->v_type == VNON) |
| break; |
| |
| #if FREEBSDV<5000 |
| (void) snpf(Namech,Namechl,"unknown file system type: %d",v->v_tag); |
| #else /* FREEBSDV>=5000 */ |
| (void) snpf(Namech, Namechl, "unknown file system type: %s", vtbp); |
| #endif /* FREEBSDV<5000 */ |
| |
| enter_nm(Namech); |
| return; |
| } |
| /* |
| * Get device and type for printing. |
| */ |
| type = v->v_type; |
| if (n) { |
| dev = n->n_vattr.va_fsid; |
| devs = 1; |
| if ((type == VCHR) || (type == VBLK)) { |
| rdev = n->n_vattr.va_rdev; |
| rdevs = 1; |
| } |
| } else if (i) { |
| |
| #if FREEBSDV>=4000 |
| if (i->i_dev |
| |
| # if !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) |
| && !kread((KA_T)i->i_dev, (char *)&si, sizeof(si)) |
| # endif /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ |
| |
| ) { |
| |
| # if defined(HAS_NO_SI_UDEV) |
| # if defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) |
| dev = Dev2Udev((KA_T)i->i_dev); |
| # else /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ |
| dev = Dev2Udev(&si); |
| # endif /* defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) */ |
| # else /* !defined(HAS_NO_SI_UDEV) */ |
| dev = si.si_udev; |
| # endif /* defined(HAS_NO_SI_UDEV) */ |
| |
| devs = 1; |
| } |
| #else /* FREEBSDV<4000 */ |
| dev = i->i_dev; |
| devs = 1; |
| #endif /* FREEBSDV>=4000 */ |
| |
| if ((type == VCHR) || (type == VBLK)) { |
| |
| #if FREEBSDV>=5000 |
| # if defined(HAS_UFS1_2) |
| if (ufst == 1) { |
| rdev = d1.di_rdev; |
| rdevs = 1; |
| } else if (ufst == 2) { |
| rdev = d2.di_rdev; |
| rdevs = 1; |
| } else |
| # endif /* defined(HAS_UFS1_2) */ |
| |
| if (cds) { |
| |
| # if defined(HAS_NO_SI_UDEV) |
| # if defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) |
| rdev = Dev2Udev((KA_T)v->v_rdev); |
| # else /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ |
| rdev = Dev2Udev(&cd); |
| # endif /* defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) */ |
| # else /* !defined(HAS_NO_SI_UDEV) */ |
| rdev = cd.si_udev; |
| # endif /* defined(HAS_NO_SI_UDEV) */ |
| |
| rdevs = 1; |
| } |
| #else /* FREEBSDV<5000 */ |
| rdev = i->i_rdev; |
| rdevs = 1; |
| #endif /* FREEBSDV>=5000 */ |
| |
| } |
| } |
| |
| #if defined(HAS_ZFS) |
| else if (z) { |
| |
| /* |
| * Record information returned by readzfsnode(). |
| */ |
| if (vfs) { |
| dev = vfs->fsid.val[0]; |
| devs = 1; |
| } |
| if ((type == VCHR) || (type == VBLK)) { |
| if (z->rdev_def) { |
| rdev = z->rdev; |
| rdevs = 1; |
| } |
| } |
| } |
| #endif /* defined(HAS_ZFS) */ |
| |
| #if defined(HASFDESCFS) && (defined(HASFDLINK) || HASFDESCFS==1) |
| else if (f) { |
| |
| # if defined(HASFDLINK) |
| if (f->fd_link |
| && kread((KA_T)f->fd_link, Namech, Namechl - 1) == 0) |
| Namech[Namechl - 1] = '\0'; |
| |
| # if HASFDESCFS==1 |
| else |
| # endif /* HASFDESFS==1 */ |
| # endif /* defined(HASFDLINK) */ |
| |
| # if HASFDESCFS==1 |
| if (f->fd_type == Fctty) { |
| if (f_tty_s == 0) |
| f_tty_s = lkup_dev_tty(&f_tty_dev, &f_tty_ino); |
| if (f_tty_s == 1) { |
| dev = f_tty_dev; |
| Lf->inode = f_tty_ino; |
| devs = Lf->inp_ty = 1; |
| } |
| } |
| # endif /* HASFDESFS==1 */ |
| |
| } |
| #endif /* defined(HASFDESCFS) && (defined(HASFDLINK) || HASFDESCFS==1) */ |
| |
| #if defined(HAS9660FS) |
| else if (iso_stat && iso_dev_def) { |
| dev = iso_dev; |
| devs = Lf->inp_ty = 1; |
| } |
| #endif /* defined(HAS9660FS) */ |
| |
| #if FREEBSDV>=5000 |
| else if (d) { |
| if (vfs) { |
| dev = vfs->fsid.val[0]; |
| devs = 1; |
| } else { |
| dev = DevDev; |
| devs = 1; |
| } |
| if ((type == VCHR)) { |
| |
| # if defined(HAS_UFS1_2) |
| if (ufst == 1) { |
| rdev = d1.di_rdev; |
| rdevs = 1; |
| } else if (ufst == 2) { |
| rdev = d2.di_rdev; |
| rdevs = 1; |
| } else |
| # endif /* defined(HAS_UFS1_2) */ |
| |
| if (cds) { |
| |
| # if defined(HAS_NO_SI_UDEV) |
| # if defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) |
| rdev = Dev2Udev((KA_T)v->v_rdev); |
| # else /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ |
| rdev = Dev2Udev(&cd); |
| # endif /* defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) */ |
| # else /* !defined(HAS_NO_SI_UDEV) */ |
| rdev = cd.si_udev; |
| # endif /* defined(HAS_NO_SI_UDEV) */ |
| |
| rdevs = 1; |
| } |
| } |
| } |
| #endif /* FREEBSDV>=5000 */ |
| |
| #if defined(HASPSEUDOFS) |
| else if (pnp) { |
| if (vfs) { |
| dev = vfs->fsid.val[0]; |
| devs = 1; |
| } |
| } |
| #endif /* defined(HASPSEUDOFS) */ |
| |
| /* |
| * Obtain the inode number. |
| */ |
| if (i) { |
| Lf->inode = (INODETYPE)i->i_number; |
| Lf->inp_ty = 1; |
| } |
| |
| #if defined(HAS_ZFS) |
| else if (z) { |
| if (z->ino_def) { |
| Lf->inode = z->ino; |
| Lf->inp_ty = 1; |
| } |
| } |
| #endif /* defined(HAS_ZFS) */ |
| |
| else if (n) { |
| Lf->inode = (INODETYPE)n->n_vattr.va_fileid; |
| Lf->inp_ty = 1; |
| } |
| |
| #if defined(HAS9660FS) |
| else if (iso_stat) { |
| Lf->inode = iso_ino; |
| Lf->inp_ty = 1; |
| } |
| #endif /* defined(HAS9660FS) */ |
| |
| #if defined(HASPROCFS) |
| # if FREEBSDV>=2000 |
| else if (p) { |
| Lf->inode = (INODETYPE)p->pfs_fileno; |
| Lf->inp_ty = 1; |
| } |
| # endif /* FREEBSDV>=2000 */ |
| #endif /* defined(HASPROCFS) */ |
| |
| #if defined(HASPSEUDOFS) |
| else if (pnp) { |
| Lf->inode = (INODETYPE)pnp->pn_fileno; |
| Lf->inp_ty = 1; |
| } |
| #endif /* defined(HASPSEUDOFS) */ |
| |
| #if FREEBSDV>=5000 |
| else if (d) { |
| Lf->inode = (INODETYPE)d->de_inode; |
| Lf->inp_ty = 1; |
| } |
| #endif /* FREEBSDV>=5000 */ |
| |
| /* |
| * Obtain the file size. |
| */ |
| if (Foffset) |
| Lf->off_def = 1; |
| else { |
| switch (Ntype) { |
| case N_FIFO: |
| if (!Fsize) |
| Lf->off_def = 1; |
| break; |
| case N_NFS: |
| if (n) { |
| Lf->sz = (SZOFFTYPE)n->n_vattr.va_size; |
| Lf->sz_def = 1; |
| } |
| break; |
| |
| #if defined(HASPROCFS) |
| case N_PROC: |
| |
| # if FREEBSDV<2000 |
| if (type == VDIR || !p || !p->pfs_vs |
| || kread((KA_T)p->pfs_vs, (char *)&vm, sizeof(vm))) |
| break; |
| if (pgsz < 0) |
| pgsz = getpagesize(); |
| Lf->sz = (SZOFFTYPE)((pgsz * vm.vm_tsize) |
| + (pgsz * vm.vm_dsize) |
| + (pgsz * vm.vm_ssize)); |
| Lf->sz_def = 1; |
| break; |
| # else /* FREEBSDV>=2000 */ |
| if (p) { |
| switch(p->pfs_type) { |
| case Proot: |
| case Pproc: |
| Lf->sz = (SZOFFTYPE)DEV_BSIZE; |
| Lf->sz_def = 1; |
| break; |
| case Pmem: |
| (void) getmemsz(p->pfs_pid); |
| break; |
| case Pregs: |
| Lf->sz = (SZOFFTYPE)sizeof(struct reg); |
| Lf->sz_def = 1; |
| break; |
| case Pfpregs: |
| Lf->sz = (SZOFFTYPE)sizeof(struct fpreg); |
| Lf->sz_def = 1; |
| break; |
| } |
| } |
| # endif /* FREEBSDV<2000 */ |
| #endif /* defined(HASPROCFS) */ |
| |
| #if defined(HASPSEUDOFS) |
| case N_PSEU: |
| Lf->sz = 0; |
| Lf->sz_def = 1; |
| break; |
| #endif /* defined(PSEUDOFS) */ |
| |
| case N_REGLR: |
| if (type == VREG || type == VDIR) { |
| if (i) { |
| |
| #if defined(HAS_UFS1_2) |
| if (ufst == 1) |
| Lf->sz = (SZOFFTYPE)d1.di_size; |
| else if (ufst == 2) |
| Lf->sz = (SZOFFTYPE)d2.di_size; |
| else |
| #endif /* defined(HAS_UFS1_2) */ |
| |
| Lf->sz = (SZOFFTYPE)i->i_size; |
| Lf->sz_def = 1; |
| } |
| |
| |
| #if defined(HAS_ZFS) |
| else if (z) { |
| if (z->sz_def) { |
| Lf->sz = z->sz; |
| Lf->sz_def = 1; |
| } |
| } |
| #endif /* defined(HAS_ZFS) */ |
| |
| #if FREEBSDV<5000 |
| else if (m) { |
| Lf->sz = (SZOFFTYPE)m->mfs_size; |
| Lf->sz_def = 1; |
| } |
| #endif /* FREEBSDV<5000 */ |
| |
| #if defined(HAS9660FS) |
| else if (iso_stat) { |
| Lf->sz = (SZOFFTYPE)iso_sz; |
| Lf->sz_def = 1; |
| } |
| #endif /* defined(HAS9660FS) */ |
| |
| } |
| else if ((type == VCHR || type == VBLK) && !Fsize) |
| Lf->off_def = 1; |
| break; |
| } |
| } |
| /* |
| * Record the link count. |
| */ |
| if (Fnlink) { |
| switch(Ntype) { |
| case N_NFS: |
| if (n) { |
| Lf->nlink = (long)n->n_vattr.va_nlink; |
| Lf->nlink_def = 1; |
| } |
| break; |
| case N_REGLR: |
| if (i) { |
| |
| #if defined(HASEFFNLINK) |
| Lf->nlink = (long)i->HASEFFNLINK; |
| #else /* !defined(HASEFFNLINK) */ |
| Lf->nlink = (long)i->i_nlink; |
| #endif /* defined(HASEFFNLINK) */ |
| |
| Lf->nlink_def = 1; |
| } |
| |
| #if defined(HAS_ZFS) |
| else if (z) { |
| if (z->nl_def) { |
| Lf->nlink = z->nl; |
| Lf->nlink_def = 1; |
| } |
| } |
| #endif /* defined(HAS_ZFS) */ |
| |
| #if defined(HAS9660FS) |
| else if (iso_stat) { |
| Lf->nlink = iso_links; |
| Lf->nlink_def = 1; |
| } |
| #endif /* defined(HAS9660FS) */ |
| |
| #if FREEBSDV>=5000 |
| else if (d) { |
| Lf->nlink = d->de_links; |
| Lf->nlink_def = 1; |
| } |
| #endif /* FREEBSDV>=5000 */ |
| |
| break; |
| |
| #if defined(HASPSEUODOFS) |
| case N_PSEU: |
| if (pnp) { |
| Lf->nlink = 1L; |
| Lf->nlink_def = 1; |
| } |
| break; |
| #endif /* defined(HASPSEUODOFS) */ |
| |
| } |
| if (Lf->nlink_def && Nlink && (Lf->nlink < Nlink)) |
| Lf->sf |= SELNLINK; |
| } |
| /* |
| * Record an NFS file selection. |
| */ |
| if (Ntype == N_NFS && Fnfs) |
| Lf->sf |= SELNFS; |
| /* |
| * Save the file system names. |
| */ |
| if (vfs) { |
| Lf->fsdir = vfs->dir; |
| Lf->fsdev = vfs->fsname; |
| } |
| /* |
| * Save the device numbers and their states. |
| * |
| * Format the vnode type, and possibly the device name. |
| */ |
| Lf->dev = dev; |
| Lf->dev_def = devs; |
| Lf->rdev = rdev; |
| Lf->rdev_def = rdevs; |
| switch (type) { |
| case VNON: |
| ty ="VNON"; |
| break; |
| case VREG: |
| case VDIR: |
| ty = (type == VREG) ? "VREG" : "VDIR"; |
| break; |
| case VBLK: |
| ty = "VBLK"; |
| Ntype = N_BLK; |
| break; |
| case VCHR: |
| ty = "VCHR"; |
| Ntype = N_CHR; |
| break; |
| case VLNK: |
| ty = "VLNK"; |
| break; |
| |
| #if defined(VSOCK) |
| case VSOCK: |
| ty = "SOCK"; |
| break; |
| #endif /* defined(VSOCK) */ |
| |
| case VBAD: |
| ty = "VBAD"; |
| break; |
| case VFIFO: |
| ty = "FIFO"; |
| break; |
| default: |
| (void) snpf(Lf->type, sizeof(Lf->type), "%04o", (type & 0xfff)); |
| ty = (char *)NULL; |
| } |
| if (ty) |
| (void) snpf(Lf->type, sizeof(Lf->type), "%s", ty); |
| Lf->ntype = Ntype; |
| /* |
| * Handle some special cases: |
| * |
| * ioctl(fd, TIOCNOTTY) files; |
| * memory node files; |
| * /proc files. |
| */ |
| |
| if (type == VBAD) |
| (void) snpf(Namech, Namechl, "(revoked)"); |
| |
| #if FREEBSDV<5000 |
| else if (m) { |
| Lf->dev_def = Lf->rdev_def = 0; |
| (void) snpf(Namech, Namechl, "%#x", m->mfs_baseoff); |
| (void) snpf(dev_ch, sizeof(dev_ch), " memory"); |
| enter_dev_ch(dev_ch); |
| } |
| #endif /* FREEBSDV<5000 */ |
| |
| |
| #if defined(HASPROCFS) |
| else if (p) { |
| Lf->dev_def = Lf->rdev_def = 0; |
| |
| # if FREEBSDV<2000 |
| if (type == VDIR) |
| (void) snpf(Namech, Namechl, "/%s", HASPROCFS); |
| else |
| (void) snpf(Namech, Namechl, "/%s/%0*d", HASPROCFS, PNSIZ, |
| p->pfs_pid); |
| enter_nm(Namech); |
| # else /* FREEBSDV>=2000 */ |
| ty = (char *)NULL; |
| (void) snpf(Namech, Namechl, "/%s", HASPROCFS); |
| switch (p->pfs_type) { |
| case Proot: |
| ty = "PDIR"; |
| break; |
| case Pproc: |
| ep = endnm(&sz); |
| (void) snpf(ep, sz, "/%d", p->pfs_pid); |
| ty = "PDIR"; |
| break; |
| case Pfile: |
| ep = endnm(&sz); |
| (void) snpf(ep, sz, "/%d/file", p->pfs_pid); |
| ty = "PFIL"; |
| break; |
| case Pmem: |
| ep = endnm(&sz); |
| (void) snpf(ep, sz, "/%d/mem", p->pfs_pid); |
| ty = "PMEM"; |
| break; |
| case Pregs: |
| ep = endnm(&sz); |
| (void) snpf(ep, sz, "/%d/regs", p->pfs_pid); |
| ty = "PREG"; |
| break; |
| case Pfpregs: |
| ep = endnm(&sz); |
| (void) snpf(ep, sz, "/%d/fpregs", p->pfs_pid); |
| ty = "PFPR"; |
| break; |
| case Pctl: |
| ep = endnm(&sz); |
| (void) snpf(ep, sz, "/%d/ctl", p->pfs_pid); |
| ty = "PCTL"; |
| break; |
| case Pstatus: |
| ep = endnm(&sz); |
| (void) snpf(ep, sz, "/%d/status", p->pfs_pid); |
| ty = "PSTA"; |
| break; |
| case Pnote: |
| ep = endnm(&sz); |
| (void) snpf(ep, sz, "/%d/note", p->pfs_pid); |
| ty = "PNTF"; |
| break; |
| case Pnotepg: |
| ep = endnm(&sz); |
| (void) snpf(ep, sz, "/%d/notepg", p->pfs_pid); |
| ty = "PGID"; |
| break; |
| |
| # if FREEBSDV>=3000 |
| case Pmap: |
| ep = endnm(&sz); |
| (void) snpf(ep, sz, "/%d/map", p->pfs_pid); |
| ty = "PMAP"; |
| break; |
| case Ptype: |
| ep = endnm(&sz); |
| (void) snpf(ep, sz, "/%d/etype", p->pfs_pid); |
| ty = "PETY"; |
| break; |
| # endif /* FREEBSDV>=3000 */ |
| |
| } |
| if (ty) |
| (void) snpf(Lf->type, sizeof(Lf->type), "%s", ty); |
| enter_nm(Namech); |
| |
| # endif /* FREEBSDV<2000 */ |
| } |
| #endif /* defined(HASPROCFS) */ |
| |
| #if defined(HASBLKDEV) |
| /* |
| * If this is a VBLK file and it's missing an inode number, try to |
| * supply one. |
| */ |
| if ((Lf->inp_ty == 0) && (type == VBLK)) |
| find_bl_ino(); |
| #endif /* defined(HASBLKDEV) */ |
| |
| /* |
| * If this is a VCHR file and it's missing an inode number, try to |
| * supply one. |
| */ |
| if ((Lf->inp_ty == 0) && (type == VCHR)) |
| find_ch_ino(); |
| /* |
| * Test for specified file. |
| */ |
| |
| #if defined(HASPROCFS) |
| if (Ntype == N_PROC) { |
| if (Procsrch) { |
| Procfind = 1; |
| Lf->sf |= SELNM; |
| } else { |
| for (pfi = Procfsid; pfi; pfi = pfi->next) { |
| if ((pfi->pid && pfi->pid == p->pfs_pid) |
| |
| # if defined(HASPINODEN) |
| || (Lf->inp_ty == 1 && Lf->inode == pfi->inode) |
| # else /* !defined(HASPINODEN) */ |
| if (pfi->pid == p->pfs_pid) |
| # endif /* defined(HASPINODEN) */ |
| |
| ) { |
| pfi->f = 1; |
| if (!Namech[0]) |
| (void) snpf(Namech, Namechl, "%s", pfi->nm); |
| Lf->sf |= SELNM; |
| break; |
| } |
| } |
| } |
| } else |
| #endif /* defined(HASPROCFS) */ |
| |
| { |
| if (Sfile && is_file_named((char *)NULL, |
| ((type == VCHR) || (type == VBLK)) ? 1 |
| : 0)) |
| Lf->sf |= SELNM; |
| } |
| /* |
| * Enter name characters. |
| */ |
| if (Namech[0]) |
| enter_nm(Namech); |
| } |
| |
| |
| #if FREEBSDV>=2020 |
| /* |
| * process_pipe() - process a file structure whose type is DTYPE_PIPE |
| */ |
| |
| void |
| process_pipe(pa) |
| KA_T pa; /* pipe structure address */ |
| { |
| char dev_ch[32], *ep; |
| struct pipe p; |
| size_t sz; |
| |
| if (!pa || kread(pa, (char *)&p, sizeof(p))) { |
| (void) snpf(Namech, Namechl, |
| "can't read DTYPE_PIPE pipe struct: %s", |
| print_kptr((KA_T)pa, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| (void) snpf(Lf->type, sizeof(Lf->type), "PIPE"); |
| (void) snpf(dev_ch, sizeof(dev_ch), "%s", |
| print_kptr(pa, (char *)NULL, 0)); |
| enter_dev_ch(dev_ch); |
| if (Foffset) |
| Lf->off_def = 1; |
| else { |
| Lf->sz = (SZOFFTYPE)p.pipe_buffer.size; |
| Lf->sz_def = 1; |
| } |
| if (p.pipe_peer) |
| (void) snpf(Namech, Namechl, "->%s", |
| print_kptr((KA_T)p.pipe_peer, (char *)NULL, 0)); |
| else |
| Namech[0] = '\0'; |
| if (p.pipe_buffer.cnt) { |
| ep = endnm(&sz); |
| (void) snpf(ep, sz, ", cnt=%d", p.pipe_buffer.cnt); |
| } |
| if (p.pipe_buffer.in) { |
| ep = endnm(&sz); |
| (void) snpf(ep, sz, ", in=%d", p.pipe_buffer.in); |
| } |
| if (p.pipe_buffer.out) { |
| ep = endnm(&sz); |
| (void) snpf(ep, sz, ", out=%d", p.pipe_buffer.out); |
| } |
| /* |
| * Enter name characters. |
| */ |
| if (Namech[0]) |
| enter_nm(Namech); |
| } |
| #endif /* FREEBSDV>=2020 */ |