53e5ec8
--- tcsh-6.14.00/sh.h.wide-seeks	2005-03-25 19:46:41.000000000 +0100
53e5ec8
+++ tcsh-6.14.00/sh.h	2006-09-26 18:26:33.000000000 +0200
c584671
@@ -801,6 +801,13 @@
c584671
  * exactly one if the input is seekable and tell is available.
c584671
  * In other cases, the shell buffers enough blocks to keep all loops
c584671
  * in the buffer.
c584671
+ *
c584671
+ * If (WIDE_STRINGS && cantell), fbobp is always a byte offset, but
c584671
+ * (fseekp - fbobp) and (feobp - fbobp) are character offsets (usable for
c584671
+ * fbuf indexing).
c584671
+ *
c584671
+ * If (!cantell), all offsets are character offsets; if (!WIDE_STRINGS), there
c584671
+ * is no difference between byte and character offsets.
c584671
  */
c584671
 EXTERN struct Bin {
c584671
     off_t   Bfseekp;		/* Seek pointer, generally != lseek() value */
c584671
@@ -824,7 +831,7 @@
c584671
 #define TCSH_F_SEEK	 2		/* File seek */
c584671
 #define TCSH_E_SEEK	 3		/* Eval seek */
c584671
     union {
c584671
-	off_t _f_seek;
c584671
+	off_t _f_seek;		/* A byte offset if (cantell) */
c584671
 	Char* _c_seek;
c584671
     } fc;
c584671
 #define f_seek fc._f_seek
53e5ec8
--- tcsh-6.14.00/sh.lex.c.wide-seeks	2006-09-26 18:26:33.000000000 +0200
53e5ec8
+++ tcsh-6.14.00/sh.lex.c	2006-09-26 18:28:10.000000000 +0200
53e5ec8
@@ -1694,7 +1694,8 @@
53e5ec8
     char cbuf[BUFSIZE + 1];
53e5ec8
     ssize_t res, r;
53e5ec8
     size_t partial;
53e5ec8
-    
53e5ec8
+    int err;
53e5ec8
+
53e5ec8
     assert (nchars <= sizeof(cbuf)/sizeof(*cbuf));
53e5ec8
     USE(use_fclens);
53e5ec8
     res = 0;
53e5ec8
@@ -1736,7 +1737,11 @@
c584671
 	    memmove(cbuf, cbuf + i, partial - i);
c584671
 	partial -= i;
c584671
     } while (partial != 0 && nchars != 0);
c584671
-    /* Throwing away possible partial multibyte characters on error */
c584671
+    /* Throwing away possible partial multibyte characters on error if the
c584671
+       stream is not seekable */
53e5ec8
+    err = errno;
c584671
+    lseek(fildes, -(off_t)partial, L_INCR);
53e5ec8
+    errno = err;
c584671
     return res != 0 ? res : r;
c584671
 }
c584671
 
53e5ec8
@@ -1753,7 +1758,13 @@
c584671
 	    (void) lseek(SHIN, fseekp, L_SET);
c584671
 	}
c584671
 	if (fseekp == feobp) {
c584671
-	    fbobp = feobp;
c584671
+ 	    off_t bytes;
c584671
+ 	    size_t i;
c584671
+
c584671
+ 	    bytes = fbobp;
c584671
+ 	    for (i = 0; i < (size_t)(feobp - fbobp); i++)
c584671
+ 		bytes += fclens[i];
c584671
+ 	    fbobp = fseekp = feobp = bytes;
c584671
 	    do
c584671
 		c = wide_read(SHIN, fbuf[0], BUFSIZE, 1);
c584671
 	    while (c < 0 && errno == EINTR);
53e5ec8
@@ -1926,9 +1937,9 @@
c584671
 	return;
c584671
     case TCSH_F_SEEK:
c584671
 #ifdef WIDE_STRINGS
c584671
-	if (cantell && fseekp >= fbobp && fseekp < feobp) {
c584671
+	if (cantell && fseekp >= fbobp && fseekp <= feobp) {
c584671
 	    size_t i;
c584671
-	    
c584671
+
c584671
 	    l->f_seek = fbobp;
c584671
 	    for (i = 0; i < fseekp - fbobp; i++)
c584671
 		l->f_seek += fclens[i];