/**
@file termSizeWatch.c
@author Mitch Richling <http://www.mitchr.me/>
@Copyright Copyright 1998 by Mitch Richling. All rights reserved.
@brief How to monitor terminal size@EOL
@Keywords termios terminal tty window
@Std C89
Demonstrates how to monitor the changing size of a
terminal window via the SIGWINCH signal mechanism. In
addition, various other terminal operations are
demonstrated: how to determine if a process is connected
to a terminal, getting the current terminal's name, and
getting the size of the current terminal.
A note for budding curses and ncurses programmers. The
"standard" way to make curses work when the terminal may
be resized, is to install a signal handler, like the one
demonstrated below, that will update things if the
window is resized (an endwin & refresh). Alternately,
ncurses provides a hook called resizeterm to help
automate this process..
*/
#include <termios.h> /* terminal I/O POSIX */
#include <sys/ioctl.h> /* for ioctl() */
#include <unistd.h> /* UNIX std stf POSIX */
#include <stdio.h> /* I/O lib ISOC */
#include <signal.h> /* UNIX signals POSIX */
#include <string.h> /* Strings ISOC */
#include <stdlib.h> /* Standard Lib ISOC */
/* Function prototypes */
static void winWatch(int sigNo);
int main();
int main() {
struct winsize termSize;
char *termNameTTY;
int termIsTTY;
struct sigaction newSigAction;
struct sigaction oldSigAction;
/* Report the current STDIN file descriptor. */
printf("Current STDIN FD: %d\n", (int)STDIN_FILENO);
/* Figure out if we are attached to a TTY. */
termIsTTY = isatty(STDIN_FILENO);
if(termIsTTY) {
printf("We are on a TTY!\n");
} else {
printf("We are NOT on a TTY!\n");
printf("ERROR: We must be connected to a TTY.\n");
exit(1);
} /* end if */
/* Get our TTY name -- just because we can. */
termNameTTY = ttyname(STDIN_FILENO);
if(termNameTTY == NULL) {
printf("ERROR: Could not get the name of our TTY.\n");
exit(1);
} /* end if */
printf("Current TTY name: %s\n", termNameTTY);
/* Get an initial window size. */
if(ioctl(STDIN_FILENO, TIOCGWINSZ, (char *) &termSize) < 0) {
printf("ERROR: We ioctl failure for our TTY.\n");
exit(1);
} /* end if */
printf("Term Size: (%d,%d)\n", (int)termSize.ws_row, (int)termSize.ws_col);
/* Set a signal handler to catch SIGWINCH */
memset(&newSigAction.sa_mask, 0, sizeof(newSigAction.sa_mask));
newSigAction.sa_flags = 0;
newSigAction.sa_handler = winWatch;
if(sigaction(SIGWINCH, &newSigAction, &oldSigAction) < 0) {
printf("ERROR: Unable to install signal handler\n");
exit(1);
} /* end if */
/* Sleep forever, catching signals as required. */
while(1) {
printf("Sleeping...\n");
sleep(10);
} /* end while */
} /* end func main */
/* Signal handler function intended to catch a SIGWINCH signal. It
just prints the window size. See the main function for more
information regarding how to use isatty() and ioctl(). */
static void winWatch(int sigNo) {
struct winsize termSize;
if(sigNo == SIGWINCH) {
if(isatty(STDIN_FILENO)) {
if(ioctl(STDIN_FILENO, TIOCGWINSZ, (char *) &termSize) >= 0) {
printf("NEW Term Size: (%d,%d)\n", (int)termSize.ws_row, (int)termSize.ws_col);
} else {
printf("ERROR: We ioctl failure for our TTY.\n");
} /* end if */
} else {
printf("ERROR: We isatty failure for our TTY.\n");
} /* end if */
} else {
printf("ERROR: We got the wrong signal directed to winWatch (%d).\n", (int)sigNo);
} /* end if */
} /* end func winWatch */
Generated by GNU Enscript 1.6.5.2.