setupterm.c revision 1.4
1/* $NetBSD: setupterm.c,v 1.4 2013/06/07 13:16:18 roy Exp $ */ 2 3/* 4 * Copyright (c) 2009, 2011 The NetBSD Foundation, Inc. 5 * 6 * This code is derived from software contributed to The NetBSD Foundation 7 * by Roy Marples. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> 31__RCSID("$NetBSD: setupterm.c,v 1.4 2013/06/07 13:16:18 roy Exp $"); 32 33#include <assert.h> 34#include <err.h> 35#include <stdio.h> 36#include <stdlib.h> 37#include <strings.h> 38#include <unistd.h> 39#include <term_private.h> 40#include <term.h> 41 42#define reterr(code, msg) \ 43 do { \ 44 if (errret == NULL) \ 45 errx(EXIT_FAILURE, msg); \ 46 else { \ 47 *errret = code; \ 48 return ERR; \ 49 } \ 50 } while (0 /* CONSTCOND */) 51 52#define reterrarg(code, msg, arg) \ 53 do { \ 54 if (errret == NULL) \ 55 errx(EXIT_FAILURE, msg, arg); \ 56 else { \ 57 *errret = code; \ 58 return ERR; \ 59 } \ 60 } while (0 /* CONSTCOND */) 61 62 63int 64ti_setupterm(TERMINAL **nterm, const char *term, int fildes, int *errret) 65{ 66 int error; 67 68 _DIAGASSERT(nterm != NULL); 69 70 if (term == NULL) 71 term = getenv("TERM"); 72 if (term == NULL || *term == '\0') { 73 *nterm = NULL; 74 reterr(0, "TERM environment variable not set"); 75 } 76 if (fildes == STDOUT_FILENO && !isatty(fildes)) 77 fildes = STDERR_FILENO; 78 79 *nterm = calloc(1, sizeof(**nterm)); 80 if (*nterm == NULL) 81 reterr(-1, "not enough memory to create terminal structure"); 82 83 error = _ti_getterm(*nterm, term, 0); 84 if (error != 1) { 85 del_curterm(*nterm); 86 *nterm = NULL; 87 switch (error) { 88 case -1: 89 reterr(error, "cannot access the terminfo database"); 90 /* NOTREACHED */ 91 case 0: 92 reterrarg(error, 93 "%s: terminal not listed in terminfo datase", 94 term); 95 /* NOTREACHED */ 96 default: 97 reterr(-1, "unknown error"); 98 /* NOTREACHED */ 99 } 100 } 101 102 (*nterm)->fildes = fildes; 103 _ti_setospeed(*nterm); 104 if (t_generic_type(*nterm)) 105 reterrarg(0, "%s: generic terminal", term); 106 if (t_hard_copy(*nterm)) 107 reterrarg(1, "%s: hardcopy terminal", term); 108 /* POSIX requires 1 for success */ 109 if (errret) 110 *errret = 1; 111 return OK; 112} 113 114int 115setupterm(const char *term, int fildes, int *errret) 116{ 117 TERMINAL *nterm; 118 int ret; 119 120 if (errret != NULL) 121 *errret = ERR; 122 ret = ti_setupterm(&nterm, term, fildes, errret); 123 if (nterm != NULL) 124 set_curterm(nterm); 125 return ret; 126} 127