mirror of
git://git.suckless.org/ubase
synced 2024-12-22 14:42:41 +00:00
Support -f for ps(1)
Fix missing break in tty.c as well.
This commit is contained in:
parent
74146c54a7
commit
e84531958e
2
proc.h
2
proc.h
@ -27,6 +27,8 @@ struct procstat {
|
||||
long rsslim;
|
||||
};
|
||||
|
||||
int parsecmdline(pid_t pid, char *buf, size_t siz);
|
||||
int parsestat(pid_t pid, struct procstat *ps);
|
||||
int proceuid(pid_t pid, uid_t *euid);
|
||||
int procuid(pid_t pid, uid_t *euid);
|
||||
int validps(const char *path);
|
||||
|
54
ps.c
54
ps.c
@ -1,10 +1,13 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
#include <sys/sysinfo.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
#include <pwd.h>
|
||||
#include "proc.h"
|
||||
#include "util.h"
|
||||
|
||||
@ -15,7 +18,8 @@ static void psr(const char *path);
|
||||
enum {
|
||||
PS_aflag = 1 << 0,
|
||||
PS_Aflag = 1 << 1,
|
||||
PS_dflag = 1 << 2
|
||||
PS_dflag = 1 << 2,
|
||||
PS_fflag = 1 << 3
|
||||
};
|
||||
|
||||
static int flags;
|
||||
@ -37,14 +41,17 @@ main(int argc, char *argv[])
|
||||
flags |= PS_Aflag;
|
||||
break;
|
||||
case 'f':
|
||||
eprintf("not implemented\n");
|
||||
flags |= PS_fflag;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
} ARGEND;
|
||||
|
||||
if (!(flags & PS_fflag))
|
||||
printf(" PID TTY TIME CMD\n");
|
||||
else
|
||||
printf("UID PID PPID C STIME TTY TIME CMD\n");
|
||||
recurse("/proc", psr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -57,10 +64,16 @@ usage(void)
|
||||
static void
|
||||
psout(struct procstat *ps)
|
||||
{
|
||||
char cmdline[BUFSIZ], *cmd;
|
||||
char stimestr[6];
|
||||
char *ttystr, *myttystr;
|
||||
int tty_maj, tty_min;
|
||||
uid_t myeuid, peuid;
|
||||
uid_t myeuid, peuid, puid;
|
||||
unsigned sut;
|
||||
struct sysinfo info;
|
||||
struct tm *tm;
|
||||
time_t start;
|
||||
struct passwd *pw;
|
||||
|
||||
/* Ignore session leaders */
|
||||
if (flags & PS_dflag)
|
||||
@ -72,13 +85,15 @@ psout(struct procstat *ps)
|
||||
devtotty(ps->tty_nr, &tty_maj, &tty_min);
|
||||
ttystr = ttytostr(tty_maj, tty_min);
|
||||
/* Only print processes that are associated with
|
||||
* a terminal */
|
||||
if (ttystr[0] == '?' && (flags & PS_aflag)) {
|
||||
* a terminal and they are not session leaders */
|
||||
if (flags & PS_aflag) {
|
||||
if (ps->pid == ps->sid || ttystr[0] == '?') {
|
||||
free(ttystr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flags) {
|
||||
if (!(flags & (PS_aflag | PS_Aflag | PS_dflag))) {
|
||||
myttystr = ttyname(STDIN_FILENO);
|
||||
if (myttystr) {
|
||||
if (strcmp(myttystr + strlen("/dev/"), ttystr)) {
|
||||
@ -97,8 +112,33 @@ psout(struct procstat *ps)
|
||||
}
|
||||
}
|
||||
|
||||
procuid(ps->pid, &puid);
|
||||
errno = 0;
|
||||
pw = getpwuid(puid);
|
||||
if (errno || !pw)
|
||||
eprintf("getpwuid %d:", puid);
|
||||
|
||||
sysinfo(&info);
|
||||
start = time(NULL) - (info.uptime - (ps->starttime / 100));
|
||||
tm = localtime(&start);
|
||||
strftime(stimestr, sizeof(stimestr),
|
||||
"%H:%M", tm);
|
||||
if (parsecmdline(ps->pid, cmdline, sizeof(cmdline)) < 0)
|
||||
cmd = ps->comm;
|
||||
else
|
||||
cmd = cmdline;
|
||||
|
||||
if (!(flags & PS_fflag))
|
||||
printf("%5d %-6s %02u:%02u:%02u %s\n", ps->pid, ttystr,
|
||||
sut / 3600, (sut % 3600) / 60, sut % 60, ps->comm);
|
||||
else {
|
||||
printf("%-8s %5d %5d ? %5s %-5s %02u:%02u:%02u %s%s%s\n",
|
||||
pw->pw_name, ps->pid,
|
||||
ps->ppid, stimestr, ttystr,
|
||||
sut / 3600, (sut % 3600) / 60, sut % 60,
|
||||
(cmd == ps->comm) ? "[" : "", cmd,
|
||||
(cmd == ps->comm) ? "]" : "");
|
||||
}
|
||||
free(ttystr);
|
||||
}
|
||||
|
||||
|
52
util/proc.c
52
util/proc.c
@ -1,4 +1,6 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
@ -32,6 +34,56 @@ proceuid(pid_t pid, uid_t *euid)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
procuid(pid_t pid, uid_t *uid)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[BUFSIZ], *p;
|
||||
char path[PATH_MAX];
|
||||
uid_t procuid;
|
||||
|
||||
snprintf(path, sizeof(path), "/proc/%d/status", pid);
|
||||
if (!(fp = fopen(path, "r")))
|
||||
eprintf("%s fopen:", path);
|
||||
while (fgets(buf, sizeof(buf), fp)) {
|
||||
if (!strncmp(buf, "Uid:", 4)) {
|
||||
p = buf + strlen("Uid:");
|
||||
sscanf(p, "%u", &procuid);
|
||||
*uid = procuid;
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
parsecmdline(pid_t pid, char *buf, size_t siz)
|
||||
{
|
||||
int fd;
|
||||
char path[PATH_MAX];
|
||||
ssize_t n, i;
|
||||
|
||||
snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
eprintf("open %s:", path);
|
||||
n = read(fd, buf, siz - 1);
|
||||
if (n < 0)
|
||||
eprintf("read %s:", path);
|
||||
if (!n) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
buf[n] = '\0';
|
||||
for (i = 0; i < n; i++)
|
||||
if (buf[i] == '\0')
|
||||
buf[i] = ' ';
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
parsestat(pid_t pid, struct procstat *ps)
|
||||
{
|
||||
|
@ -30,6 +30,7 @@ ttytostr(int tty_maj, int tty_min)
|
||||
break;
|
||||
case 4:
|
||||
snprintf(ttystr, len, "%s%d", tty, tty_min);
|
||||
break;
|
||||
default:
|
||||
ttystr[0] = '?';
|
||||
ttystr[1] = '\0';
|
||||
|
Loading…
Reference in New Issue
Block a user