]>
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 KZ |
9 | |
10 | #include "c.h" | |
11 | #include "ttyutils.h" | |
12 | ||
f46a8d7e KZ |
13 | |
14 | static int get_env_int(const char *name) | |
4e76adb0 | 15 | { |
f46a8d7e KZ |
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; | |
4e76adb0 | 36 | |
43b4f7ea BE |
37 | #if defined(TIOCGWINSZ) |
38 | struct winsize w_win; | |
f46a8d7e KZ |
39 | if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &w_win) == 0) { |
40 | c = w_win.ws_col; | |
41 | l = w_win.ws_row; | |
42 | } | |
43b4f7ea BE |
43 | #elif defined(TIOCGSIZE) |
44 | struct ttysize t_win; | |
f46a8d7e KZ |
45 | if (ioctl (STDOUT_FILENO, TIOCGSIZE, &t_win) == 0) { |
46 | c = t_win.ts_cols; | |
47 | l = t_win.ts_lines; | |
48 | } | |
4e76adb0 | 49 | #endif |
4e76adb0 | 50 | |
f46a8d7e KZ |
51 | if (cols && c <= 0) |
52 | c = get_env_int("COLUMNS"); | |
53 | if (lines && l <= 0) | |
54 | l = get_env_int("LINES"); | |
43b4f7ea | 55 | |
f46a8d7e KZ |
56 | if (cols) |
57 | *cols = c; | |
58 | if (lines) | |
59 | *lines = l; | |
60 | return 0; | |
61 | } | |
43b4f7ea | 62 | |
f46a8d7e KZ |
63 | int get_terminal_width(int default_width) |
64 | { | |
65 | int width = 0; | |
4e76adb0 | 66 | |
f46a8d7e | 67 | get_terminal_dimension(&width, NULL); |
43b4f7ea BE |
68 | |
69 | return width > 0 ? width : default_width; | |
4e76adb0 KZ |
70 | } |
71 | ||
285c1f3a | 72 | int get_terminal_name(const char **path, |
1ef28920 KZ |
73 | const char **name, |
74 | const char **number) | |
75 | { | |
76 | const char *tty; | |
77 | const char *p; | |
285c1f3a SK |
78 | int fd; |
79 | ||
1ef28920 KZ |
80 | |
81 | if (name) | |
82 | *name = NULL; | |
83 | if (path) | |
84 | *path = NULL; | |
85 | if (number) | |
86 | *number = NULL; | |
87 | ||
285c1f3a SK |
88 | if (isatty(STDIN_FILENO)) |
89 | fd = STDIN_FILENO; | |
90 | else if (isatty(STDOUT_FILENO)) | |
91 | fd = STDOUT_FILENO; | |
92 | else if (isatty(STDERR_FILENO)) | |
93 | fd = STDERR_FILENO; | |
94 | else | |
95 | return -1; | |
96 | ||
507341f8 | 97 | tty = ttyname(fd); |
1ef28920 KZ |
98 | if (!tty) |
99 | return -1; | |
100 | if (path) | |
101 | *path = tty; | |
102 | tty = strncmp(tty, "/dev/", 5) == 0 ? tty + 5 : tty; | |
103 | if (name) | |
104 | *name = tty; | |
105 | if (number) { | |
106 | for (p = tty; p && *p; p++) { | |
107 | if (isdigit(*p)) { | |
108 | *number = p; | |
109 | break; | |
110 | } | |
111 | } | |
112 | } | |
113 | return 0; | |
114 | } | |
115 | ||
116 | ||
e8f7acb0 | 117 | #ifdef TEST_PROGRAM_TTYUTILS |
5f247c8b | 118 | # include <stdlib.h> |
5f247c8b KZ |
119 | int main(void) |
120 | { | |
1ef28920 | 121 | const char *path, *name, *num; |
f46a8d7e | 122 | int c, l; |
1ef28920 | 123 | |
b8fd5c05 | 124 | if (get_terminal_name(&path, &name, &num) == 0) { |
1ef28920 KZ |
125 | fprintf(stderr, "tty path: %s\n", path); |
126 | fprintf(stderr, "tty name: %s\n", name); | |
127 | fprintf(stderr, "tty number: %s\n", num); | |
128 | } | |
f46a8d7e KZ |
129 | get_terminal_dimension(&c, &l); |
130 | fprintf(stderr, "tty cols: %d\n", c); | |
131 | fprintf(stderr, "tty lines: %d\n", l); | |
132 | ||
1ef28920 | 133 | |
5f247c8b KZ |
134 | return EXIT_SUCCESS; |
135 | } | |
e8f7acb0 | 136 | #endif /* TEST_PROGRAM_TTYUTILS */ |