[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Andrés Delfino: IMHO, wsconsctl(8) output when setting variable values should be modified



In response to the mail on misc@ from Andris Delfino:

> I guess wsconsctl(8) output when setting variable values should be
> slightly modified, since mixerctl and sysctl uses: "variable:
> old_value -> new_value", and wsconsctl(8) uses: "variable ->
> new_value", as you can see below.
> 
> $ mixerctl outputs.master=199,199
> outputs.master: 199,199 -> 199,199
> 
> $ sudo sysctl machdep.userldt=1
> machdep.userldt: 1 -> 1
> 
> $ wsconsctl keyboard.bell.pitch=50
> keyboard.bell.pitch -> 50

Here is a patch.  Tested quite a bit, but not extensively.  Comments?

Index: display.c
===================================================================
RCS file: /cvs/src/sbin/wsconsctl/display.c,v
retrieving revision 1.10
diff -u -p -r1.10 display.c
--- display.c	19 Nov 2004 19:34:40 -0000	1.10
+++ display.c	12 Mar 2006 20:23:56 -0000
@@ -148,7 +148,7 @@ display_get_values(const char *pre, int 
 	}
 }
 
-void
+int
 display_put_values(const char *pre, int fd)
 {
 	struct wsdisplay_param param;
@@ -157,7 +157,7 @@ display_put_values(const char *pre, int 
 	const char *cmd_str;
 	void *ptr;
 	unsigned long cmd;
-	int id;
+	int id, error = 0;
 
 	for (pf = display_field_tab; pf->name; pf++) {
 
@@ -222,10 +222,11 @@ display_put_values(const char *pre, int 
 			if (errno == ENOTTY) {
 				pf->flags |= FLG_DEAD;
 				continue;
-			} else
+			} else {
 				warn(cmd_str);
+				error = 1;
+			}
 		}
-
-		pr_field(pre, pf, " -> ");
 	}
+	return (error);
 }
Index: keyboard.c
===================================================================
RCS file: /cvs/src/sbin/wsconsctl/keyboard.c,v
retrieving revision 1.5
diff -u -p -r1.5 keyboard.c
--- keyboard.c	7 Mar 2003 00:04:21 -0000	1.5
+++ keyboard.c	12 Mar 2006 20:23:56 -0000
@@ -134,9 +134,11 @@ keyboard_get_values(const char *pre, int
 			warn("WSKBDIO_GETENCODING");
 }
 
