ubase

suckless linux base utils
git clone git://git.suckless.org/ubase
Log | Files | Refs | README | LICENSE

commit b6669b5f196275bcf205abe5904b63bcd9213011
parent cdaa7b860ea3af523318bc8d3c9a412fcd0d24b4
Author: FRIGN <dev@frign.de>
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:
MMakefile | 1+
Mchvt.1 | 9+++++----
Mchvt.c | 33++++++++++++++++++---------------
Alibutil/strtonum.c | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mutil.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);