Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Jan 2018 21:59:13 +0000 (UTC)
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r328149 - stable/11/usr.bin/hexdump
Message-ID:  <201801182159.w0ILxDSS019416@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kevans
Date: Thu Jan 18 21:59:13 2018
New Revision: 328149
URL: https://svnweb.freebsd.org/changeset/base/328149

Log:
  MFC r327567: hexdump(1): Speed up -s flag on devices
  
  Using the -s flag on devices is extraordinarily slow due to using fseek(3) a
  little too conservatively. Address this by using fseek on character/block
  devices as well, falling back to getchar(3) only if we fail to seek or we're
  operating on tape drives, where fseek may succeed while not actually being
  supported.
  
  PR:		86485

Modified:
  stable/11/usr.bin/hexdump/display.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/usr.bin/hexdump/display.c
==============================================================================
--- stable/11/usr.bin/hexdump/display.c	Thu Jan 18 21:53:07 2018	(r328148)
+++ stable/11/usr.bin/hexdump/display.c	Thu Jan 18 21:59:13 2018	(r328149)
@@ -36,6 +36,8 @@ static char sccsid[] = "@(#)display.c	8.1 (Berkeley) 6
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/ioctl.h>
 #include <sys/stat.h>
 
 #include <ctype.h>
@@ -52,6 +54,7 @@ static off_t address;			/* address/offset in stream */
 static off_t eaddress;			/* end address */
 
 static void print(PR *, u_char *);
+static void noseek(void);
 
 void
 display(void)
@@ -368,7 +371,7 @@ next(char **argv)
 void
 doskip(const char *fname, int statok)
 {
-	int cnt;
+	int type;
 	struct stat sb;
 
 	if (statok) {
@@ -380,16 +383,37 @@ doskip(const char *fname, int statok)
 			return;
 		}
 	}
-	if (statok && S_ISREG(sb.st_mode)) {
-		if (fseeko(stdin, skip, SEEK_SET))
+	if (!statok || S_ISFIFO(sb.st_mode) || S_ISSOCK(sb.st_mode)) {
+		noseek();
+		return;
+	}
+	if (S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) {
+		if (ioctl(fileno(stdin), FIODTYPE, &type))
 			err(1, "%s", fname);
-		address += skip;
-		skip = 0;
-	} else {
-		for (cnt = 0; cnt < skip; ++cnt)
-			if (getchar() == EOF)
-				break;
-		address += cnt;
-		skip -= cnt;
+		/*
+		 * Most tape drives don't support seeking,
+		 * yet fseek() would succeed.
+		 */
+		if (type & D_TAPE) {
+			noseek();
+			return;
+		}
 	}
+	if (fseeko(stdin, skip, SEEK_SET)) {
+		noseek();
+		return;
+	}
+	address += skip;
+	skip = 0;
+}
+
+static void
+noseek(void)
+{
+	int count;
+	for (count = 0; count < skip; ++count)
+		if (getchar() == EOF)
+			break;
+	address += count;
+	skip -= count;
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201801182159.w0ILxDSS019416>