Refactor chvt(1) - ubase - suckless linux base utils | |
git clone git://git.suckless.org/ubase | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit b6669b5f196275bcf205abe5904b63bcd9213011 | |
parent cdaa7b860ea3af523318bc8d3c9a412fcd0d24b4 | |
Author: FRIGN <[email protected]> | |
Date: Mon, 7 Sep 2015 12:21:26 +0200 | |
Refactor chvt(1) | |
1) Properly implement arg.h. | |
2) Use estrtonum instead of estrtol. | |
3) Check close(). | |
4) Small fixes. | |
5) Update manpage. | |
Diffstat: | |
M Makefile | 1 + | |
M chvt.1 | 9 +++++---- | |
M chvt.c | 33 +++++++++++++++++------------… | |
A libutil/strtonum.c | 85 +++++++++++++++++++++++++++++… | |
M util.h | 6 ++++++ | |
5 files changed, 115 insertions(+), 19 deletions(-) | |
--- | |
diff --git a/Makefile b/Makefile | |
@@ -31,6 +31,7 @@ LIBUTILSRC = \ | |
libutil/recurse.c \ | |
libutil/strlcat.c \ | |
libutil/strlcpy.c \ | |
+ libutil/strtonum.c \ | |
libutil/tty.c | |
LIB = $(LIBUTIL) | |
diff --git a/chvt.1 b/chvt.1 | |
@@ -1,4 +1,4 @@ | |
-.Dd February 2, 2015 | |
+.Dd September 7, 2015 | |
.Dt CHVT 1 | |
.Os ubase | |
.Sh NAME | |
@@ -6,9 +6,10 @@ | |
.Nd change foreground virtual terminal | |
.Sh SYNOPSIS | |
.Nm | |
-.Ar N | |
+.Ar num | |
.Sh DESCRIPTION | |
.Nm | |
brings | |
-.Pf /dev/tty Ar N | |
-to the foreground. This has the same effect as Ctrl-Alt-FN. | |
+.Pf /dev/tty Ar num | |
+to the foreground. This has the same effect as | |
+.Pf Ctrl-Alt-F Ar num . | |
diff --git a/chvt.c b/chvt.c | |
@@ -3,8 +3,8 @@ | |
#include <sys/types.h> | |
#include <fcntl.h> | |
+#include <limits.h> | |
#include <stdio.h> | |
-#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
@@ -15,7 +15,7 @@ | |
#define VT_ACTIVATE 0x5606 /* make vt active */ | |
#define VT_WAITACTIVE 0x5607 /* wait for vt active */ | |
-static char *vts[] = { | |
+static char *vt[] = { | |
"/proc/self/fd/0", | |
"/dev/console", | |
"/dev/tty", | |
@@ -25,7 +25,7 @@ static char *vts[] = { | |
static void | |
usage(void) | |
{ | |
- eprintf("usage: %s N\n", argv0); | |
+ eprintf("usage: %s num\n", argv0); | |
} | |
int | |
@@ -36,29 +36,32 @@ main(int argc, char *argv[]) | |
char c; | |
ARGBEGIN { | |
+ default: | |
+ usage(); | |
} ARGEND; | |
- if (argc != 2 || strspn(argv[1], "1234567890") != strlen(argv[1])) | |
+ if (argc != 1) | |
usage(); | |
- n = estrtol(argv[1], 10); | |
- for (i = 0; i < LEN(vts); i++) { | |
- fd = open(vts[i], O_RDONLY); | |
- if (fd < 0) | |
+ n = estrtonum(argv[0], 0, UINT_MAX); | |
+ for (i = 0; i < LEN(vt); i++) { | |
+ if ((fd = open(vt[i], O_RDONLY)) < 0) | |
continue; | |
c = 0; | |
if (ioctl(fd, KDGKBTYPE, &c) == 0) | |
- goto VTfound; | |
- close(fd); | |
+ goto found; | |
+ if (close(fd) < 0) | |
+ eprintf("close %s:", vt[i]); | |
} | |
+ eprintf("no console found\n"); | |
- eprintf("couldn't find a console.\n"); | |
-VTfound: | |
+found: | |
if (ioctl(fd, VT_ACTIVATE, n) == -1) | |
- eprintf("VT_ACTIVATE %d:", n); | |
+ eprintf("VT_ACTIVATE %u:", n); | |
if (ioctl(fd, VT_WAITACTIVE, n) == -1) | |
- eprintf("VT_WAITACTIVE %d:", n); | |
- close(fd); | |
+ eprintf("VT_WAITACTIVE %u:", n); | |
+ if (close(fd) < 0) | |
+ eprintf("close %s:", vt[i]); | |
return 0; | |
} | |
diff --git a/libutil/strtonum.c b/libutil/strtonum.c | |
@@ -0,0 +1,85 @@ | |
+/* $OpenBSD: strtonum.c,v 1.7 2013/04/17 18:40:58 tedu Exp $ */ | |
+ | |
+/* | |
+ * Copyright (c) 2004 Ted Unangst and Todd Miller | |
+ * All rights reserved. | |
+ * | |
+ * Permission to use, copy, modify, and distribute this software for any | |
+ * purpose with or without fee is hereby granted, provided that the above | |
+ * copyright notice and this permission notice appear in all copies. | |
+ * | |
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
+ */ | |
+ | |
+#include <errno.h> | |
+#include <limits.h> | |
+#include <stdlib.h> | |
+ | |
+#include "../util.h" | |
+ | |
+#define INVALID 1 | |
+#define TOOSMALL 2 | |
+#define TOOLARGE 3 | |
+ | |
+long long | |
+strtonum(const char *numstr, long long minval, long long maxval, | |
+ const char **errstrp) | |
+{ | |
+ long long ll = 0; | |
+ int error = 0; | |
+ char *ep; | |
+ struct errval { | |
+ const char *errstr; | |
+ int err; | |
+ } ev[4] = { | |
+ { NULL, 0 }, | |
+ { "invalid", EINVAL }, | |
+ { "too small", ERANGE }, | |
+ { "too large", ERANGE }, | |
+ }; | |
+ | |
+ ev[0].err = errno; | |
+ errno = 0; | |
+ if (minval > maxval) { | |
+ error = INVALID; | |
+ } else { | |
+ ll = strtoll(numstr, &ep, 10); | |
+ if (numstr == ep || *ep != '\0') | |
+ error = INVALID; | |
+ else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) | |
+ error = TOOSMALL; | |
+ else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) | |
+ error = TOOLARGE; | |
+ } | |
+ if (errstrp != NULL) | |
+ *errstrp = ev[error].errstr; | |
+ errno = ev[error].err; | |
+ if (error) | |
+ ll = 0; | |
+ | |
+ return (ll); | |
+} | |
+ | |
+long long | |
+enstrtonum(int status, const char *numstr, long long minval, long long maxval) | |
+{ | |
+ const char *errstr; | |
+ long long ll; | |
+ | |
+ ll = strtonum(numstr, minval, maxval, &errstr); | |
+ if (errstr) | |
+ enprintf(status, "strtonum %s: %s\n", numstr, errstr); | |
+ return ll; | |
+} | |
+ | |
+long long | |
+estrtonum(const char *numstr, long long minval, long long maxval) | |
+{ | |
+ return enstrtonum(1, numstr, minval, maxval); | |
+} | |
diff --git a/util.h b/util.h | |
@@ -50,6 +50,12 @@ size_t estrlcat(char *, const char *, size_t); | |
size_t strlcpy(char *, const char *, size_t); | |
size_t estrlcpy(char *, const char *, size_t); | |
+/* strtonum.c */ | |
+#undef strtonum | |
+long long strtonum(const char *, long long, long long, const char **); | |
+long long enstrtonum(int, const char *, long long, long long); | |
+long long estrtonum(const char *, long long, long long); | |
+ | |
/* tty.c */ | |
void devtotty(int, int *, int *); | |
int ttytostr(int, int, char *, size_t); |