git: 968a3db71516 - main - kbdcontrol: Support building as a bootstrap tool on old and non-FreeBSD

From: Jessica Clarke <jrtc27_at_FreeBSD.org>
Date: Tue, 22 Aug 2023 20:01:43 UTC
The branch main has been updated by jrtc27:

URL: https://cgit.FreeBSD.org/src/commit/?id=968a3db7151644bda2036e1be8d4c536220b318f

commit 968a3db7151644bda2036e1be8d4c536220b318f
Author:     Jessica Clarke <jrtc27@FreeBSD.org>
AuthorDate: 2023-08-22 20:00:28 +0000
Commit:     Jessica Clarke <jrtc27@FreeBSD.org>
CommitDate: 2023-08-22 20:00:28 +0000

    kbdcontrol: Support building as a bootstrap tool on old and non-FreeBSD
    
    Systems that predate 971bac5ace7a ("kbd: consolidate kb interfaces
    (phase one)") cannot build kbdcontrol since kbdelays and kbrates moved
    to sys/kbio.h. Moreover, on non-FreeBSD, it requires all kinds of ioctls
    and sysctls that are highly FreeBSD-specific to build, but we use it as
    a bootstrap tool to generate the keymaps used by some kernels (LINT ones
    in particular). Thus, when bootstrapping kbdcontrol, disable everything
    that's not needed for that singular use, and use the in-tree kbio.h to
    get the definitions of the necessary structures.
    
    This allows KBDMUX_DFLT_KEYMAP, UKBD_DFLT_KEYMAP and ATKBD_DFLT_KEYMAP
    to be enabled when building on non-FreeBSD, and thus LINT kernels.
    
    Reviewed by:    imp
    Differential Revision:  https://reviews.freebsd.org/D41541
---
 Makefile.inc1                    |  4 ----
 tools/build/Makefile             |  2 ++
 usr.sbin/kbdcontrol/Makefile     |  5 +++++
 usr.sbin/kbdcontrol/kbdcontrol.c | 33 +++++++++++++++++++++++++++++++++
 4 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/Makefile.inc1 b/Makefile.inc1
index 295c93d0282c..8838d31c795a 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -2384,15 +2384,11 @@ _bootstrap_tools_links+=crunchgen
 # The ATKBD_DFLT_KEYMAP, UKBD_DFLT_KEYMAP and KBDMUX_DFLT_KEYMAP kernel options
 # require kbdcontrol. Note that, even on FreeBSD, the host will lack kbdcontrol
 # if built with WITHOUT_LEGACY_CONSOLE.
-#
-# XXX: kbdcontrol cannot currently be bootstrapped on non-FreeBSD systems
-.if !defined(CROSSBUILD_HOST)
 .if defined(BOOTSTRAP_ALL_TOOLS) || !exists(/usr/sbin/kbdcontrol)
 _kbdcontrol=	usr.sbin/kbdcontrol
 .else
 _bootstrap_tools_links+=kbdcontrol
 .endif
-.endif
 
 .if ${MK_DISK_IMAGE_TOOLS_BOOTSTRAP} != "no"
 _etdump=	usr.bin/etdump
diff --git a/tools/build/Makefile b/tools/build/Makefile
index 2aa34f4f87cf..8ad104f904ea 100644
--- a/tools/build/Makefile
+++ b/tools/build/Makefile
@@ -289,6 +289,8 @@ SYSINCS+=	${SRCTOP}/sys/sys/fnv_hash.h
 INCS+=	${SRCTOP}/include/elf.h
 SYSINCS+=	${SRCTOP}/sys/sys/elf.h
 SYSINCS+=	${SRCTOP}/sys/sys/ctf.h
+# for kbdcontrol:
+SYSINCS+=	${SRCTOP}/sys/sys/kbio.h
 
 # We want to run the build with only ${WORLDTMP} in $PATH to ensure we don't
 # accidentally run tools that are incompatible but happen to be in $PATH.
diff --git a/usr.sbin/kbdcontrol/Makefile b/usr.sbin/kbdcontrol/Makefile
index 219f0fc1dca6..982fa42e1564 100644
--- a/usr.sbin/kbdcontrol/Makefile
+++ b/usr.sbin/kbdcontrol/Makefile
@@ -8,7 +8,12 @@ SRCS=	kbdcontrol.c lex.l
 WARNS?=	4
 CFLAGS+= -I${.CURDIR}
 
+.ifdef BOOTSTRAPPING
+# Provide minimal load and dump functionality
+CFLAGS+= -DBOOTSTRAP_KBDCONTROL
+.else
 # temporarily added for pre-Unicode accent key API/ABI compatibility
 CFLAGS+= -DCOMPAT_FREEBSD13
+.endif
 
 .include <bsd.prog.mk>
diff --git a/usr.sbin/kbdcontrol/kbdcontrol.c b/usr.sbin/kbdcontrol/kbdcontrol.c
index 522aab54c466..e55165fd0888 100644
--- a/usr.sbin/kbdcontrol/kbdcontrol.c
+++ b/usr.sbin/kbdcontrol/kbdcontrol.c
@@ -46,12 +46,14 @@
 
 #define	SPECIAL		0x80000000
 
+#ifndef BOOTSTRAP_KBDCONTROL
 static const char ctrl_names[32][4] = {
 	"nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
 	"bs ", "ht ", "nl ", "vt ", "ff ", "cr ", "so ", "si ",
 	"dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
 	"can", "em ", "sub", "esc", "fs ", "gs ", "rs ", "us "
 	};
+#endif
 
 static const char acc_names[15][5] = {
 	"dgra", "dacu", "dcir", "dtil", "dmac", "dbre", "ddot",
@@ -65,6 +67,7 @@ static const char acc_names_u[15][5] = {
 	"DCAR",
 	};
 
+#ifndef BOOTSTRAP_KBDCONTROL
 static const char fkey_table[96][MAXFK] = {
 /* 01-04 */	"\033[M", "\033[N", "\033[O", "\033[P",
 /* 05-08 */	"\033[Q", "\033[R", "\033[S", "\033[T",
@@ -91,10 +94,13 @@ static const char fkey_table[96][MAXFK] = {
 /* 89-92 */	""      , ""      , ""      , ""      ,
 /* 93-96 */	""      , ""      , ""      , ""      ,
 	};
+#endif
 
+#ifndef BOOTSTRAP_KBDCONTROL
 static const int ndelays = nitems(kbdelays);
 static const int nrepeats = nitems(kbrates);
 static int	hex = 0;
+#endif
 static int	paths_configured = 0;
 static int	token;
 
@@ -109,9 +115,12 @@ static int	get_accent_definition_line(accentmap_t *);
 static int	get_entry(void);
 static int	get_key_definition_line(keymap_t *);
 static void	load_keymap(char *opt, int dumponly);
+#ifndef BOOTSTRAP_KBDCONTROL
 static void	load_default_functionkeys(void);
+#endif
 static char *	nextarg(int ac, char **av, int *indp, int oc);
 static char *	mkfullname(const char *s1, const char *s2, const char *s3);
+#ifndef BOOTSTRAP_KBDCONTROL
 static void	print_accent_definition_line(FILE *fp, int accent,
 		struct acc_t *key);
 static void	print_entry(FILE *fp, int value);
@@ -125,6 +134,7 @@ static void	set_functionkey(char *keynumstr, char *string);
 static void	set_keyboard(char *device);
 static void	set_keyrates(char *opt);
 static void	show_kbd_info(void);
+#endif
 static void	usage(void) __dead2;
 
 struct pathent {
@@ -133,6 +143,7 @@ struct pathent {
 };
 static STAILQ_HEAD(, pathent) pathlist = STAILQ_HEAD_INITIALIZER(pathlist);
 
+#ifndef BOOTSTRAP_KBDCONTROL
 /* Detect presence of vt(4). */
 static int
 is_vt4(void)
@@ -144,6 +155,7 @@ is_vt4(void)
 		return (0);
 	return (strcmp(vty_name, "vt") == 0);
 }
+#endif
 
 static char *
 nextarg(int ac, char **av, int *indp, int oc)
@@ -390,6 +402,7 @@ get_accent_definition_line(accentmap_t *map)
 	return (accent + 1);
 }
 
+#ifndef BOOTSTRAP_KBDCONTROL
 static void
 print_entry(FILE *fp, int value)
 {
@@ -590,6 +603,7 @@ print_accent_definition_line(FILE *fp, int accent, struct acc_t *key)
 	}
 	fprintf(fp, "\n");
 }
+#endif
 
 static void
 dump_entry(int value)
@@ -836,10 +850,12 @@ load_keymap(char *opt, int dumponly)
 		if (cp != NULL)
 			add_keymap_path(cp);
 		add_keymap_path("");
+#ifndef BOOTSTRAP_KBDCONTROL
 		if (is_vt4())
 			add_keymap_path(vt_keymap_path);
 		else
 			add_keymap_path(keymap_path);
+#endif
 		paths_configured = 1;
 	}
 