-void
+int
 keyboard_put_values(const char *pre, int fd)
 {
+	int error = 0;
+
 	bell.which = 0;
 	if (field_by_value(keyboard_field_tab, &bell.pitch)->flags & FLG_SET)
 		bell.which |= WSKBD_BELL_DOPITCH;
@@ -144,18 +146,9 @@ keyboard_put_values(const char *pre, int
 		bell.which |= WSKBD_BELL_DOPERIOD;
 	if (field_by_value(keyboard_field_tab, &bell.volume)->flags & FLG_SET)
 		bell.which |= WSKBD_BELL_DOVOLUME;
-	if (bell.which != 0 && ioctl(fd, WSKBDIO_SETBELL, &bell) < 0)
+	if (bell.which != 0 && ioctl(fd, WSKBDIO_SETBELL, &bell) < 0) {
 		warn("WSKBDIO_SETBELL");
-	else {
-		if (bell.which & WSKBD_BELL_DOPITCH)
-			pr_field(pre, field_by_value(keyboard_field_tab,
-			    &bell.pitch), " -> ");
-		if (bell.which & WSKBD_BELL_DOPERIOD)
-			pr_field(pre, field_by_value(keyboard_field_tab,
-			    &bell.period), " -> ");
-		if (bell.which & WSKBD_BELL_DOVOLUME)
-			pr_field(pre, field_by_value(keyboard_field_tab,
-			    &bell.volume), " -> ");
+		error = 1;
 	}
 
 	dfbell.which = 0;
@@ -166,23 +159,15 @@ keyboard_put_values(const char *pre, int
 	if (field_by_value(keyboard_field_tab, &dfbell.volume)->flags & FLG_SET)
 		dfbell.which |= WSKBD_BELL_DOVOLUME;
 	if (dfbell.which != 0 &&
-	    ioctl(fd, WSKBDIO_SETDEFAULTBELL, &dfbell) < 0)
+	    ioctl(fd, WSKBDIO_SETDEFAULTBELL, &dfbell) < 0) {
 		warn("WSKBDIO_SETDEFAULTBELL");
-	else {
-		if (dfbell.which & WSKBD_BELL_DOPITCH)
-			pr_field(pre, field_by_value(keyboard_field_tab,
-			    &dfbell.pitch), " -> ");
-		if (dfbell.which & WSKBD_BELL_DOPERIOD)
-			pr_field(pre, field_by_value(keyboard_field_tab,
-			    &dfbell.period), " -> ");
-		if (dfbell.which & WSKBD_BELL_DOVOLUME)
-			pr_field(pre, field_by_value(keyboard_field_tab,
-			    &dfbell.volume), " -> ");
+		error = 1;
 	}
 
 	if (field_by_value(keyboard_field_tab, &kbmap)->flags & FLG_SET) {
 		if (ioctl(fd, WSKBDIO_SETMAP, &kbmap) < 0)
 			warn("WSKBDIO_SETMAP");
+		error = 1;
 	}
 
 	repeat.which = 0;
@@ -191,15 +176,9 @@ keyboard_put_values(const char *pre, int
 	if (field_by_value(keyboard_field_tab, &repeat.delN)->flags & FLG_SET)
 		repeat.which |= WSKBD_KEYREPEAT_DODELN;
 	if (repeat.which != 0 &&
-	    ioctl(fd, WSKBDIO_SETKEYREPEAT, &repeat) < 0)
+	    ioctl(fd, WSKBDIO_SETKEYREPEAT, &repeat) < 0) {
 		warn("WSKBDIO_SETKEYREPEAT");
-	else {
-		if (repeat.which & WSKBD_KEYREPEAT_DODEL1)
-			pr_field(pre, field_by_value(keyboard_field_tab,
-			    &repeat.del1), " -> ");
-		if (repeat.which & WSKBD_KEYREPEAT_DODELN)
-			pr_field(pre, field_by_value(keyboard_field_tab,
-			    &repeat.delN), " -> ");
+		error = 1;
 	}
 
 	dfrepeat.which = 0;
@@ -208,32 +187,23 @@ keyboard_put_values(const char *pre, int
 	if (field_by_value(keyboard_field_tab, &dfrepeat.delN)->flags & FLG_SET)
 		dfrepeat.which |= WSKBD_KEYREPEAT_DODELN;
 	if (dfrepeat.which != 0 &&
-	    ioctl(fd, WSKBDIO_SETDEFAULTKEYREPEAT, &dfrepeat) < 0)
+	    ioctl(fd, WSKBDIO_SETDEFAULTKEYREPEAT, &dfrepeat) < 0) {
 		warn("WSKBDIO_SETDEFAULTKEYREPEAT");
-	else {
-		if (dfrepeat.which &WSKBD_KEYREPEAT_DODEL1)
-			pr_field(pre, field_by_value(keyboard_field_tab,
-			    &dfrepeat.del1), " -> ");
-		if (dfrepeat.which & WSKBD_KEYREPEAT_DODELN)
-			pr_field(pre, field_by_value(keyboard_field_tab,
-			    &dfrepeat.delN), " -> ");
+		error = 1;
 	}
 
 	if (field_by_value(keyboard_field_tab, &ledstate)->flags & FLG_SET) {
-		if (ioctl(fd, WSKBDIO_SETLEDS, &ledstate) < 0)
+		if (ioctl(fd, WSKBDIO_SETLEDS, &ledstate) < 0) {
 			warn("WSKBDIO_SETLEDS");
-		else {
-			pr_field(pre, field_by_value(keyboard_field_tab,
-			    &ledstate), " -> ");
+			error = 1;
 		}
 	}
 
 	if (field_by_value(keyboard_field_tab, &kbdencoding)->flags & FLG_SET) {
-		if (ioctl(fd, WSKBDIO_SETENCODING, &kbdencoding) < 0)
+		if (ioctl(fd, WSKBDIO_SETENCODING, &kbdencoding) < 0) {
 			warn("WSKBDIO_SETENCODING");
-		else {
-			pr_field(pre, field_by_value(keyboard_field_tab,
-			    &kbdencoding), " -> ");
+			error = 1;
 		}
 	}
+	return (error);
 }
Index: mouse.c
===================================================================
RCS file: /cvs/src/sbin/wsconsctl/mouse.c,v
retrieving revision 1.5
diff -u -p -r1.5 mouse.c
--- mouse.c	11 Dec 2002 18:27:19 -0000	1.5
+++ mouse.c	12 Mar 2006 20:23:57 -0000
@@ -62,23 +62,22 @@ mouse_get_values(const char *pre, int fd
 			warn("WSMOUSEIO_GTYPE");
 }
 
-void
+int
 mouse_put_values(const char *pre, int fd)
 {
+	int error = 0;
+
 	if (field_by_value(mouse_field_tab, &resolution)->flags & FLG_SET) {
-		if (ioctl(fd, WSMOUSEIO_SRES, &resolution) < 0)
+		if (ioctl(fd, WSMOUSEIO_SRES, &resolution) < 0) {
 			warn("WSMOUSEIO_SRES");
-		else {
-			pr_field(pre, field_by_value(mouse_field_tab,
-			    &resolution), " -> ");
+			error = 1;
 		}
 	}
 	if (field_by_value(mouse_field_tab, &samplerate)->flags & FLG_SET) {
-		if (ioctl(fd, WSMOUSEIO_SRATE, &samplerate) < 0)
+		if (ioctl(fd, WSMOUSEIO_SRATE, &samplerate) < 0) {
 			warn("WSMOUSEIO_SRATE");
-		else {
-			pr_field(pre, field_by_value(mouse_field_tab,
-			    &samplerate), " -> ");
+			error = 1;
 		}
 	}
+	return (error);
 }
Index: util.c
===================================================================
RCS file: /cvs/src/sbin/wsconsctl/util.c,v
retrieving revision 1.32
diff -u -p -r1.32 util.c
--- util.c	14 Feb 2006 18:52:15 -0000	1.32
+++ util.c	12 Mar 2006 20:23:57 -0000
@@ -43,6 +43,7 @@
 #include <err.h>
 #include <string.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <unistd.h>
 #include "wsconsctl.h"
 
@@ -210,16 +211,13 @@ name2int(char *val, const struct nameint
 }
 
 void
-pr_field(const char *pre, struct field *f, const char *sep)
+pr_fieldval(struct field *f)
 {
 	struct field_pc *pc;
 	u_int flags;
 	int i, n;
 	char *p;
 
-	if (sep)
-		printf("%s.%s%s", pre, f->name, sep);
-
 	switch (f->format) {
 	case FMT_UINT:
 		printf("%u", *((u_int *) f->valp));
@@ -269,11 +267,61 @@ pr_field(const char *pre, struct field *
 		print_kmap((struct wskbd_map_data *) f->valp);
 		break;
 	default:
-		errx(1, "internal error: pr_field: no format %d", f->format);
+		errx(1, "internal error: pr_fieldval: no format %d", f->format);
 		break;
 	}
+}
 
+void
+pr_field(const char *pre, struct field *fold, const char *sep, struct field *fcur)
+{
+	if (sep)
+		printf("%s.%s", pre, fcur->name);
+	if (fold) {
+		printf(": ");
+		pr_fieldval(fold);
+	}
+	printf("%s", sep);
+	pr_fieldval(fcur);
 	printf("\n");
+}
+
+struct field *
+dupfield(struct field *f)
+{
+	struct field *p;
+	size_t siz;
+
+	if ((p = malloc(sizeof(*f))) == NULL)
+		err(1, NULL);
+	memcpy(p, f, sizeof(*p));
+
+	if ((p->name = strdup(f->name)) == NULL)
+		err(1, "strdup");
+
+	switch (f->format) {
+	case FMT_UINT:
+	case FMT_BOOL:
+	case FMT_KBDENC:
+		siz = sizeof(u_int);
+		break;
+	case FMT_INT:
+		siz = sizeof(int);
+		break;
+	case FMT_PC:
+		siz = sizeof(struct field_pc);
+		break;
+	case FMT_KBMAP:
+		break;
+	default:
+		errx(1, "internal error: dupfield: no format %d", f->format);
+		break;
+	}
+
+	if ((p->valp = malloc(siz)) == NULL)
+		err(1, NULL);
+	memcpy(p->valp, f->valp, siz);
+	return (p);
 }
 
 void
Index: wsconsctl.c
===================================================================
RCS file: /cvs/src/sbin/wsconsctl/wsconsctl.c,v
retrieving revision 1.16
diff -u -p -r1.16 wsconsctl.c
--- wsconsctl.c	9 Aug 2004 18:39:22 -0000	1.16
+++ wsconsctl.c	12 Mar 2006 20:23:57 -0000
@@ -62,7 +62,7 @@ struct vartypesw {
 	int fd;
 	struct field *field_tab;
 	void (*getval)(const char *pre, int);
-	void (*putval)(const char *pre, int);
+	int (*putval)(const char *pre, int);
 } typesw[] = {
 	{ "keyboard", PATH_KEYBOARD, -1, keyboard_field_tab,
 	  keyboard_get_values, keyboard_put_values },
@@ -97,7 +97,7 @@ main(int argc, char *argv[])
 	int i, ch, error = 0, aflag = 0, do_merge;
 	struct vartypesw *sw = NULL;
 	char *sep = "=", *p;
-	struct field *f;
+	struct field *f, *fold;
 
 	while ((ch = getopt(argc, argv, "anw")) != -1) {
 		switch(ch) {
@@ -141,41 +141,20 @@ main(int argc, char *argv[])
 					warnx("Use explicit arg to view %s.%s.",
 					      sw->name, f->name);
 				else if (f->flags & FLG_GET)
-					pr_field(sw->name, f, sep);
+					pr_field(sw->name, NULL, sep, f);
 		}
 	} else if (argc > 0) {
 		for (i = 0; i < argc; i++) {
-			p = strchr(argv[i], '=');
-			if (p == NULL) {
-				sw = tab_by_name(argv[i]);
-				if (!sw)
-					continue;
-				if (sw->fd < 0 &&
-				    (sw->fd = open(sw->file, O_WRONLY)) < 0 &&
-				    (sw->fd = open(sw->file, O_RDONLY)) < 0) {
-					warn("open: %s", sw->file);
-					error = 1;
-					continue;
-				}
-				f = field_by_name(sw->field_tab, argv[i]);
-				if (f->flags & FLG_DEAD)
-					continue;
-				if ((f->flags & FLG_WRONLY) != 0) {
-					warnx("%s: write only", argv[i]);
-					continue;
-				}
-				f->flags |= FLG_GET;
-				(*sw->getval)(sw->name, sw->fd);
-				pr_field(sw->name, f, sep);
-				continue;
+			if ((p = strchr(argv[i], '=')) != NULL) {
+				if (p > argv[i] &&
+				    (*(p - 1) == '+' || *(p - 1) == '-')) {
+					do_merge = *(p - 1);
+					*(p - 1) = '\0';
+				} else
+					do_merge = 0;
+				*p++ = '\0';
 			}
-			if (p > argv[i] &&
-			    (*(p - 1) == '+' || *(p - 1) == '-')) {
-				do_merge = *(p - 1);
-				*(p - 1) = '\0';
-			} else
-				do_merge = 0;
-			*p++ = '\0';
+
 			sw = tab_by_name(argv[i]);
 			if (!sw)
 				continue;
@@ -189,10 +168,29 @@ main(int argc, char *argv[])
 			f = field_by_name(sw->field_tab, argv[i]);
 			if (f->flags & FLG_DEAD)
 				continue;
-			if ((f->flags & FLG_RDONLY) != 0) {
-				warnx("%s: read only", argv[i]);
+			if (p == NULL) {
+				/* No `=' found, try to read. */
+				if ((f->flags & FLG_WRONLY) != 0) {
+					warnx("%s: write only", argv[i]);
+					continue;
+				}
+			} else {
+				/* Trying to write it. */
+				if ((f->flags & FLG_RDONLY) != 0) {
+					warnx("%s: read only", argv[i]);
+					continue;
+				}
+			}
+			f->flags |= FLG_GET;
+			(*sw->getval)(sw->name, sw->fd);
+			f->flags &= ~FLG_GET;
+
+			if (p == NULL) {
+				/* Not setting, just print and move on. */
+				pr_field(sw->name, NULL, sep, f);
 				continue;
 			}
+			fold = dupfield(f);
 			if (do_merge || f->flags & FLG_INIT) {
 				if ((f->flags & FLG_MODIFY) == 0)
 					errx(1, "%s: can only be set",
@@ -203,8 +201,15 @@ main(int argc, char *argv[])
 			}
 			rd_field(f, p, do_merge);
 			f->flags |= FLG_SET;
-			(*sw->putval)(sw->name, sw->fd);
+			if ((*sw->putval)(sw->name, sw->fd))
+				continue;
 			f->flags &= ~FLG_SET;
+
+			f->flags |= FLG_GET;
+			(*sw->getval)(sw->name, sw->fd);
+			f->flags &= ~FLG_GET;
+
+			pr_field(sw->name, fold, " -> ", f);
 		}
 	} else
 		usage(NULL);
Index: wsconsctl.h
===================================================================
RCS file: /cvs/src/sbin/wsconsctl/wsconsctl.h,v
retrieving revision 1.6
diff -u -p -r1.6 wsconsctl.h
--- wsconsctl.h	17 Dec 2002 07:10:25 -0000	1.6
+++ wsconsctl.h	12 Mar 2006 20:23:57 -0000
@@ -67,19 +67,20 @@ struct field_pc {
 	int max, min, cur;
 };
 
+struct field *dupfield(struct field *);
 struct field *field_by_name(struct field *, char *);
 struct field *field_by_value(struct field *, void *);
-void pr_field(const char *, struct field *, const char *);
+void pr_field(const char *, struct field *, const char *, struct field *);
 void rd_field(struct field *, char *, int);
 int name2ksym(char *);
 char *ksym2name(int);
 keysym_t ksym_upcase(keysym_t);
 void keyboard_get_values(const char *,int);
-void keyboard_put_values(const char *,int);
+int  keyboard_put_values(const char *,int);
 void mouse_get_values(const char *,int);
-void mouse_put_values(const char *,int);
+int  mouse_put_values(const char *,int);
 void display_get_values(const char *,int);
-void display_put_values(const char *,int);
+int  display_put_values(const char *,int);
 int yyparse(void);
 void yyerror(char *);
 int yylex(void);