]> git.ipfire.org Git - thirdparty/util-linux.git/blob - lib/ttyutils.c
scriptreplay: fix uninitialized value [coverity scan]
[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 #ifdef HAVE_GETTTYNAM
11 # include <ttyent.h>
12 #endif
13
14 #include "c.h"
15 #include "ttyutils.h"
16
17 #ifdef __linux__
18 # ifndef DEFAULT_VCTERM
19 # define DEFAULT_VCTERM "linux"
20 # endif
21 # if defined (__s390__) || defined (__s390x__)
22 # define DEFAULT_TTYS0 "dumb"
23 # define DEFAULT_TTY32 "ibm327x"
24 # define DEFAULT_TTYS1 "vt220"
25 # endif
26 # ifndef DEFAULT_STERM
27 # define DEFAULT_STERM "vt102"
28 # endif
29 #elif defined(__GNU__)
30 # ifndef DEFAULT_VCTERM
31 # define DEFAULT_VCTERM "hurd"
32 # endif
33 # ifndef DEFAULT_STERM
34 # define DEFAULT_STERM "vt102"
35 # endif
36 #else
37 # ifndef DEFAULT_VCTERM
38 # define DEFAULT_VCTERM "vt100"
39 # endif
40 # ifndef DEFAULT_STERM
41 # define DEFAULT_STERM "vt100"
42 # endif
43 #endif
44
45 static int get_env_int(const char *name)
46 {
47 const char *cp = getenv(name);
48
49 if (cp) {
50 char *end = NULL;
51 long x;
52
53 errno = 0;
54 x = strtol(cp, &end, 10);
55
56 if (errno == 0 && end && *end == '\0' && end > cp &&
57 x > 0 && x <= INT_MAX)
58 return x;
59 }
60
61 return -1;
62 }
63
64 int get_terminal_dimension(int *cols, int *lines)
65 {
66 int c = 0, l = 0;
67
68 #if defined(TIOCGWINSZ)
69 struct winsize w_win;
70 if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &w_win) == 0) {
71 c = w_win.ws_col;
72 l = w_win.ws_row;
73 }
74 #elif defined(TIOCGSIZE)
75 struct ttysize t_win;
76 if (ioctl (STDOUT_FILENO, TIOCGSIZE, &t_win) == 0) {
77 c = t_win.ts_cols;
78 l = t_win.ts_lines;
79 }
80 #endif
81 if (cols) {
82 if (c <= 0)
83 c = get_env_int("COLUMNS");
84 *cols = c;
85 }
86 if (lines) {
87 if (l <= 0)
88 l = get_env_int("LINES");
89 *lines = l;
90 }
91 return 0;
92 }
93
94 int get_terminal_width(int default_width)
95 {
96 int width = 0;
97
98 get_terminal_dimension(&width, NULL);
99
100 return width > 0 ? width : default_width;
101 }
102
103 int get_terminal_stdfd(void)
104 {
105 if (isatty(STDIN_FILENO))
106 return STDIN_FILENO;
107 if (isatty(STDOUT_FILENO))
108 return STDOUT_FILENO;
109 if (isatty(STDERR_FILENO))
110 return STDERR_FILENO;
111
112 return -EINVAL;
113 }
114
115 int get_terminal_name(const char **path,
116 const char **name,
117 const char **number)
118 {
119 const char *tty;
120 const char *p;
121 int fd;
122
123
124 if (name)
125 *name = NULL;
126 if (path)
127 *path = NULL;
128 if (number)
129 *number = NULL;
130
131 fd = get_terminal_stdfd();
132 if (fd < 0)
133 return fd; /* error */
134
135 tty = ttyname(fd);
136 if (!tty)
137 return -1;
138
139 if (path)
140 *path = tty;
141 if (name || number)
142 tty = strncmp(tty, "/dev/", 5) == 0 ? tty + 5 : tty;
143 if (name)
144 *name = tty;
145 if (number) {
146 for (p = tty; p && *p; p++) {
147 if (isdigit(*p)) {
148 *number = p;
149 break;
150 }
151 }
152 }
153 return 0;
154 }
155
156 int get_terminal_type(const char **type)
157 {
158 *type = getenv("TERM");
159 if (*type)
160 return -EINVAL;
161 return 0;
162 }
163
164 char *get_terminal_default_type(const char *ttyname, int is_serial)
165 {
166 if (ttyname) {
167 #ifdef HAVE_GETTTYNAM
168 struct ttyent *ent = getttynam(ttyname);
169
170 if (ent && ent->ty_type)
171 return strdup(ent->ty_type);
172 #endif
173
174 #if defined (__s390__) || defined (__s390x__)
175 /*
176 * Special terminal on first serial line on a S/390(x) which
177 * is due legacy reasons a block terminal of type 3270 or
178 * higher. Whereas the second serial line on a S/390(x) is
179 * a real character terminal which is compatible with VT220.
180 */
181 if (strcmp(ttyname, "ttyS0") == 0) /* linux/drivers/s390/char/con3215.c */
182 return strdup(DEFAULT_TTYS0);
183 else if (strncmp(ttyname, "3270/tty", 8) == 0) /* linux/drivers/s390/char/con3270.c */
184 return strdup(DEFAULT_TTY32);
185 else if (strcmp(ttyname, "ttyS1") == 0) /* linux/drivers/s390/char/sclp_vt220.c */
186 return strdup(DEFAULT_TTYS1);
187 #endif
188 }
189
190 return strdup(is_serial ? DEFAULT_STERM : DEFAULT_VCTERM);
191 }
192
193 #ifdef TEST_PROGRAM_TTYUTILS
194 # include <stdlib.h>
195 int main(void)
196 {
197 const char *path, *name, *num;
198 int c, l;
199
200 if (get_terminal_name(&path, &name, &num) == 0) {
201 char *term;
202
203 fprintf(stderr, "tty path: %s\n", path);
204 fprintf(stderr, "tty name: %s\n", name);
205 fprintf(stderr, "tty number: %s\n", num);
206
207 fprintf(stderr, "tty term: %s\n", getenv("TERM"));
208
209 term = get_terminal_default_type(name, 0);
210 fprintf(stderr, "tty dflt term: %s\n", term);
211 free(term);
212 }
213 get_terminal_dimension(&c, &l);
214 fprintf(stderr, "tty cols: %d\n", c);
215 fprintf(stderr, "tty lines: %d\n", l);
216
217
218 return EXIT_SUCCESS;
219 }
220 #endif /* TEST_PROGRAM_TTYUTILS */