@@ -875,6 +891,7 @@ load_keymap(char *opt, int dumponly)
 		dump_accent_definition(opt, &accentmap);
 		return;
 	}
+#ifndef BOOTSTRAP_KBDCONTROL
 	if ((keymap.n_keys > 0) && (ioctl(0, PIO_KEYMAP, &keymap) < 0)) {
 		warn("setting keymap");
 		fclose(file);
@@ -892,6 +909,7 @@ load_keymap(char *opt, int dumponly)
 			return;
 		}
 	}
+#endif
 }
 
 #ifdef OPIO_DEADKEYMAP
@@ -911,6 +929,7 @@ to_new_accentmap(oaccentmap_t *from, accentmap_t *to)
 }
 #endif /* OPIO_DEADKEYMAP */
 
+#ifndef BOOTSTRAP_KBDCONTROL
 static void
 print_keymap(void)
 {
@@ -1240,14 +1259,20 @@ mux_keyboard(u_int op, char *kbd)
 	if (ioctl(0, op, &info) == -1)
 		warn("unable to (un)mux the keyboard");
 }
+#endif
 
 static void
 usage(void)
 {
+#ifdef BOOTSTRAP_KBDCONTROL
+	fprintf(stderr, "%s\n",
+"usage: kbdcontrol [-L mapfile] [-P path]");
+#else
 	fprintf(stderr, "%s\n%s\n%s\n",
 "usage: kbdcontrol [-dFKix] [-A name] [-a name] [-b duration.pitch | [quiet.]belltype]",
 "                  [-r delay.repeat | speed] [-l mapfile] [-f # string]",
 "                  [-k device] [-L mapfile] [-P path]");
+#endif
 	exit(1);
 }
 
