(root)/
util-linux-2.39/
lib/
ttyutils.c
       1  /*
       2   * No copyright is claimed.  This code is in the public domain; do with
       3   * it what you wish.
       4   *
       5   * Written by Karel Zak <kzak@redhat.com>
       6   */
       7  #include <ctype.h>
       8  #include <unistd.h>
       9  
      10  #include "c.h"
      11  #include "ttyutils.h"
      12  
      13  
      14  static int get_env_int(const char *name)
      15  {
      16  	const char *cp = getenv(name);
      17  
      18  	if (cp) {
      19  		char *end = NULL;
      20  		long x;
      21  
      22  		errno = 0;
      23  		x = strtol(cp, &end, 10);
      24  
      25  		if (errno == 0 && end && *end == '\0' && end > cp &&
      26  		    x > 0 && x <= INT_MAX)
      27  			return x;
      28  	}
      29  
      30  	return -1;
      31  }
      32  
      33  int get_terminal_dimension(int *cols, int *lines)
      34  {
      35  	int c = 0, l = 0;
      36  
      37  #if defined(TIOCGWINSZ)
      38  	struct winsize	w_win;
      39  	if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &w_win) == 0) {
      40  		c = w_win.ws_col;
      41  		l = w_win.ws_row;
      42  	}
      43  #elif defined(TIOCGSIZE)
      44  	struct ttysize	t_win;
      45  	if (ioctl (STDOUT_FILENO, TIOCGSIZE, &t_win) == 0) {
      46  		c = t_win.ts_cols;
      47  		l = t_win.ts_lines;
      48  	}
      49  #endif
      50  	if (cols) {
      51  		if (c <= 0)
      52  			c = get_env_int("COLUMNS");
      53  		*cols = c;
      54  	}
      55  	if (lines) {
      56  		if (l <= 0)
      57  			l = get_env_int("LINES");
      58  		*lines = l;
      59  	}
      60  	return 0;
      61  }
      62  
      63  int get_terminal_width(int default_width)
      64  {
      65  	int width = 0;
      66  
      67  	get_terminal_dimension(&width, NULL);
      68  
      69  	return width > 0 ? width : default_width;
      70  }
      71  
      72  int get_terminal_stdfd(void)
      73  {
      74  	if (isatty(STDIN_FILENO))
      75  		return STDIN_FILENO;
      76  	if (isatty(STDOUT_FILENO))
      77  		return STDOUT_FILENO;
      78  	if (isatty(STDERR_FILENO))
      79  		return STDERR_FILENO;
      80  
      81  	return -EINVAL;
      82  }
      83  
      84  int get_terminal_name(const char **path,
      85  		      const char **name,
      86  		      const char **number)
      87  {
      88  	const char *tty;
      89  	const char *p;
      90  	int fd;
      91  
      92  
      93  	if (name)
      94  		*name = NULL;
      95  	if (path)
      96  		*path = NULL;
      97  	if (number)
      98  		*number = NULL;
      99  
     100  	fd = get_terminal_stdfd();
     101  	if (fd < 0)
     102  		return fd;	/* error */
     103  
     104  	tty = ttyname(fd);
     105  	if (!tty)
     106  		return -1;
     107  
     108  	if (path)
     109  		*path = tty;
     110  	if (name || number)
     111  		tty = strncmp(tty, "/dev/", 5) == 0 ? tty + 5 : tty;
     112  	if (name)
     113  		*name = tty;
     114  	if (number) {
     115  		for (p = tty; p && *p; p++) {
     116  			if (isdigit(*p)) {
     117  				*number = p;
     118  				break;
     119  			}
     120  		}
     121  	}
     122  	return 0;
     123  }
     124  
     125  int get_terminal_type(const char **type)
     126  {
     127  	*type = getenv("TERM");
     128  	if (*type)
     129  		return -EINVAL;
     130  	return 0;
     131  }
     132  
     133  #ifdef TEST_PROGRAM_TTYUTILS
     134  # include <stdlib.h>
     135  int main(void)
     136  {
     137  	const char *path, *name, *num;
     138  	int c, l;
     139  
     140  	if (get_terminal_name(&path, &name, &num) == 0) {
     141  		fprintf(stderr, "tty path:   %s\n", path);
     142  		fprintf(stderr, "tty name:   %s\n", name);
     143  		fprintf(stderr, "tty number: %s\n", num);
     144  	}
     145  	get_terminal_dimension(&c, &l);
     146  	fprintf(stderr,         "tty cols:   %d\n", c);
     147  	fprintf(stderr,         "tty lines:  %d\n", l);
     148  
     149  
     150  	return EXIT_SUCCESS;
     151  }
     152  #endif /* TEST_PROGRAM_TTYUTILS */