/* See LICENSE file for copyright and license details. */ #include #include #include #include #include #include #include #include #include #include "../util.h" void devtotty(int dev, int *tty_maj, int *tty_min) { *tty_maj = (dev >> 8) & 0xfff; *tty_min = (dev & 0xff) | ((dev >> 12) & 0xfff00); } int ttytostr(int tty_maj, int tty_min, char *str, size_t n) { struct stat sb; struct dirent *dp; DIR *dirp; char path[PATH_MAX]; int fd; int r = 0; switch (tty_maj) { case 136: snprintf(str, n, "pts/%d", tty_min); return 0; case 4: snprintf(str, n, "tty%d", tty_min); return 0; default: str[0] = '?'; str[1] = '\0'; break; } dirp = opendir("/dev"); if (!dirp) { weprintf("opendir /dev:"); return -1; } while ((dp = readdir(dirp))) { if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue; if (strlcpy(path, "/dev/", sizeof(path)) >= sizeof(path)) { weprintf("path too long\n"); r = -1; goto err0; } if (strlcat(path, dp->d_name, sizeof(path)) >= sizeof(path)) { weprintf("path too long\n"); r = -1; goto err0; } if (stat(path, &sb) < 0) { weprintf("stat %s:", path); r = -1; goto err0; } if ((int)major(sb.st_rdev) == tty_maj && (int)minor(sb.st_rdev) == tty_min) { fd = open(path, O_RDONLY | O_NONBLOCK); if (fd < 0) continue; if (isatty(fd)) { strlcpy(str, dp->d_name, n); close(fd); break; } else { close(fd); r = -1; goto err0; } } } err0: if (closedir(dirp) < 0) { weprintf("closedir /dev:"); r = -1; } return r; }