I am currently writing regress tests for mg which use an mg startup file's capabilities to process mg commands to test mg's internal functions. In order to facilitate mg fitting into the OpenBSD regress test framework and be able to run via a cron job I have amended mg to be able to run with a pty. The diff below adds a 'batch' mode to mg via the '-b' command line option which will initialise a pty, run the specified file of mg commands and then exit.

There are other things to do to get mg fully integrated into the regress framework, but this diff is independant of them and offers a solution to no tty being available when being executed vi cron.

Comments/oks/criticisms?

Mark

Index: def.h
===================================================================
RCS file: /cvs/src/usr.bin/mg/def.h,v
retrieving revision 1.168
diff -u -p -r1.168 def.h
--- def.h       1 Mar 2021 10:51:14 -0000       1.168
+++ def.h       18 Mar 2021 15:58:39 -0000
@@ -750,6 +750,7 @@ extern int           doaudiblebell;
 extern int              dovisiblebell;
 extern int              dblspace;
 extern int              allbro;
+extern int              batch;
 extern char             cinfo[];
 extern char            *keystrings[];
 extern char             pat[NPAT];
Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/main.c,v
retrieving revision 1.88
diff -u -p -r1.88 main.c
--- main.c      23 Feb 2021 08:10:51 -0000      1.88
+++ main.c      18 Mar 2021 15:58:40 -0000
@@ -14,7 +14,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <termios.h>
 #include <unistd.h>
+#include <util.h>

 #include "def.h"
 #include "kbd.h"
@@ -33,6 +35,7 @@ int            doaudiblebell;                 /* audible bell 
t
 int             dovisiblebell;                 /* visible bell toggle  */
 int             dblspace;                      /* sentence end #spaces */
 int             allbro;                        /* all buffs read-only  */
+int             batch;                         /* for regress tests    */
 struct buffer  *curbp;                         /* current buffer       */
 struct buffer  *bheadp;                        /* BUFFER list head     */
 struct mgwin   *curwp;                         /* current window       */
@@ -40,6 +43,7 @@ struct mgwin  *wheadp;                        /* MGWIN listhea
 char            pat[NPAT];                     /* pattern              */

 static void     edinit(struct buffer *);
+static void     pty_init(void);
 static __dead void usage(void);

 extern char    *__progname;
@@ -48,8 +52,8 @@ extern void     closetags(void);
 static __dead void
 usage()
 {
-       fprintf(stderr, "usage: %s [-nR] [-f mode] [-u file] [+number] "
-           "[file ...]\n",
+       fprintf(stderr, "usage: %s [-nR] [-b file] [-f mode] [-u file] "
+           " [+number] [file ...]\n",
            __progname);
        exit(1);
 }
@@ -58,6 +62,7 @@ int
 main(int argc, char **argv)
 {
        char            *cp, *conffile = NULL, *init_fcn_name = NULL;
+       char            *batchfile = NULL;
        PF               init_fcn = NULL;
        int              o, i, nfiles;
        int              nobackups = 0;
@@ -67,8 +72,12 @@ main(int argc, char **argv)
            NULL) == -1)
                err(1, "pledge");

-       while ((o = getopt(argc, argv, "nRf:u:")) != -1)
+       while ((o = getopt(argc, argv, "nRb:f:u:")) != -1)
                switch (o) {
+               case 'b':
+                       batch = 1;
+                       batchfile = optarg;
+                       break;
                case 'R':
                        allbro = 1;
                        break;
@@ -87,6 +96,20 @@ main(int argc, char **argv)
                default:
                        usage();
                }
+
+       if (batch && (conffile != NULL)) {
+                fprintf(stderr, "%s: -b and -u are mutually exclusive.\n",
+                    __progname);
+                exit(1);
+       } else if (batch) {
+               pty_init();
+               conffile = batchfile;
+       }
+       if (conffile != NULL && access(conffile, R_OK) != 0) {
+                fprintf(stderr, "%s: Missing file: %s\n", __progname, 
conffile);
+                exit(1);
+       }
+
        argc -= optind;
        argv += optind;

@@ -136,6 +159,9 @@ main(int argc, char **argv)
        if ((cp = startupfile(NULL, conffile)) != NULL)
                (void)load(cp);

+       if (batch)
+               return (0);
+
        /*
         * Now ensure any default buffer modes from the startup file are
         * given to any files opened when parsing the startup file.
@@ -249,6 +275,26 @@ edinit(struct buffer *bp)
        wp->w_linep = wp->w_dotp = bp->b_headp;
        wp->w_ntrows = nrow - 2;             /* 2 = mode, echo.       */
        wp->w_rflag = WFMODE | WFFULL;               /* Full.                 */
+}
+
+/*
+ * Create pty for batch mode.
+ */
+static void
+pty_init(void)
+{
+       struct winsize   ws;
+       int master;
+       int slave;
+
+       memset(&ws, 0, sizeof(ws));
+       ws.ws_col = 80,
+       ws.ws_row = 24;
+ + openpty(&master, &slave, NULL, NULL, &ws);
+       login_tty(slave);
+
+       return;
 }

 /*
Index: mg.1
===================================================================
RCS file: /cvs/src/usr.bin/mg/mg.1,v
retrieving revision 1.120
diff -u -p -r1.120 mg.1
--- mg.1        23 Feb 2021 18:45:33 -0000      1.120
+++ mg.1        18 Mar 2021 15:58:40 -0000
@@ -10,6 +10,7 @@
 .Sh SYNOPSIS
 .Nm mg
 .Op Fl nR
+.Op Fl b Ar file
 .Op Fl f Ar mode
 .Op Fl u Ar file
 .Op + Ns Ar number
@@ -35,6 +36,12 @@ sign and the number).
 If a negative number is specified, the line number counts
 backwards from the end of the file i.e. +-1 will be the last
 line of the file, +-2 will be second last, and so on.
+.It Fl b Ar file
+Turn on batch mode and execute the
+.Nm
+commands found in the specified
+.Ar file
+and then terminate.
 .It Fl f Ar mode
 Run the mode command for all buffers created from
 arguments on the command line, including the
Index: tty.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/tty.c,v
retrieving revision 1.38
diff -u -p -r1.38 tty.c
--- tty.c       1 Mar 2021 10:51:14 -0000       1.38
+++ tty.c       18 Mar 2021 15:58:40 -0000
@@ -34,6 +34,7 @@
 #include <signal.h>
 #include <stdio.h>
 #include <term.h>
+#include <unistd.h>

 #include "def.h"

@@ -64,9 +65,15 @@ winchhandler(int sig)
 void
 ttinit(void)
 {
+       char *tty;
        int errret;

-       if (setupterm(NULL, 1, &errret))
+       if (batch == 1)
+               tty = "pty";
+       else
+               tty = NULL;
+
+       if (setupterm(tty, STDOUT_FILENO, &errret))
                panic("Terminal setup failed");

        signal(SIGWINCH, winchhandler);
Index: ttyio.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/ttyio.c,v
retrieving revision 1.39
diff -u -p -r1.39 ttyio.c
--- ttyio.c     1 Mar 2021 10:51:14 -0000       1.39
+++ ttyio.c     18 Mar 2021 15:58:40 -0000
@@ -140,7 +140,7 @@ ttflush(void)
        ssize_t  written;
        char    *buf = obuf;

-       if (nobuf == 0)
+       if (nobuf == 0 || batch == 1)
                return;

        while ((written = write(fileno(stdout), buf, nobuf)) != nobuf) {

Reply via email to