2024-07-01 10:23:00 +00:00
|
|
|
#include <fcntl.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <errno.h>
|
2024-07-05 16:54:49 +00:00
|
|
|
#include <ctype.h>
|
|
|
|
#include <pwd.h>
|
2024-07-01 10:23:00 +00:00
|
|
|
|
2024-07-09 12:43:55 +00:00
|
|
|
static int pscan(const char *pid) {
|
2024-07-05 16:54:49 +00:00
|
|
|
char path[PATH_MAX + 1];
|
|
|
|
|
|
|
|
/* Arguments */
|
|
|
|
snprintf(path, sizeof(path), "/proc/%s/status", pid);
|
2024-07-01 10:23:00 +00:00
|
|
|
int fd = open(path, O_RDONLY);
|
|
|
|
if (fd < 0) {
|
|
|
|
fprintf(stderr, "ps: %s: %s\n", path, strerror(errno));
|
2024-07-05 16:54:49 +00:00
|
|
|
return 1;
|
2024-07-01 10:23:00 +00:00
|
|
|
}
|
|
|
|
|
2024-07-05 16:54:49 +00:00
|
|
|
char status[2048];
|
|
|
|
ssize_t n = read(fd, status, sizeof(status) - 1);
|
|
|
|
status[n] = '\0';
|
2024-07-01 10:23:00 +00:00
|
|
|
|
2024-07-05 16:54:49 +00:00
|
|
|
close(fd);
|
2024-07-01 10:23:00 +00:00
|
|
|
|
2024-07-05 16:54:49 +00:00
|
|
|
char *prog = "none";
|
|
|
|
char *state = "none";
|
|
|
|
char *user = "none";
|
2024-07-01 10:23:00 +00:00
|
|
|
|
2024-07-05 16:54:49 +00:00
|
|
|
/* Parsing */
|
|
|
|
char *token = strtok(status, "\n");
|
|
|
|
while (token) {
|
|
|
|
char *val = strchr(token, ':');
|
|
|
|
if (val == NULL) {
|
|
|
|
fprintf(stderr, "ps: incorrect %s file\n", path);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
*val = '\0';
|
|
|
|
val++;
|
|
|
|
|
|
|
|
/* Strip */
|
|
|
|
while (isspace(*val))
|
|
|
|
val++;
|
2024-07-01 10:23:00 +00:00
|
|
|
|
2024-07-05 16:54:49 +00:00
|
|
|
/* Write values */
|
|
|
|
if (!strncmp(token, "State", 5))
|
|
|
|
state = val;
|
|
|
|
|
|
|
|
else if (!strncmp(token, "Name", 4))
|
|
|
|
prog = val;
|
|
|
|
|
|
|
|
else if (!strncmp(token, "Uid", 3)) {
|
|
|
|
struct passwd *pw = getpwuid(atoi(val));
|
|
|
|
if (pw != NULL)
|
|
|
|
user = pw->pw_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
token = strtok(NULL, "\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("%s\t%s\t%s\t%s\n", pid, state, user, prog);
|
2024-07-01 10:23:00 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
|
|
|
|
int opt;
|
2024-07-05 16:54:49 +00:00
|
|
|
while ((opt = getopt(argc, argv, "")) != -1) {
|
|
|
|
puts("ps [PID]");
|
|
|
|
return 0;
|
2024-07-01 10:23:00 +00:00
|
|
|
}
|
|
|
|
|
2024-07-05 16:54:49 +00:00
|
|
|
argv += optind;
|
|
|
|
argc -= optind;
|
2024-07-01 10:23:00 +00:00
|
|
|
|
2024-07-05 16:54:49 +00:00
|
|
|
printf("PID\tSTATE\tUSER\tCMD\n");
|
2024-07-01 10:23:00 +00:00
|
|
|
|
|
|
|
int ret = 0;
|
2024-07-05 16:54:49 +00:00
|
|
|
if (argc == 0) {
|
|
|
|
DIR *dp = opendir("/proc");
|
|
|
|
if (dp == NULL) {
|
|
|
|
fprintf(stderr, "ps: /proc: %s\n", strerror(errno));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct dirent *ep;
|
|
|
|
while ((ep = readdir(dp)) != NULL)
|
|
|
|
if (atoi(ep->d_name))
|
|
|
|
if (pscan(ep->d_name))
|
|
|
|
ret = 1;
|
|
|
|
|
|
|
|
closedir(dp);
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
for (int i = 0; i < argc; i++)
|
|
|
|
if (atoi(argv[i]))
|
|
|
|
if (pscan(argv[i]))
|
|
|
|
ret = 1;
|
|
|
|
}
|
2024-07-01 10:23:00 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|