Hi
I think you should not pass NULL to the last argument of setupterm(),
from terminfo(3):
If errret is null, setupterm prints an error message upon finding an
error and exits.
On Sat, Jun 16, 2018 at 04:16:57PM -0600, Todd C. Miller wrote:
> On Sat, 16 Jun 2018 14:50:40 +0200, Mark Kettenis wrote:
>
> > To be honest, I find the whole idea of invoking an external program to
> > clear the screen insane.
>
> Linking with curses doesn't increase the size a huge amount since
> we just need to query terminfo.
>
> text data bss dec hex
> 529120 12584 57024 598728 922c8 /bin/ksh
> 595671 21904 57024 674599 a4b27 ./obj/ksh
>
> - todd
>
> Index: bin/ksh/Makefile
> ===================================================================
> RCS file: /cvs/src/bin/ksh/Makefile,v
> retrieving revision 1.38
> diff -u -p -u -r1.38 Makefile
> --- bin/ksh/Makefile 6 Jan 2018 16:28:58 -0000 1.38
> +++ bin/ksh/Makefile 16 Jun 2018 22:00:32 -0000
> @@ -1,6 +1,9 @@
> # $OpenBSD: Makefile,v 1.38 2018/01/06 16:28:58 millert Exp $
>
> PROG= ksh
> +DPADD+= ${LIBCURSES}
> +LDADD+= -lcurses
> +
> SRCS= alloc.c c_ksh.c c_sh.c c_test.c c_ulimit.c edit.c emacs.c
> eval.c \
> exec.c expr.c history.c io.c jobs.c lex.c mail.c main.c \
> misc.c path.c shf.c syn.c table.c trap.c tree.c tty.c var.c \
> Index: bin/ksh/edit.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/edit.c,v
> retrieving revision 1.65
> diff -u -p -u -r1.65 edit.c
> --- bin/ksh/edit.c 9 Apr 2018 17:53:36 -0000 1.65
> +++ bin/ksh/edit.c 16 Jun 2018 22:09:17 -0000
> @@ -138,10 +138,10 @@ x_flush(void)
> shf_flush(shl_out);
> }
>
> -void
> +int
> x_putc(int c)
> {
> - shf_putc(c, shl_out);
> + return shf_putc(c, shl_out);
> }
>
> void
> Index: bin/ksh/edit.h
> ===================================================================
> RCS file: /cvs/src/bin/ksh/edit.h,v
> retrieving revision 1.11
> diff -u -p -u -r1.11 edit.h
> --- bin/ksh/edit.h 26 Jan 2016 17:39:31 -0000 1.11
> +++ bin/ksh/edit.h 16 Jun 2018 22:09:27 -0000
> @@ -37,7 +37,7 @@ extern X_chars edchars;
> /* edit.c */
> int x_getc(void);
> void x_flush(void);
> -void x_putc(int);
> +int x_putc(int);
> void x_puts(const char *);
> bool x_mode(bool);
> int promptlen(const char *, const char **);
> Index: bin/ksh/emacs.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/emacs.c,v
> retrieving revision 1.84
> diff -u -p -u -r1.84 emacs.c
> --- bin/ksh/emacs.c 16 Jan 2018 17:17:18 -0000 1.84
> +++ bin/ksh/emacs.c 16 Jun 2018 22:12:24 -0000
> @@ -21,6 +21,10 @@
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> +#ifndef SMALL
> +# include <term.h>
> +# include <curses.h>
> +#endif
>
> #include "sh.h"
> #include "edit.h"
> @@ -28,6 +32,7 @@
> static Area aedit;
> #define AEDIT &aedit /* area for kill ring and macro defns */
>
> +#undef CTRL
> #define CTRL(x) ((x) == '?' ? 0x7F : (x) & 0x1F) /*
> ASCII */
> #define UNCTRL(x) ((x) == 0x7F ? '?' : (x) | 0x40) /*
> ASCII */
>
> @@ -146,6 +151,7 @@ static int isu8cont(unsigned char);
> /* proto's for keybindings */
> static int x_abort(int);
> static int x_beg_hist(int);
> +static int x_clear_screen(int);
> static int x_comp_comm(int);
> static int x_comp_file(int);
> static int x_complete(int);
> @@ -202,6 +208,7 @@ static int x_debug_info(int);
> static const struct x_ftab x_ftab[] = {
> { x_abort, "abort", 0 },
> { x_beg_hist, "beginning-of-history", 0 },
> + { x_clear_screen, "clear-screen", 0 },
> { x_comp_comm, "complete-command", 0 },
> { x_comp_file, "complete-file", 0 },
> { x_complete, "complete", 0 },
> @@ -1004,12 +1011,19 @@ x_draw_line(int c)
> {
> x_redraw(-1);
> return KSTD;
> +}
>
> +static int
> +x_clear_screen(int c)
> +{
> + x_redraw(-2);
> + return KSTD;
> }
>
> -/* Redraw (part of) the line. If limit is < 0, the everything is redrawn
> - * on a NEW line, otherwise limit is the screen column up to which needs
> - * redrawing.
> +/* Redraw (part of) the line.
> + * A non-negative limit is the screen column up to which needs
> + * redrawing. A limit of -1 redraws on a new line, while a limit
> + * of -2 (attempts to) clear the screen.
> */
> static void
> x_redraw(int limit)
> @@ -1018,9 +1032,23 @@ x_redraw(int limit)
> char *cp;
>
> x_adj_ok = 0;
> - if (limit == -1)
> + if (limit == -2) {
> + int ret = -1;
> +#ifndef SMALL
> + char *str, *term = str_val(global("TERM"));
> + if (term && *term) {
> + setupterm(term, 1, NULL);
> + str = tigetstr("clear");
> + if (str != NULL && str != (char *)-1)
> + ret = tputs(str, 1, x_putc) == ERR;
> + }
> +#endif
> + if (ret != 0)
> + x_e_putc('\n');
> + }
> + else if (limit == -1)
> x_e_putc('\n');
> - else
> + else if (limit >= 0)
> x_e_putc('\r');
> x_flush();
> if (xbp == xbuf) {
> Index: bin/ksh/ksh.1
> ===================================================================
> RCS file: /cvs/src/bin/ksh/ksh.1,v
> retrieving revision 1.200
> diff -u -p -u -r1.200 ksh.1
> --- bin/ksh/ksh.1 30 May 2018 21:20:52 -0000 1.200
> +++ bin/ksh/ksh.1 16 Jun 2018 12:29:34 -0000
> @@ -4690,6 +4690,10 @@ Moves the cursor to the beginning of the
> Uppercase the first character in the next
> .Ar n
> words, leaving the cursor past the end of the last word.
> +.It clear-screen:
> +Attempts to clears the screen by invoking
> +.Xr clear 1
> +and redraws the prompt and current input line.
> .It comment: ^[#
> If the current line does not begin with a comment character, one is added at
> the beginning of the line and the line is entered (as if return had been
>