]>
Commit | Line | Data |
---|---|---|
0f23ee0c KZ |
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 | */ | |
4e76adb0 | 7 | #include <ctype.h> |
285c1f3a | 8 | #include <unistd.h> |
4e76adb0 | 9 | |
cba97be9 KZ |
10 | #ifdef HAVE_GETTTYNAM |
11 | # include <ttyent.h> | |
12 | #endif | |
13 | ||
4e76adb0 KZ |
14 | #include "c.h" |
15 | #include "ttyutils.h" | |
16 | ||
cba97be9 KZ |
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 | |
f46a8d7e KZ |
44 | |
45 | static int get_env_int(const char *name) | |
4e76adb0 | 46 | { |
f46a8d7e KZ |
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; | |
4e76adb0 | 67 | |
43b4f7ea BE |
68 | #if defined(TIOCGWINSZ) |
69 | struct winsize w_win; | |
f46a8d7e KZ |
70 | if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &w_win) == 0) { |
71 | c = w_win.ws_col; | |
72 | l = w_win.ws_row; | |
73 | } | |
43b4f7ea BE |
74 | #elif defined(TIOCGSIZE) |
75 | struct ttysize t_win; | |
f46a8d7e KZ |
76 | if (ioctl (STDOUT_FILENO, TIOCGSIZE, &t_win) == 0) { |
77 | c = t_win.ts_cols; | |
78 | l = t_win.ts_lines; | |
79 | } | |
4e76adb0 | 80 | #endif |
5119ef0a SK |
81 | if (cols) { |
82 | if (c <= 0) | |
83 | c = get_env_int("COLUMNS"); | |
f46a8d7e | 84 | *cols = c; |
5119ef0a SK |
85 | } |
86 | if (lines) { | |
87 | if (l <= 0) | |
88 | l = get_env_int("LINES"); | |
f46a8d7e | 89 | *lines = l; |
5119ef0a | 90 | } |
f46a8d7e KZ |
91 | return 0; |
92 | } | |
43b4f7ea | 93 | |
f46a8d7e KZ |
94 | int get_terminal_width(int default_width) |
95 | { | |
96 | int width = 0; | |
4e76adb0 | 97 | |
f46a8d7e | 98 | get_terminal_dimension(&width, NULL); |
43b4f7ea BE |
99 | |
100 | return width > 0 ? width : default_width; | |
4e76adb0 KZ |
101 | } |
102 | ||
a6d9d23b KZ |
103 | int get_terminal_stdfd(void) |
104 | { | |
105 | if (isatty(STDIN_FILENO)) | |
106 | return STDIN_FILENO; | |
042f62df | 107 | if (isatty(STDOUT_FILENO)) |
a6d9d23b | 108 | return STDOUT_FILENO; |
042f62df | 109 | if (isatty(STDERR_FILENO)) |
a6d9d23b KZ |
110 | return STDERR_FILENO; |
111 | ||
112 | return -EINVAL; | |
113 | } | |
114 | ||
285c1f3a | 115 | int get_terminal_name(const char **path, |
1ef28920 KZ |
116 | const char **name, |
117 | const char **number) | |
118 | { | |
119 | const char *tty; | |
120 | const char *p; | |
285c1f3a SK |
121 | int fd; |
122 | ||
1ef28920 KZ |
123 | |
124 | if (name) | |
125 | *name = NULL; | |
126 | if (path) | |
127 | *path = NULL; | |
128 | if (number) | |
129 | *number = NULL; | |
130 | ||
a6d9d23b KZ |
131 | fd = get_terminal_stdfd(); |
132 | if (fd < 0) | |
133 | return fd; /* error */ | |
285c1f3a | 134 | |
507341f8 | 135 | tty = ttyname(fd); |
1ef28920 KZ |
136 | if (!tty) |
137 | return -1; | |
a6d9d23b | 138 | |
1ef28920 KZ |
139 | if (path) |
140 | *path = tty; | |
a6d9d23b KZ |
141 | if (name || number) |
142 | tty = strncmp(tty, "/dev/", 5) == 0 ? tty + 5 : tty; | |
1ef28920 KZ |
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 | ||
4d9b788d KZ |
156 | int get_terminal_type(const char **type) |
157 | { | |
158 | *type = getenv("TERM"); | |
159 | if (*type) | |
160 | return -EINVAL; | |
161 | return 0; | |
162 | } | |
1ef28920 | 163 | |
cba97be9 KZ |
164 | char *get_terminal_default_type(const char *ttyname, int is_serial) |
165 | { | |
cba97be9 | 166 | if (ttyname) { |
84a8f5ed | 167 | #ifdef HAVE_GETTTYNAM |
cba97be9 KZ |
168 | struct ttyent *ent = getttynam(ttyname); |
169 | ||
170 | if (ent && ent->ty_type) | |
171 | return strdup(ent->ty_type); | |
cba97be9 KZ |
172 | #endif |
173 | ||
174 | #if defined (__s390__) || defined (__s390x__) | |
cba97be9 KZ |
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); | |
cba97be9 | 187 | #endif |
84a8f5ed | 188 | } |
cba97be9 KZ |
189 | |
190 | return strdup(is_serial ? DEFAULT_STERM : DEFAULT_VCTERM); | |
191 | } | |
192 | ||
e8f7acb0 | 193 | #ifdef TEST_PROGRAM_TTYUTILS |
5f247c8b | 194 | # include <stdlib.h> |
5f247c8b KZ |
195 | int main(void) |
196 | { | |
1ef28920 | 197 | const char *path, *name, *num; |
f46a8d7e | 198 | int c, l; |
1ef28920 | 199 | |
b8fd5c05 | 200 | if (get_terminal_name(&path, &name, &num) == 0) { |
cba97be9 KZ |
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); | |
1ef28920 | 212 | } |
f46a8d7e | 213 | get_terminal_dimension(&c, &l); |
cba97be9 KZ |
214 | fprintf(stderr, "tty cols: %d\n", c); |
215 | fprintf(stderr, "tty lines: %d\n", l); | |
f46a8d7e | 216 | |
1ef28920 | 217 | |
5f247c8b KZ |
218 | return EXIT_SUCCESS; |
219 | } | |
e8f7acb0 | 220 | #endif /* TEST_PROGRAM_TTYUTILS */ |