Module Name: src Committed By: christos Date: Sat Feb 27 15:36:40 UTC 2021
Modified Files: src/usr.bin/resize: Makefile resize.c Added Files: src/usr.bin/resize: resize.h resize.man Removed Files: src/usr.bin/resize: resize.1 Log Message: Add a maintainable version of resize, with a copy target and a header that provides all the glue needed without other X headers. To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/usr.bin/resize/Makefile \ src/usr.bin/resize/resize.c cvs rdiff -u -r1.2 -r0 src/usr.bin/resize/resize.1 cvs rdiff -u -r0 -r1.1 src/usr.bin/resize/resize.h \ src/usr.bin/resize/resize.man Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/resize/Makefile diff -u src/usr.bin/resize/Makefile:1.1 src/usr.bin/resize/Makefile:1.2 --- src/usr.bin/resize/Makefile:1.1 Sun Dec 27 16:13:18 2020 +++ src/usr.bin/resize/Makefile Sat Feb 27 10:36:39 2021 @@ -1,7 +1,33 @@ -# $NetBSD: Makefile,v 1.1 2020/12/27 21:13:18 reinoud Exp $ +# $NetBSD: Makefile,v 1.2 2021/02/27 15:36:39 christos Exp $ + +.include <bsd.own.mk> WARNS= 3 PROG= resize -SRCS= resize.c xstrings.c +SRCS= resize.c + +CPPFLAGS+=-DRESIZE_ONLY +DPADD+= ${LIBUTIL} +LDADD+= -lutil .include <bsd.prog.mk> + +XTERM=${X11SRCDIR}/external/mit/xterm/dist + +.for i in resize.c resize.man +copy:: ${.CURDIR}/${i} +${.CURDIR}/${i}: ${XTERM}/${i} + cp -p ${.ALLSRC} ${.TARGET} +.endfor + +CLEANFILES+=resize.1 + +resize.1: resize.man + @rm -f ${.TARGET} + ${TOOL_SED} \ + -e "s@__app_date__@1970-01-01@" \ + -e "s@__app_version__@NetBSD@" \ + -e "s@__default_termname__@vt100@" \ + -e "s@__mansuffix__@1@" \ + -e "s@__miscmansuffix__@7@" \ + < ${.ALLSRC} > ${.TARGET} Index: src/usr.bin/resize/resize.c diff -u src/usr.bin/resize/resize.c:1.1 src/usr.bin/resize/resize.c:1.2 --- src/usr.bin/resize/resize.c:1.1 Sun Dec 27 16:13:18 2020 +++ src/usr.bin/resize/resize.c Sat Feb 27 10:36:39 2021 @@ -1,8 +1,7 @@ -/* $NetBSD: resize.c,v 1.1 2020/12/27 21:13:18 reinoud Exp $ */ -/* $XTermId: resize.c,v 1.139 2017/05/31 08:58:56 tom Exp $ */ +/* $XTermId: resize.c,v 1.144 2020/06/03 00:26:23 tom Exp $ */ /* - * Copyright 2003-2015,2017 by Thomas E. Dickey + * Copyright 2003-2018,2020 by Thomas E. Dickey * * All Rights Reserved * @@ -53,32 +52,51 @@ * SOFTWARE. */ -/* - * Extracted version from Xterm tailored for NetBSD - */ /* resize.c */ #include <stdio.h> #include <ctype.h> -#include <stdlib.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include <errno.h> -#include <unistd.h> -#include <strings.h> -#include <libgen.h> -#include <termios.h> -#include "xstrings.h" +#ifdef RESIZE_ONLY +#include "resize.h" +#else +#include <xterm.h> +#include <version.h> +#include <xstrings.h> +#include <xtermcap.h> +#include <xterm_io.h> +#endif + +#ifndef USE_TERMINFO /* avoid conflict with configure script */ +#if defined(__QNX__) || defined(__SCO__) || defined(linux) || defined(__OpenBSD__) || defined(__UNIXWARE__) +#define USE_TERMINFO +#endif +#endif + +#if defined(__QNX__) +#include <unix.h> +#endif -/* imported from origional <xterm.h> */ -#define DFT_TERMTYPE "xterm" -#define UIntClr(dst,bits) dst = dst & (unsigned) ~(bits) +/* + * Some OS's may want to use both, like SCO for example. We catch here anyone + * who hasn't decided what they want. + */ +#if !defined(USE_TERMCAP) && !defined(USE_TERMINFO) +#define USE_TERMINFO +#endif #include <signal.h> #include <pwd.h> +#ifdef USE_IGNORE_RC +int ignore_unused; +#endif + +#ifdef __MVS__ +#define ESCAPE(string) "\047" string +#else #define ESCAPE(string) "\033" string +#endif #define EMULATIONS 2 #define SUN 1 @@ -89,6 +107,7 @@ #define SHELL_UNKNOWN 0 #define SHELL_C 1 #define SHELL_BOURNE 2 + /* *INDENT-OFF* */ static struct { const char *name; @@ -124,6 +143,13 @@ static const char *const getsize[EMULATI ESCAPE("7") ESCAPE("[r") ESCAPE("[9999;9999H") ESCAPE("[6n"), ESCAPE("[18t"), }; +#if defined(USE_STRUCT_WINSIZE) +static const char *const getwsize[EMULATIONS] = +{ /* size in pixels */ + 0, + ESCAPE("[14t"), +}; +#endif /* USE_STRUCT_WINSIZE */ static const char *const restore[EMULATIONS] = { ESCAPE("8"), @@ -135,7 +161,13 @@ static const char *const setsize[EMULATI ESCAPE("[8;%s;%st"), }; +#ifdef USE_ANY_SYSV_TERMIO +static struct termio tioorig; +#elif defined(USE_TERMIOS) static struct termios tioorig; +#else +static struct sgttyb sgorig; +#endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */ static const char *const size[EMULATIONS] = { @@ -146,6 +178,18 @@ static const char sunname[] = "sunsize"; static int tty; static FILE *ttyfp; +#if defined(USE_STRUCT_WINSIZE) +static const char *wsize[EMULATIONS] = +{ + 0, + ESCAPE("[4;%hd;%hdt"), +}; +#endif /* USE_STRUCT_WINSIZE */ + +static void failed(const char *) GCC_NORETURN; +static void onintr(int) GCC_NORETURN; +static void resize_timeout(int) GCC_NORETURN; +static void Usage(void) GCC_NORETURN; static void failed(const char *s) @@ -162,7 +206,13 @@ failed(const char *s) static void onintr(int sig GCC_UNUSED) { +#ifdef USE_ANY_SYSV_TERMIO + (void) ioctl(tty, TCSETAW, &tioorig); +#elif defined(USE_TERMIOS) (void) tcsetattr(tty, TCSADRAIN, &tioorig); +#else /* not USE_TERMIOS */ + (void) ioctl(tty, TIOCSETP, &sgorig); +#endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */ exit(EXIT_FAILURE); } @@ -182,6 +232,31 @@ Usage(void) exit(EXIT_FAILURE); } +#ifdef USE_TERMCAP +static void +print_termcap(const char *termcap) +{ + int ch; + + putchar('\''); + while ((ch = *termcap++) != '\0') { + switch (ch & 0xff) { + case 127: /* undo bug in GNU termcap */ + printf("^?"); + break; + case '\'': /* must escape anyway (unlikely) */ + /* FALLTHRU */ + case '!': /* must escape for SunOS csh */ + putchar('\\'); + /* FALLTHRU */ + default: + putchar(ch); + break; + } + } + putchar('\''); +} +#endif /* USE_TERMCAP */ static int checkdigits(char *str) @@ -198,12 +273,19 @@ static void readstring(FILE *fp, char *buf, const char *str) { int last, c; +#if !defined(USG) && !defined(__minix) + /* What is the advantage of setitimer() over alarm()? */ struct itimerval it; +#endif signal(SIGALRM, resize_timeout); +#if defined(USG) || defined(__minix) + alarm(TIMEOUT); +#else memset((char *) &it, 0, sizeof(struct itimerval)); it.it_value.tv_sec = TIMEOUT; setitimer(ITIMER_REAL, &it, (struct itimerval *) NULL); +#endif if ((c = getc(fp)) == 0233) { /* meta-escape, CSI */ c = ESCAPE("")[0]; *buf++ = (char) c; @@ -219,8 +301,12 @@ readstring(FILE *fp, char *buf, const ch while ((*buf++ = (char) getc(fp)) != last) { ; } +#if defined(USG) || defined(__minix) + alarm(0); +#else memset((char *) &it, 0, sizeof(struct itimerval)); setitimer(ITIMER_REAL, &it, (struct itimerval *) NULL); +#endif *buf = 0; } @@ -230,15 +316,35 @@ readstring(FILE *fp, char *buf, const ch int main(int argc, char **argv ENVP_ARG) { +#ifdef USE_TERMCAP + char *env; +#endif char *ptr; int emu = VT100; char *shell; int i; int rc; int rows, cols; +#ifdef USE_ANY_SYSV_TERMIO + struct termio tio; +#elif defined(USE_TERMIOS) struct termios tio; +#else + struct sgttyb sg; +#endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */ +#ifdef USE_TERMCAP + int ok_tcap = 1; + char termcap[TERMCAP_SIZE]; + char newtc[TERMCAP_SIZE]; +#endif /* USE_TERMCAP */ char buf[BUFSIZ]; +#ifdef TTYSIZE_STRUCT + TTYSIZE_STRUCT ts; +#endif char *name_of_tty; +#ifdef CANT_OPEN_DEV_TTY + extern char *ttyname(); +#endif const char *setname = ""; myname = x_basename(argv[0]); @@ -258,7 +364,7 @@ main(int argc, char **argv ENVP_ARG) shell_type = SHELL_C; break; case 'v': - printf("Xterm(330)\n"); + printf("%s\n", xtermVersion()); exit(EXIT_SUCCESS); default: Usage(); /* Never returns */ @@ -307,6 +413,9 @@ main(int argc, char **argv ENVP_ARG) } else if (argc != 0) { Usage(); /* Never returns */ } +#ifdef CANT_OPEN_DEV_TTY + if ((name_of_tty = ttyname(fileno(stderr))) == NULL) +#endif name_of_tty = x_strdup("/dev/tty"); if ((ttyfp = fopen(name_of_tty, "r+")) == NULL) { @@ -315,6 +424,21 @@ main(int argc, char **argv ENVP_ARG) exit(EXIT_FAILURE); } tty = fileno(ttyfp); +#ifdef USE_TERMCAP + if ((env = x_getenv("TERM")) == 0) { + env = x_strdup(DFT_TERMTYPE); + if (SHELL_BOURNE == shell_type) { + setname = "TERM=" DFT_TERMTYPE ";\nexport TERM;\n"; + } else { + setname = "setenv TERM " DFT_TERMTYPE ";\n"; + } + } + termcap[0] = 0; /* ...just in case we've accidentally gotten terminfo */ + if (tgetent(termcap, env) <= 0 || termcap[0] == 0) { + ok_tcap = 0; + } +#endif /* USE_TERMCAP */ +#ifdef USE_TERMINFO if (x_getenv("TERM") == 0) { if (SHELL_BOURNE == shell_type) { setname = "TERM=" DFT_TERMTYPE ";\nexport TERM;\n"; @@ -322,7 +446,17 @@ main(int argc, char **argv ENVP_ARG) setname = "setenv TERM " DFT_TERMTYPE ";\n"; } } +#endif /* USE_TERMINFO */ +#ifdef USE_ANY_SYSV_TERMIO + rc = ioctl(tty, TCGETA, &tioorig); + tio = tioorig; + UIntClr(tio.c_iflag, (ICRNL | IUCLC)); + UIntClr(tio.c_lflag, (ICANON | ECHO)); + tio.c_cflag |= CS8; + tio.c_cc[VMIN] = 6; + tio.c_cc[VTIME] = 1; +#elif defined(USE_TERMIOS) rc = tcgetattr(tty, &tioorig); tio = tioorig; UIntClr(tio.c_iflag, ICRNL); @@ -330,6 +464,12 @@ main(int argc, char **argv ENVP_ARG) tio.c_cflag |= CS8; tio.c_cc[VMIN] = 6; tio.c_cc[VTIME] = 1; +#else /* not USE_TERMIOS */ + rc = ioctl(tty, TIOCGETP, &sgorig); + sg = sgorig; + sg.sg_flags |= RAW; + UIntClr(sg.sg_flags, ECHO); +#endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */ if (rc != 0) failed("get tty settings"); @@ -337,7 +477,13 @@ main(int argc, char **argv ENVP_ARG) signal(SIGQUIT, onintr); signal(SIGTERM, onintr); +#ifdef USE_ANY_SYSV_TERMIO + rc = ioctl(tty, TCSETAW, &tio); +#elif defined(USE_TERMIOS) rc = tcsetattr(tty, TCSADRAIN, &tio); +#else /* not USE_TERMIOS */ + rc = ioctl(tty, TIOCSETP, &sg); +#endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */ if (rc != 0) failed("set tty settings"); @@ -364,8 +510,38 @@ main(int argc, char **argv ENVP_ARG) } if (restore[emu]) IGNORE_RC(write(tty, restore[emu], strlen(restore[emu]))); - +#if defined(USE_STRUCT_WINSIZE) + /* finally, set the tty's window size */ + if (getwsize[emu]) { + /* get the window size in pixels */ + IGNORE_RC(write(tty, getwsize[emu], strlen(getwsize[emu]))); + readstring(ttyfp, buf, wsize[emu]); + if (sscanf(buf, wsize[emu], &ts.ws_xpixel, &ts.ws_ypixel) != 2) { + fprintf(stderr, "%s: Can't get window size\r\n", myname); + onintr(0); + } + setup_winsize(ts, rows, cols, 0, 0); + SET_TTYSIZE(tty, ts); + } else if (ioctl(tty, TIOCGWINSZ, &ts) != -1) { + /* we don't have any way of directly finding out + the current height & width of the window in pixels. We try + our best by computing the font height and width from the "old" + window-size values, and multiplying by these ratios... */ +#define scaled(old,new,len) (old)?((unsigned)(new)*(len)/(old)):(len) + setup_winsize(ts, rows, cols, + scaled(TTYSIZE_ROWS(ts), rows, ts.ws_ypixel), + scaled(TTYSIZE_COLS(ts), cols, ts.ws_xpixel)); + SET_TTYSIZE(tty, ts); + } +#endif /* USE_STRUCT_WINSIZE */ + +#ifdef USE_ANY_SYSV_TERMIO + rc = ioctl(tty, TCSETAW, &tioorig); +#elif defined(USE_TERMIOS) rc = tcsetattr(tty, TCSADRAIN, &tioorig); +#else /* not USE_TERMIOS */ + rc = ioctl(tty, TIOCSETP, &sgorig); +#endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */ if (rc != 0) failed("set tty settings"); @@ -373,16 +549,62 @@ main(int argc, char **argv ENVP_ARG) signal(SIGQUIT, SIG_DFL); signal(SIGTERM, SIG_DFL); +#ifdef USE_TERMCAP + if (ok_tcap) { + /* update termcap string */ + /* first do columns */ + if ((ptr = x_strindex(termcap, "co#")) == NULL) { + fprintf(stderr, "%s: No `co#'\n", myname); + exit(EXIT_FAILURE); + } + + i = (int) (ptr - termcap) + 3; + strncpy(newtc, termcap, (size_t) i); + sprintf(newtc + i, "%d", cols); + if ((ptr = strchr(ptr, ':')) != 0) + strcat(newtc, ptr); + + /* now do lines */ + if ((ptr = x_strindex(newtc, "li#")) == NULL) { + fprintf(stderr, "%s: No `li#'\n", myname); + exit(EXIT_FAILURE); + } + + i = (int) (ptr - newtc) + 3; + strncpy(termcap, newtc, (size_t) i); + sprintf(termcap + i, "%d", rows); + if ((ptr = strchr(ptr, ':')) != 0) + strcat(termcap, ptr); + } +#endif /* USE_TERMCAP */ if (SHELL_BOURNE == shell_type) { +#ifdef USE_TERMCAP + if (ok_tcap) { + printf("%sTERMCAP=", setname); + print_termcap(termcap); + printf(";\nexport TERMCAP;\n"); + } +#endif /* USE_TERMCAP */ +#ifdef USE_TERMINFO printf("%sCOLUMNS=%d;\nLINES=%d;\nexport COLUMNS LINES;\n", setname, cols, rows); +#endif /* USE_TERMINFO */ } else { /* not Bourne shell */ +#ifdef USE_TERMCAP + if (ok_tcap) { + printf("set noglob;\n%ssetenv TERMCAP ", setname); + print_termcap(termcap); + printf(";\nunset noglob;\n"); + } +#endif /* USE_TERMCAP */ +#ifdef USE_TERMINFO printf("set noglob;\n%ssetenv COLUMNS '%d';\nsetenv LINES '%d';\nunset noglob;\n", setname, cols, rows); +#endif /* USE_TERMINFO */ } exit(EXIT_SUCCESS); } Added files: Index: src/usr.bin/resize/resize.h diff -u /dev/null src/usr.bin/resize/resize.h:1.1 --- /dev/null Sat Feb 27 10:36:40 2021 +++ src/usr.bin/resize/resize.h Sat Feb 27 10:36:39 2021 @@ -0,0 +1,92 @@ +/* $NetBSD: resize.h,v 1.1 2021/02/27 15:36:39 christos Exp $ */ + +/*- + * Copyright (c) 2021 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <time.h> +#include <termios.h> +#include <pwd.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <fcntl.h> +#include <util.h> +#include <signal.h> +#include <libgen.h> +#include <sys/ioctl.h> + +#define DFT_TERMTYPE "vt100" + +#define USE_TERMINFO +#define USE_STRUCT_WINSIZE +#define USE_TERMIOS + +#define GCC_NORETURN __dead +#define GCC_UNUSED __unused + +#define IGNORE_RC(a) (void)(a) +#define ENVP_ARG , char **envp + +#define TTYSIZE_STRUCT struct winsize +#define TTYSIZE_ROWS(ws) (ws).ws_row +#define TTYSIZE_COLS(ws) (ws).ws_col +#define SET_TTYSIZE(fd, ws) ioctl((fd), TIOCSWINSZ, &ws) + +#define x_basename(a) basename(a) +#define x_strdup(a) estrdup(a) +#define x_getenv(a) getenv(a) +#define x_getlogin(u, p) __nothing +#define x_strindex(s, c) strstr((s), (c)) + +static int +x_getpwuid(uid_t uid, struct passwd *pw) +{ + struct passwd *p = getpwuid(uid); + if (p == NULL) { + memset(pw, 0, sizeof(*pw)); + return 1; + } + *pw = *p; + return 0; +} + +#define setup_winsize(ws, row, col, xpixel, ypixel) \ + (void)((ws).ws_row = row, \ + (ws).ws_col = col, \ + (ws).ws_xpixel = xpixel, \ + (ws).ws_ypixel = ypixel) + +#define CharOf(a) ((unsigned char)(a)) +#define OkPasswd(pw) *((pw)->pw_name) +#define TypeMallocN(t, l) emalloc(sizeof(t) * (l)) +#define UIntClr(d, b) (d) = (d) & ~(b) + +#define xtermVersion() "NetBSD" Index: src/usr.bin/resize/resize.man diff -u /dev/null src/usr.bin/resize/resize.man:1.1 --- /dev/null Sat Feb 27 10:36:40 2021 +++ src/usr.bin/resize/resize.man Sat Feb 27 10:36:39 2021 @@ -0,0 +1,235 @@ +.\" $XTermId: resize.man,v 1.37 2019/02/07 00:16:12 tom Exp $ +.\" +.\" Copyright 1998-2017,2019 by Thomas E. Dickey +.\" +.\" All Rights Reserved +.\" +.\" Permission is hereby granted, free of charge, to any person obtaining a +.\" copy of this software and associated documentation files (the +.\" "Software"), to deal in the Software without restriction, including +.\" without limitation the rights to use, copy, modify, merge, publish, +.\" distribute, sublicense, and/or sell copies of the Software, and to +.\" permit persons to whom the Software is furnished to do so, subject to +.\" the following conditions: +.\" +.\" The above copyright notice and this permission notice shall be included +.\" in all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +.\" IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY +.\" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +.\" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +.\" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +.\" +.\" Except as contained in this notice, the name(s) of the above copyright +.\" holders shall not be used in advertising or otherwise to promote the +.\" sale, use or other dealings in this Software without prior written +.\" authorization. +.\" +.\" updated by Thomas E. Dickey for XFree86, 1998-2006. +.\" +.ds N Resize +.ds n resize +.\" +.\" Bulleted paragraph +.de bP +.ie n .IP \(bu 4 +.el .IP \(bu 2 +.. +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds AQ \(aq +.el .ds AQ ' +.ie \n(.g .ds `` \(lq +.el .ds `` `` +.ie \n(.g .ds '' \(rq +.el .ds '' '' +.TH RESIZE 1 "__app_date__" "__app_version__" "X Window System" +.SH NAME +resize \- set environment and terminal settings to current xterm window size +.SH SYNOPSIS +.B \*n +[ \fB\-v\fP | \fB\-u\fP | \fB\-c\fP ] [ \fB\-s\fP [ \fIrow col\fP ] ] +.SH DESCRIPTION +.I \*N +prints a shell command for setting the appropriate environment variables +to indicate the current size of \fIxterm\fP window from which the command +is run. +.PP +.I \*N +determines the command through several steps: +.bP +first, it finds the name of the user's shell program. +It uses the \fBSHELL\fP variable if set, +otherwise it uses the user's data from /etc/passwd. +.bP +then it decides whether to use Bourne shell syntax or C-Shell syntax. +It uses a built-in table of known shells, +which can be overridden by the \fB\-u\fP and \fB\-c\fP options. +.bP +then \fI\*n\fP asks the operating system for the terminal settings. +This is the same information which can be manipulated using \fIstty\fP. +.bP +then \fI\*n\fP asks the terminal for its size in characters. +Depending on whether the "\fB\-s\fP option is given, +\fI\*n\fP uses a different escape sequence to ask for this information. +.bP +at this point, \fI\*n\fP attempts to update the terminal settings +to reflect the terminal window's size in pixels: +.RS +.bP +if the \fB\-s\fP option is used, +\fI\*n\fP then asks the terminal for its size in pixels. +.bP +otherwise, +\fI\*n\fP asks the operating system for the information +and updates that after ensuring that the window's dimensions are +a multiple of the character height and width. +.bP +in either case, the updated terminal settings are done +using a different system call than used for \fIstty\fP. +.RE +.bP +then \fI\*n\fP updates the terminal settings to reflect any altered +values such as its size in rows or columns. +This affects the values shown by \fIstty\fP. +.bP +finally, \fI\*n\fP generates shell commands for setting the +environment variables, +and writes that to the standard output. +.SH EXAMPLES +For \fI\*n\fP's output to take effect, +\fI\*n\fP must either be evaluated +as part of the command line (usually done with a shell alias or function) or +else redirected to a file which can then be read in. +From the C shell (usually +known as \fI/bin/csh\fP), the following alias could be defined in the +user's \fI.cshrc\fP: +.sp +.nf + % alias rs \*(AQset noglob; eval \fC\`\fP\*n\fC\`\fP\*(AQ +.fi +.sp +After resizing the window, the user would type: +.sp +.nf + % rs +.fi +.sp +Users of versions of the Bourne shell (usually known as \fI/bin/sh\fP) that +don't have command +functions will need to send the output to a temporary file and then read it back +in with the \*(``.\*('' command: +.sp +.nf + $ \*n > /tmp/out + $ .\0/tmp/out +.fi +.SH OPTIONS +The following options may be used with \fI\*n\fP: +.TP 8 +.B \-c +This option indicates that C shell commands should be generated even if the +user's current shell does not appear to use C shell syntax. +.TP 8 +.B \-s \fR[\fIrows columns\fP] +This option indicates that Sun console escape sequences will be used +instead of the VT100-style \fIxterm\fP escape codes. +If \fIrows\fP and +\fIcolumns\fP are given, +\fI\*n\fP will ask the \fIxterm\fP to resize itself using those values. +.IP +Both of the escape sequences used for this option +(first to obtain the window size and +second to modify it) +are subject to \fIxterm\fP's \fBallowWindowOps\fP resource setting. +The window manager may also choose to disallow the change. +.IP +The VT100-style escape sequence used to determine the +screen size always works for VT100-compatible terminals. +VT100s have no corresponding way to modify the screensize. +.TP 8 +.B \-u +This option indicates that Bourne shell commands should be generated even if +the user's current shell does not appear to use Bourne shell syntax. +.TP 8 +.B \-v +This causes \fI\*n\fP to print a version number to the standard output, +and then exit. +.PP +Note that the Sun console escape sequences are recognized +by XFree86 \fIxterm\fP and +by \fIdtterm\fP. +The \fI\*n\fP program may be installed as \fIsunsize\fP, +which causes makes it assume the \fB\-s\fP option. +.PP +The \fIrows\fP and +\fIcolumns\fP arguments must appear last; though they are normally +associated with the \fB\-s\fP option, they are parsed separately. +.SH FILES +.TP 15 +/etc/termcap +for the base termcap entry to modify. +.TP 15 +~/.cshrc +user's alias for the command. +.SH ENVIRONMENT +.TP 15 +SHELL +Unless overridden by the \fB\-c\fP option, +\fI\*n\fP determines the user's current shell by +.RS +.bP +first checking if \fB$SHELL\fP +is set, and using that, +.bP +otherwise \fI\*n\fP looks in the password file +(/etc/passwd). +.RE +.IP +Generally Bourne-shell variants (including \fIksh\fP) +do not modify \fB$SHELL\fP, +so it is possible for \fI\*n\fP to be confused if one runs +\fI\*n\fP from a Bourne shell spawned from a C shell. +.IP +After determining the user's shell, \fI\*n\fP checks the shell's name +against a table of known shell names. +If it does not find the name in its table, \fI\*n\fP will use +C shell syntax for the generated commands to set environment variables. +.TP 15 +TERM +.IR \*N 's +generated shell command +sets this to "__default_termname__" if not already set. +.TP 15 +TERMCAP +.IR \*N 's +generated shell command +sets this variable on systems using termcap, +e.g., when \fI\*n\fP is linked with the \fItermcap\fP library +rather than a \fIterminfo\fP library. +The latter does not provide the complete text for a termcap entry. +.TP 15 +COLUMNS, LINES +.IR \*N 's +generated shell command +sets these variables on systems using terminfo. +Many applications (including the curses library) +use those variables when set to override their screensize. +.SH "SEE ALSO" +use_env(3x) +.br +csh(1), stty(1), tset(1) +.br +xterm(__mansuffix__) +.SH AUTHORS +Mark Vandevoorde (MIT-Athena), Edward Moy (Berkeley) +.br +Thomas Dickey (invisible-island.net). +.br +Copyright (c) 1984, 1985 by X Consortium +.br +See +.IR X (__miscmansuffix__) +for a complete copyright notice.