tty.c - ubase - suckless linux base utils
(HTM) git clone git://git.suckless.org/ubase
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
tty.c (1717B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <sys/sysmacros.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5
6 #include <fcntl.h>
7 #include <dirent.h>
8 #include <limits.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13
14 #include "../util.h"
15
16 void
17 devtotty(int dev, int *tty_maj, int *tty_min)
18 {
19 *tty_maj = (dev >> 8) & 0xfff;
20 *tty_min = (dev & 0xff) | ((dev >> 12) & 0xfff00);
21 }
22
23 int
24 ttytostr(int tty_maj, int tty_min, char *str, size_t n)
25 {
26 struct stat sb;
27 struct dirent *dp;
28 DIR *dirp;
29 char path[PATH_MAX];
30 int fd;
31 int r = 0;
32
33 switch (tty_maj) {
34 case 136:
35 snprintf(str, n, "pts/%d", tty_min);
36 return 0;
37 case 4:
38 snprintf(str, n, "tty%d", tty_min);
39 return 0;
40 default:
41 str[0] = '?';
42 str[1] = '\0';
43 break;
44 }
45
46 dirp = opendir("/dev");
47 if (!dirp) {
48 weprintf("opendir /dev:");
49 return -1;
50 }
51
52 while ((dp = readdir(dirp))) {
53 if (!strcmp(dp->d_name, ".") ||
54 !strcmp(dp->d_name, ".."))
55 continue;
56
57 if (strlcpy(path, "/dev/", sizeof(path)) >= sizeof(path)) {
58 weprintf("path too long\n");
59 r = -1;
60 goto err0;
61 }
62 if (strlcat(path, dp->d_name, sizeof(path)) >= sizeof(path)) {
63 weprintf("path too long\n");
64 r = -1;
65 goto err0;
66 }
67
68 if (stat(path, &sb) < 0) {
69 weprintf("stat %s:", path);
70 r = -1;
71 goto err0;
72 }
73
74 if ((int)major(sb.st_rdev) == tty_maj &&
75 (int)minor(sb.st_rdev) == tty_min) {
76 fd = open(path, O_RDONLY | O_NONBLOCK);
77 if (fd < 0)
78 continue;
79 if (isatty(fd)) {
80 strlcpy(str, dp->d_name, n);
81 close(fd);
82 break;
83 } else {
84 close(fd);
85 r = -1;
86 goto err0;
87 }
88 }
89 }
90
91 err0:
92 if (closedir(dirp) < 0) {
93 weprintf("closedir /dev:");
94 r = -1;
95 }
96
97 return r;
98 }