URI: 
       Refactor chvt(1) - ubase - suckless linux base utils
  HTML git clone git://git.suckless.org/ubase
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit b6669b5f196275bcf205abe5904b63bcd9213011
   DIR parent cdaa7b860ea3af523318bc8d3c9a412fcd0d24b4
  HTML 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:
         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(-)
       ---
   DIR 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)
   DIR 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 .
   DIR 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;
        }
   DIR 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);
       +}
   DIR 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);