Fix vi recovery mode.
authortb <tb@openbsd.org>
Sun, 20 Feb 2022 19:45:51 +0000 (19:45 +0000)
committertb <tb@openbsd.org>
Sun, 20 Feb 2022 19:45:51 +0000 (19:45 +0000)
From trondd, tested by various

ok afresh1

usr.bin/vi/common/exf.h
usr.bin/vi/common/line.c
usr.bin/vi/common/recover.c
usr.bin/vi/ex/ex.c
usr.bin/vi/vi/vi.c

index 3ae13e2..c47be00 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: exf.h,v 1.5 2015/04/24 21:48:31 brynet Exp $  */
+/*     $OpenBSD: exf.h,v 1.6 2022/02/20 19:45:51 tb Exp $      */
 
 /*-
  * Copyright (c) 1992, 1993, 1994
@@ -58,7 +58,8 @@ struct _exf {
 #define        F_RCV_NORM      0x020           /* Don't delete recovery files. */
 #define        F_RCV_ON        0x040           /* Recovery is possible. */
 #define        F_UNDO          0x080           /* No change since last undo. */
-       u_int8_t flags;
+#define        F_RCV_SYNC      0x100           /* Recovery file sync needed. */
+       u_int16_t flags;
 };
 
 /* Flags to db_get(). */
index d666822..7dfbdbf 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: line.c,v 1.15 2016/01/06 22:28:52 millert Exp $       */
+/*     $OpenBSD: line.c,v 1.16 2022/02/20 19:45:51 tb Exp $    */
 
 /*-
  * Copyright (c) 1992, 1993, 1994
@@ -218,7 +218,7 @@ db_delete(SCR *sp, recno_t lno)
        /* File now modified. */
        if (F_ISSET(ep, F_FIRSTMODIFY))
                (void)rcv_init(sp);
-       F_SET(ep, F_MODIFIED);
+       F_SET(ep, F_MODIFIED | F_RCV_SYNC);
 
        /* Update screen. */
        return (scr_update(sp, lno, LINE_DELETE, 1));
@@ -266,7 +266,7 @@ db_append(SCR *sp, int update, recno_t lno, char *p, size_t len)
        /* File now dirty. */
        if (F_ISSET(ep, F_FIRSTMODIFY))
                (void)rcv_init(sp);
-       F_SET(ep, F_MODIFIED);
+       F_SET(ep, F_MODIFIED | F_RCV_SYNC);
 
        /* Log change. */
        log_line(sp, lno + 1, LOG_LINE_APPEND);
@@ -334,7 +334,7 @@ db_insert(SCR *sp, recno_t lno, char *p, size_t len)
        /* File now dirty. */
        if (F_ISSET(ep, F_FIRSTMODIFY))
                (void)rcv_init(sp);
-       F_SET(ep, F_MODIFIED);
+       F_SET(ep, F_MODIFIED | F_RCV_SYNC);
 
        /* Log change. */
        log_line(sp, lno, LOG_LINE_INSERT);
@@ -394,7 +394,7 @@ db_set(SCR *sp, recno_t lno, char *p, size_t len)
        /* File now dirty. */
        if (F_ISSET(ep, F_FIRSTMODIFY))
                (void)rcv_init(sp);
-       F_SET(ep, F_MODIFIED);
+       F_SET(ep, F_MODIFIED | F_RCV_SYNC);
 
        /* Log after change. */
        log_line(sp, lno, LOG_LINE_RESET_F);
index c49cfec..3c09b72 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: recover.c,v 1.31 2021/10/24 21:24:17 deraadt Exp $    */
+/*     $OpenBSD: recover.c,v 1.32 2022/02/20 19:45:51 tb Exp $ */
 
 /*-
  * Copyright (c) 1993, 1994
@@ -252,6 +252,8 @@ rcv_sync(SCR *sp, u_int flags)
 
        /* Sync the file if it's been modified. */
        if (F_ISSET(ep, F_MODIFIED)) {
+               /* Clear recovery sync flag. */
+               F_CLR(ep, F_RCV_SYNC);
                if (ep->db->sync(ep->db, R_RECNOSYNC)) {
                        F_CLR(ep, F_RCV_ON | F_RCV_NORM);
                        msgq_str(sp, M_SYSERR,
index 912768e..357aa86 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ex.c,v 1.21 2016/03/19 00:21:28 mestre Exp $  */
+/*     $OpenBSD: ex.c,v 1.22 2022/02/20 19:45:51 tb Exp $      */
 
 /*-
  * Copyright (c) 1992, 1993, 1994
@@ -133,6 +133,10 @@ ex(SCR **spp)
                        msgq(sp, M_ERR, "Interrupted");
                }
 
+               /* Sync recovery if changes were made. */
+               if (F_ISSET(sp->ep, F_RCV_SYNC))
+                       rcv_sync(sp, 0);
+
                /*
                 * If the last command caused a restart, or switched screens
                 * or into vi, return.
index 9059ffe..167d133 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vi.c,v 1.22 2019/01/24 15:09:41 millert Exp $ */
+/*     $OpenBSD: vi.c,v 1.23 2022/02/20 19:45:51 tb Exp $      */
 
 /*-
  * Copyright (c) 1992, 1993, 1994
@@ -400,6 +400,10 @@ intr:                      CLR_INTERRUPT(sp);
                        (void)sp->gp->scr_rename(sp, sp->frp->name, 1);
                }
 
+               /* Sync recovery if changes were made. */
+               if (F_ISSET(sp->ep, F_RCV_SYNC))
+                       rcv_sync(sp, 0);
+
                /* If leaving vi, return to the main editor loop. */
                if (F_ISSET(gp, G_SRESTART) || F_ISSET(sp, SC_EX)) {
                        *spp = sp;