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 }