| tty.c - ubase - suckless linux base utils | |
| git clone git://git.suckless.org/ubase | |
| Log | |
| Files | |
| Refs | |
| README | |
| 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(pa… | |
| 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 } |