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(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 }