Introduction
Introduction Statistics Contact Development Disclaimer Help
Properly match (ttymaj, ttymin) pairs to tty names in /dev - ubase - suckless l…
git clone git://git.suckless.org/ubase
Log
Files
Refs
README
LICENSE
---
commit d76319f838dfb42c13c099012e72ca11d37d7178
parent 2a0deb76009631af15b1dd7b435392bf2511b319
Author: sin <[email protected]>
Date: Fri, 16 Jan 2015 15:32:55 +0000
Properly match (ttymaj, ttymin) pairs to tty names in /dev
For the common case where we have pts/ or tty do it straight
away. Otherwise traverse /dev for a match. This fixes ps(1) when
it is executed over a serial terminal with tty names like ttyAMA0.
Diffstat:
M libutil/tty.c | 75 ++++++++++++++++++++++++-----…
M ps.c | 20 ++++++--------------
M util.h | 2 +-
3 files changed, 65 insertions(+), 32 deletions(-)
---
diff --git a/libutil/tty.c b/libutil/tty.c
@@ -1,7 +1,13 @@
/* See LICENSE file for copyright and license details. */
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <dirent.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include "../util.h"
@@ -12,28 +18,63 @@ devtotty(int dev, int *tty_maj, int *tty_min)
*tty_min = (dev & 0xff) | ((dev >> 12) & 0xfff00);
}
-char *
-ttytostr(int tty_maj, int tty_min)
+int
+ttytostr(int tty_maj, int tty_min, char *str, size_t n)
{
- const char *pts = "pts/";
- const char *tty = "tty";
- char *ttystr;
- size_t len;
-
- /* Up to 10k ttys */
- len = strlen(pts) + 4 + 1;
- ttystr = emalloc(len);
+ struct stat sb;
+ struct dirent *dp;
+ DIR *dirp;
+ char path[PATH_MAX];
+
switch (tty_maj) {
case 136:
- snprintf(ttystr, len, "%s%d", pts, tty_min);
- break;
+ snprintf(str, n, "pts/%d", tty_min);
+ return 0;
case 4:
- snprintf(ttystr, len, "%s%d", tty, tty_min);
- break;
+ snprintf(str, n, "tty%d", tty_min);
+ return 0;
default:
- ttystr[0] = '?';
- ttystr[1] = '\0';
+ str[0] = '?';
+ str[1] = '\0';
break;
}
- return ttystr;
+
+ 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");
+ return -1;
+ }
+ if (strlcat(path, dp->d_name, sizeof(path)) >= sizeof(path)) {
+ weprintf("path too long\n");
+ return -1;
+ }
+
+ if (stat(path, &sb) < 0) {
+ weprintf("stat %s:", dp->d_name);
+ return -1;
+ }
+
+ if ((int)major(sb.st_rdev) == tty_maj &&
+ (int)minor(sb.st_rdev) == tty_min) {
+ strlcpy(str, dp->d_name, n);
+ break;
+ }
+ }
+
+ if (closedir(dirp) < 0) {
+ weprintf("closedir /dev:");
+ return -1;
+ }
+
+ return 0;
}
diff --git a/ps.c b/ps.c
@@ -70,7 +70,7 @@ psout(struct procstat *ps)
struct procstatus pstatus;
char cmdline[BUFSIZ], *cmd;
char buf[BUFSIZ];
- char *ttystr, *myttystr;
+ char ttystr[PATH_MAX], *myttystr;
int tty_maj, tty_min;
uid_t myeuid;
unsigned sutime;
@@ -86,16 +86,13 @@ psout(struct procstat *ps)
return;
devtotty(ps->tty_nr, &tty_maj, &tty_min);
- ttystr = ttytostr(tty_maj, tty_min);
+ ttytostr(tty_maj, tty_min, ttystr, sizeof(ttystr));
/* Only print processes that are associated with
* a terminal and they are not session leaders */
- if (flags & PS_aflag) {
- if (ps->pid == ps->sid || ttystr[0] == '?') {
- free(ttystr);
+ if (flags & PS_aflag)
+ if (ps->pid == ps->sid || ttystr[0] == '?')
return;
- }
- }
if (parsestatus(ps->pid, &pstatus) < 0)
return;
@@ -106,10 +103,8 @@ psout(struct procstat *ps)
if (!(flags & (PS_aflag | PS_Aflag | PS_dflag))) {
myttystr = ttyname(0);
if (myttystr) {
- if (strcmp(myttystr + strlen("/dev/"), ttystr)) {
- free(ttystr);
+ if (strcmp(myttystr + strlen("/dev/"), ttystr))
return;
- }
} else {
/* The invoker has no controlling terminal - just
* go ahead and print the processes anyway */
@@ -117,10 +112,8 @@ psout(struct procstat *ps)
ttystr[1] = '\0';
}
myeuid = geteuid();
- if (myeuid != pstatus.euid) {
- free(ttystr);
+ if (myeuid != pstatus.euid)
return;
- }
}
sutime = (ps->stime + ps->utime) / sysconf(_SC_CLK_TCK);
@@ -166,7 +159,6 @@ psout(struct procstat *ps)
else
printf("%s\n", buf);
}
- free(ttystr);
}
static void
diff --git a/util.h b/util.h
@@ -50,4 +50,4 @@ size_t strlcpy(char *, const char *, size_t);
/* tty.c */
void devtotty(int, int *, int *);
-char *ttytostr(int, int);
+int ttytostr(int, int, char *, size_t);
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.