Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/vi/common Recovery of vi files has been broken for a...



details:   https://anonhg.NetBSD.org/src/rev/1a0e66fef67e
branches:  trunk
changeset: 545987:1a0e66fef67e
user:      christos <christos%NetBSD.org@localhost>
date:      Fri Apr 18 18:33:41 2003 +0000

description:
Recovery of vi files has been broken for a long while. This patch is a
stopgap measure to make vi recovery mostly functional on non-binary files.
The problem is that the db holding the recovery file can become corrupted,
in which case the data size of the line becomes huge. We use heuristics to
correct the size when we load a db in recovery mode. We could use a slightly
better heuristic (looking for ascii chars before correcting the length),
but it is not worth it. Another way would have been to trap the SEGV and
access data[len] and see if that worked, but that seemed exceedingly ugly.

diffstat:

 usr.bin/vi/common/line.c |  22 ++++++++++++++++++++--
 1 files changed, 20 insertions(+), 2 deletions(-)

diffs (49 lines):

diff -r 92b6a0919e9b -r 1a0e66fef67e usr.bin/vi/common/line.c
--- a/usr.bin/vi/common/line.c  Fri Apr 18 18:33:22 2003 +0000
+++ b/usr.bin/vi/common/line.c  Fri Apr 18 18:33:41 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: line.c,v 1.4 2002/04/09 01:47:31 thorpej Exp $ */
+/*     $NetBSD: line.c,v 1.5 2003/04/18 18:33:41 christos Exp $        */
 
 /*-
  * Copyright (c) 1992, 1993, 1994
@@ -16,13 +16,14 @@
 #if 0
 static const char sccsid[] = "@(#)line.c       10.21 (Berkeley) 9/15/96";
 #else
-__RCSID("$NetBSD: line.c,v 1.4 2002/04/09 01:47:31 thorpej Exp $");
+__RCSID("$NetBSD: line.c,v 1.5 2003/04/18 18:33:41 christos Exp $");
 #endif
 #endif /* not lint */
 
 #include <sys/types.h>
 #include <sys/queue.h>
 #include <sys/time.h>
+#include <sys/stat.h>
 
 #include <bitstring.h>
 #include <errno.h>
@@ -172,6 +173,23 @@
                return (1);
        }
 
+       if (F_ISSET(sp, SC_ARGRECOVER)) {
+               /*
+                * Don't trust the integrity of the db.
+                */
+               struct stat st;
+               int fd = (*ep->db->fd)(ep->db);
+               if (fd != -1 && fstat(fd, &st) != -1) {
+                       if (data.size > (size_t)st.st_size)
+                               data.size = strlen((const char *)data.data);
+               } else {
+                       /*
+                        * This breaks recovery of binary files
+                        */
+                       data.size = strlen((const char *)data.data);
+               }
+       }
+
        /* Reset the cache. */
        ep->c_lno = lno;
        ep->c_len = data.size;



Home | Main Index | Thread Index | Old Index