git: 9front

Download patch

ref: 66e33b9e0fcbde17081bfb82135e06e61120a693
parent: ebaf2f12ed2a2390ccf74c73524398945f8d0adc
author: Jacob Moody <moody@posixcafe.org>
date: Tue May 23 09:56:43 EDT 2023

kbmap, kbremap: open kbmap file with OTRUNC and bugfixes

Now that kbdfs supports reseting the map to
the default itself we no longer need to
manually load the ascii maps.

This also fixes a 'bug in the making' in
the buffer read logic that would cause it
to cut lines in half when writing to the
kbmap file. All of our kbmaps are under
8k so this never showed up.

Also fix a small bug in kbremap where it
was not writing out the last null when writing out
kbd events.

--- a/sys/man/1/kbmap
+++ b/sys/man/1/kbmap
@@ -74,6 +74,3 @@
 .B /sys/src/cmd/kbremap.c
 .SH "SEE ALSO"
 .IR kbdfs (8)
-.SH BUGS
-Not all keyboards map the entire set of characters, so one has to
-switch back to the default map before changing to another.
--- a/sys/src/cmd/kbmap.c
+++ b/sys/src/cmd/kbmap.c
@@ -140,21 +140,39 @@
 {
 	int i, fd, ofd;
 	char buf[8192];
+	int n;
+	char *p;
 
 	if((fd = open(file, OREAD)) < 0){
-		fprint(2, "cannot open %s: %r", file);
+		fprint(2, "cannot open %s: %r\n", file);
 		return -1;
 	}
-	if((ofd = open("/dev/kbmap", OWRITE)) < 0) {
-		fprint(2, "cannot open /dev/kbmap: %r");
+	if((ofd = open("/dev/kbmap", OWRITE|OTRUNC)) < 0){
+		fprint(2, "cannot open /dev/kbmap: %r\n");
 		close(fd);
 		return -1;
 	}
-	while((i = read(fd, buf, sizeof buf)) > 0)
-		if(write(ofd, buf, i) != i){
-			fprint(2, "writing /dev/kbmap: %r");
+	/* do not write half lines */
+	n = 0;
+	while((i = read(fd, buf + n, sizeof buf - 1 - n)) > 0){
+		n += i;
+		buf[n] = '\0';
+		p = strrchr(buf, '\n');
+		if(p == nil){
+			if(n == sizeof buf - 1){
+				fprint(2, "writing /dev/kbmap: line too long\n");
+				break;
+			}
+			continue;
+		}
+		p++;
+		if(write(ofd, buf, p - buf) !=  p - buf){
+			fprint(2, "writing /dev/kbmap: %r\n");
 			break;
 		}
+		n -= p - buf;
+		memmove(buf, p, n);
+	}
 
 	close(fd);
 	close(ofd);
@@ -165,7 +183,6 @@
 click(Mouse m)
 {
 	int i, j;
-	char buf[128];
 
 	if(m.buttons == 0 || (m.buttons & ~4))
 		return;
@@ -193,9 +210,6 @@
 	if(j != i)
 		return;
 
-	/* since maps are often just a delta of the distributed map... */
-	snprint(buf, sizeof buf, "%s/ascii", dir);
-	writemap(buf);
 	writemap(map[i].file);
 
 	/* clean the previous current map */
--- a/sys/src/cmd/kbremap.c
+++ b/sys/src/cmd/kbremap.c
@@ -10,16 +10,32 @@
 {
 	int i, fd, ofd;
 	char buf[8192];
+	int n;
+	char *p;
 
 	if((fd = open(file, OREAD)) < 0)
 		sysfatal("cannot open %s: %r", file);
 
-	if((ofd = open("/dev/kbmap", OWRITE)) < 0)
+	if((ofd = open("/dev/kbmap", OWRITE|OTRUNC)) < 0)
 		sysfatal("cannot open /dev/kbmap: %r");
 
-	while((i = read(fd, buf, sizeof buf)) > 0)
-		if(write(ofd, buf, i) != i)
+	/* do not write half lines */
+	n = 0;
+	while((i = read(fd, buf + n, sizeof buf - 1 - n)) > 0){
+		n += i;
+		buf[n] = '\0';
+		p = strrchr(buf, '\n');
+		if(p == nil){
+			if(n == sizeof buf - 1)
+				sysfatal("writing /dev/kbmap: line too long");
+			continue;
+		}
+		p++;
+		if(write(ofd, buf, p - buf) !=  p - buf)
 			sysfatal("writing /dev/kbmap: %r");
+		n -= p - buf;
+		memmove(buf, p, n);
+	}
 
 	fprint(ofd, "%s\t%s\t0x%X\n", mod, key, Kswitch);
 	close(fd);
@@ -56,7 +72,6 @@
 		usage();
 
 	chdir("/sys/lib/kbmap");
-	writemap("ascii");
 	writemap(argv[0]);
 	for(;;){
 		n = read(0, buf, sizeof buf - 1);
@@ -66,13 +81,12 @@
 		for(p = buf; p < buf+n; p += strlen(p) + 1){
 			chartorune(&r, p+1);
 			if(*p != 'c' || r != Kswitch){
-				write(1, p, strlen(p));
+				write(1, p, strlen(p) + 1);
 				continue;
 			}
 			index++;
 			if(argv[index] == nil)
 				index = 0;
-			writemap("ascii");
 			writemap(argv[index]);
 		}
 	}
--