ubase

suckless linux base utils
git clone git://git.suckless.org/ubase
Log | Files | Refs | README | LICENSE

tty.c (1690B)


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