Subject: bin/36854: [dM] -o (show offset) option for fstat
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: netbsd-bugs
Date: 08/28/2007 03:35:00
>Number: 36854
>Category: bin
>Synopsis: [dM] -o (show offset) option for fstat
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Tue Aug 28 03:35:00 +0000 2007
>Originator: der Mouse
>Release: NetBSD 3.1
>Organization:
Dis-
>Environment:
Any 3.1. I've personally installed this patch on these four
machines:
System: NetBSD NetBSD-3-1.Rodents.Montreal.QC.CA 3.1 NetBSD 3.1 (GEN31) #5: Sun Aug 26 17:18:13 EDT 2007 mouse@NetBSD-3-1.Rodents.Montreal.QC.CA:/home/mouse/kbuild/GEN31 i386
Architecture: i386
Machine: i386
System: NetBSD Omega.Rodents.Montreal.QC.CA 3.1 NetBSD 3.1 (OMEGA) #5: Sat Aug 25 21:45:40 EDT 2007 mouse@Omega.Rodents.Montreal.QC.CA:/home/mouse/kbuild/OMEGA alpha
Architecture: alpha
Machine: alpha
System: NetBSD Shark.Rodents.Montreal.QC.CA 3.1 NetBSD 3.1 (SHARK) #0: Thu Aug 23 06:00:48 EDT 2007 mouse@Shark.Rodents.Montreal.QC.CA:/home/mouse/kbuild/SHARK shark
Architecture: arm
Machine: shark
System: NetBSD Darkstar.Rodents.Montreal.QC.CA 3.1 NetBSD 3.1 (DARKSTAR) #0: Fri Aug 24 10:39:03 EDT 2007 mouse@Darkstar.Rodents.Montreal.QC.CA:/home/mouse/kbuild/DARKSTAR hpcmips
Architecture: mipsel
Machine: hpcmips
>Description:
There is no way to get fstat to print the lseek offset from an
open file descriptor, even though it fetches that information
out of the kernel along with the rest of the fd's info. This
patch adds such a way (a -o command-line option).
>How-To-Repeat:
Wish for a way to see the lseek offset of an open file
descriptor (in my case, usually, to see how far something is
thorugh processing a large file).
Discover fstat doesn't have one, even though it fetches the
relevant information out of the kernel.
Get fed up with this inability and fix it.
>Fix:
Here's the patch, relative to the 3.1 sources (as indicated in
Release: and Environment: above).
diff -u -r src.stock/usr.bin/fstat/fstat.1 src/usr.bin/fstat/fstat.1
--- src.stock/usr.bin/fstat/fstat.1 2007-08-27 23:17:00.000000000 -0400
+++ src/usr.bin/fstat/fstat.1 2007-08-27 21:31:45.000000000 -0400
@@ -38,7 +38,7 @@
.Nd display status of open files
.Sh SYNOPSIS
.Nm
-.Op Fl fnv
+.Op Fl fnov
.Op Fl M Ar core
.Op Fl N Ar system
.Op Fl p Ar pid
@@ -81,6 +81,13 @@
in
.Pa /dev ;
and print the mode of the file in octal instead of symbolic form.
+.It Fl o
+Print the offset instead of the size, for descriptors open onto files.
+This does not affect the display for files printed for reasons other
+than open file descriptor; to help visually distinguish the two, when
+.Fl o
+is given and the size is printed nevertheless, it is prefixed with a
+.Sq \&* .
.It Fl p
Report all files open by the specified process.
.It Fl u
diff -u -r src.stock/usr.bin/fstat/fstat.c src/usr.bin/fstat/fstat.c
--- src.stock/usr.bin/fstat/fstat.c 2007-08-27 23:17:01.000000000 -0400
+++ src/usr.bin/fstat/fstat.c 2007-08-27 23:11:12.000000000 -0400
@@ -127,6 +127,7 @@
uflg; /* show files open by a particular (effective) user */
int checkfile; /* true if restricting to particular files or filesystems */
int nflg; /* (numerical) display f.s. and rdev as dev_t */
+int oflg; /* show offset, not size, for open files */
int vflg; /* display errors in locating kernel data objects etc... */
struct file **ofiles; /* buffer of pointers to file structures */
@@ -161,7 +162,7 @@
int ufs_filestat __P((struct vnode *, struct filestat *));
void usage __P((void));
char *vfilestat __P((struct vnode *, struct filestat *));
-void vtrans __P((struct vnode *, int, int));
+void vtrans __P((struct vnode *, int, int, int, off_t));
void ftrans __P((struct file *, int));
void ptrans __P((struct file *, struct pipe *, int));
@@ -182,7 +183,7 @@
arg = 0;
what = KERN_PROC_ALL;
nlistf = memf = NULL;
- while ((ch = getopt(argc, argv, "fnp:u:vN:M:")) != -1)
+ while ((ch = getopt(argc, argv, "fnop:u:vN:M:")) != -1)
switch((char)ch) {
case 'f':
fsflg = 1;
@@ -196,6 +197,9 @@
case 'n':
nflg = 1;
break;
+ case 'o':
+ oflg = 1;
+ break;
case 'p':
if (pflg++)
usage();
@@ -262,12 +266,10 @@
if ((p = kvm_getproc2(kd, what, arg, sizeof *p, &cnt)) == NULL) {
errx(1, "%s", kvm_geterr(kd));
}
- if (nflg)
- printf("%s",
-"USER CMD PID FD DEV INUM MODE SZ|DV R/W");
- else
- printf("%s",
-"USER CMD PID FD MOUNT INUM MODE SZ|DV R/W");
+ printf("USER CMD PID FD %s%s|DV R/W",
+ nflg ? " DEV INUM MODE "
+ : "MOUNT INUM MODE ",
+ oflg ? "OF" : "SZ" );
if (checkfile && fsflg == 0)
printf(" NAME\n");
else
@@ -338,11 +340,11 @@
* root directory vnode, if one
*/
if (cwdi.cwdi_rdir)
- vtrans(cwdi.cwdi_rdir, RDIR, FREAD);
+ vtrans(cwdi.cwdi_rdir, RDIR, FREAD, 0, 0);
/*
* current working directory vnode
*/
- vtrans(cwdi.cwdi_cdir, CDIR, FREAD);
+ vtrans(cwdi.cwdi_cdir, CDIR, FREAD, 0, 0);
/*
* ktrace vnode, if one
*/
@@ -384,7 +386,8 @@
}
switch (file.f_type) {
case DTYPE_VNODE:
- vtrans((struct vnode *)file.f_data, i, file.f_flag);
+ vtrans((struct vnode *)file.f_data, i, file.f_flag,
+ 1, file.f_offset);
break;
case DTYPE_SOCKET:
if (checkfile == 0)
@@ -464,10 +467,12 @@
}
void
-vtrans(vp, i, flag)
+vtrans(vp, i, flag, haveoffset, offset)
struct vnode *vp;
int i;
int flag;
+ int haveoffset;
+ off_t offset;
{
struct vnode vn;
struct filestat fst;
@@ -524,7 +529,13 @@
break;
}
default:
- printf(" %6lld", (long long)fst.size);
+ if (oflg)
+ if (haveoffset)
+ printf(" %6lld", (long long)offset);
+ else
+ printf(" *%5lld", (long long)fst.size);
+ else
+ printf(" %6lld", (long long)fst.size);
}
rw[0] = '\0';
if (flag & FREAD)
/~\ The ASCII der Mouse
\ / Ribbon Campaign
X Against HTML mouse@rodents.montreal.qc.ca
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B