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