From b6669b5f196275bcf205abe5904b63bcd9213011 Mon Sep 17 00:00:00 2001 From: FRIGN Date: Mon, 7 Sep 2015 12:21:26 +0200 Subject: [PATCH] Refactor chvt(1) 1) Properly implement arg.h. 2) Use estrtonum instead of estrtol. 3) Check close(). 4) Small fixes. 5) Update manpage. --- Makefile | 1 + chvt.1 | 9 ++--- chvt.c | 33 ++++++++++-------- libutil/strtonum.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++ util.h | 6 ++++ 5 files changed, 115 insertions(+), 19 deletions(-) create mode 100644 libutil/strtonum.c diff --git a/Makefile b/Makefile index c758095..4ab1856 100644 --- 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 index 5c49069..50f2005 100644 --- 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 index 95e4ff8..edd2d9b 100644 --- a/chvt.c +++ b/chvt.c @@ -3,8 +3,8 @@ #include #include +#include #include -#include #include #include @@ -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 new file mode 100644 index 0000000..c0ac401 --- /dev/null +++ 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 +#include +#include + +#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 index 7b832e7..073156d 100644 --- 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);