]> git.ipfire.org Git - thirdparty/util-linux.git/blob - lib/ttyutils.c
Merge branch 'fix-map-current-user-shortopt' of https://github.com/mat8913/util-linux
[thirdparty/util-linux.git] / 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 else if (isatty(STDOUT_FILENO))
77 return STDOUT_FILENO;
78 else 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 */