@@ -1255,7 +1280,11 @@ usage(void)
 int
 main(int argc, char **argv)
 {
+#ifdef BOOTSTRAP_KBDCONTROL
+	const char	*optstring = "L:P:";
+#else
 	const char	*optstring = "A:a:b:df:iKk:Fl:L:P:r:x";
+#endif
 	int		opt;
 
 	/* Collect any -P arguments, regardless of where they appear. */
@@ -1269,6 +1298,7 @@ main(int argc, char **argv)
 	optind = optreset = 1;
 	while ((opt = getopt(argc, argv, optstring)) != -1)
 		switch(opt) {
+#ifndef BOOTSTRAP_KBDCONTROL
 		case 'A':
 		case 'a':
 			mux_keyboard((opt == 'A')? KBRELKBD : KBADDKBD, optarg);
@@ -1282,11 +1312,13 @@ main(int argc, char **argv)
 		case 'l':
 			load_keymap(optarg, 0);
 			break;
+#endif
 		case 'L':
 			load_keymap(optarg, 1);
 			break;
 		case 'P':
 			break;
+#ifndef BOOTSTRAP_KBDCONTROL
 		case 'f':
 			set_functionkey(optarg,
 			    nextarg(argc, argv, &optind, 'f'));
@@ -1309,6 +1341,7 @@ main(int argc, char **argv)
 		case 'x':
 			hex = 1;
 			break;
+#endif
 		default:
 			usage();
 		}