Introduction
Introduction Statistics Contact Development Disclaimer Help
ps.c - ubase - suckless linux base utils
git clone git://git.suckless.org/ubase
Log
Files
Refs
README
LICENSE
---
ps.c (3852B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <sys/ioctl.h>
3 #include <sys/sysinfo.h>
4
5 #include <errno.h>
6 #include <libgen.h>
7 #include <limits.h>
8 #include <pwd.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <time.h>
13 #include <unistd.h>
14
15 #include "proc.h"
16 #include "util.h"
17
18 static void psout(struct procstat *ps);
19 static void psr(const char *file);
20
21 enum {
22 PS_aflag = 1 << 0,
23 PS_Aflag = 1 << 1,
24 PS_dflag = 1 << 2,
25 PS_fflag = 1 << 3
26 };
27
28 static int flags;
29
30 static void
31 psout(struct procstat *ps)
32 {
33 struct procstatus pstatus;
34 char cmdline[BUFSIZ], *cmd;
35 char buf[BUFSIZ];
36 char ttystr[TTY_NAME_MAX], *myttystr;
37 int tty_maj, tty_min;
38 uid_t myeuid;
39 unsigned sutime;
40 time_t start;
41 char stimestr[sizeof("%H:%M")];
42 struct sysinfo info;
43 struct passwd *pw;
44 struct winsize w;
45
46 /* Ignore session leaders */
47 if (flags & PS_dflag)
48 if (ps->pid == ps->sid)
49 return;
50
51 devtotty(ps->tty_nr, &tty_maj, &tty_min);
52 ttytostr(tty_maj, tty_min, ttystr, sizeof(ttystr));
53
54 /* Only print processes that are associated with
55 * a terminal and they are not session leaders */
56 if (flags & PS_aflag)
57 if (ps->pid == ps->sid || ttystr[0] == '?')
58 return;
59
60 if (parsestatus(ps->pid, &pstatus) < 0)
61 return;
62
63 /* This is the default case, only print processes that have
64 * the same controlling terminal as the invoker and the same
65 * euid as the current user */
66 if (!(flags & (PS_aflag | PS_Aflag | PS_dflag))) {
67 myttystr = ttyname(0);
68 if (myttystr) {
69 if (strcmp(myttystr + strlen("/dev/"), ttystr))
70 return;
71 } else {
72 /* The invoker has no controlling terminal - just
73 * go ahead and print the processes anyway */
74 ttystr[0] = '?';
75 ttystr[1] = '\0';
76 }
77 myeuid = geteuid();
78 if (myeuid != pstatus.euid)
79 return;
80 }
81
82 sutime = (ps->stime + ps->utime) / sysconf(_SC_CLK_TCK);
83
84 ioctl(1, TIOCGWINSZ, &w);
85 if (!(flags & PS_fflag)) {
86 snprintf(buf, sizeof(buf), "%5d %-6s %02u:%02u:%02u %s…
87 sutime / 3600, (sutime % 3600) / 60, sutime % 6…
88 ps->comm);
89 if (w.ws_col)
90 printf("%.*s\n", w.ws_col, buf);
91 else
92 printf("%s\n", buf);
93 } else {
94 errno = 0;
95 pw = getpwuid(pstatus.uid);
96 if (!pw)
97 eprintf("getpwuid %d:", pstatus.uid);
98
99 if (sysinfo(&info) < 0)
100 eprintf("sysinfo:");
101
102 start = time(NULL) - info.uptime;
103 start += (ps->starttime / sysconf(_SC_CLK_TCK));
104 strftime(stimestr, sizeof(stimestr),
105 "%H:%M", localtime(&start));
106
107 /* For kthreads/zombies /proc/<pid>/cmdline will be
108 * empty so use ps->comm in that case */
109 if (parsecmdline(ps->pid, cmdline, sizeof(cmdline)) < 0)
110 cmd = ps->comm;
111 else
112 cmd = cmdline;
113
114 snprintf(buf, sizeof(buf), "%-8s %5d %5d ? %5s %-5s …
115 pw->pw_name, ps->pid,
116 ps->ppid, stimestr, ttystr,
117 sutime / 3600, (sutime % 3600) / 60, sutime % 6…
118 (cmd == ps->comm) ? "[" : "", cmd,
119 (cmd == ps->comm) ? "]" : "");
120 if (w.ws_col)
121 printf("%.*s\n", w.ws_col, buf);
122 else
123 printf("%s\n", buf);
124 }
125 }
126
127 static void
128 psr(const char *file)
129 {
130 char path[PATH_MAX], *p;
131 struct procstat ps;
132 pid_t pid;
133
134 if (strlcpy(path, file, sizeof(path)) >= sizeof(path))
135 eprintf("path too long\n");
136 p = basename(path);
137 if (pidfile(p) == 0)
138 return;
139 pid = estrtol(p, 10);
140 if (parsestat(pid, &ps) < 0)
141 return;
142 psout(&ps);
143 }
144
145 static void
146 usage(void)
147 {
148 eprintf("usage: %s [-aAdef]\n", argv0);
149 }
150
151 int
152 main(int argc, char *argv[])
153 {
154 ARGBEGIN {
155 case 'a':
156 flags |= PS_aflag;
157 break;
158 case 'A':
159 flags |= PS_Aflag;
160 break;
161 case 'd':
162 flags |= PS_dflag;
163 break;
164 case 'e':
165 flags |= PS_Aflag;
166 break;
167 case 'f':
168 flags |= PS_fflag;
169 break;
170 default:
171 usage();
172 } ARGEND;
173
174 if (!(flags & PS_fflag))
175 printf(" PID TTY TIME CMD\n");
176 else
177 printf("UID PID PPID C STIME TTY TIME …
178 recurse("/proc", psr);
179 return 0;
180 }
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.