Skip to content

Commit

Permalink
Add Solaris implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
ricardobranco777 committed Feb 5, 2024
1 parent 136fe51 commit edba488
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 0 deletions.
9 changes: 9 additions & 0 deletions solaris/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CC = gcc
BIN = restartable
CFLAGS = -Wall -O2

$(BIN): *.c
$(CC) -o $@ $(CFLAGS) *.c $(LDFLAGS)

clean:
@rm -f $(BIN)
107 changes: 107 additions & 0 deletions solaris/restartable.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#include <sys/types.h>
#include <ctype.h>
#include <err.h>
#include <fcntl.h>
#include <dirent.h>
#include <limits.h>
#include <paths.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define _KERNEL
#include <sys/procfs.h>

static int verbose;

static void
parse_psinfo(const char *pid, int procFd) {
struct passwd *pwd;
char *user = "-";
psinfo_t psinfo;
int fd;

if ((fd = openat(procFd, "psinfo", O_RDONLY)) == -1) {
warn("%s", pid);
return;
}

if (read(fd, &psinfo, sizeof(psinfo_t)) == sizeof(psinfo_t)) {
if ((pwd = getpwuid(psinfo.pr_uid)) != NULL)
user = pwd->pw_name;
printf("%d\t%d\t%d\t%s\t%s\n", psinfo.pr_pid, psinfo.pr_ppid, psinfo.pr_uid, user, psinfo.pr_fname);
if (verbose)
printf("\t%s\n", psinfo.pr_psargs);
}

(void) close(fd);
}

static void
print_proc(const char *pid) {
char linkPath[PATH_MAX];
char link[PATH_MAX];
char procPid[256];
int procFd, mapFd;
prmap_t entry;

(void) snprintf(procPid, sizeof(procPid), "/proc/%s", pid);
if ((procFd = open(procPid, O_RDONLY | O_DIRECTORY)) == -1)
return;

if ((mapFd = openat(procFd, "map", O_RDONLY)) == -1) {
warn("%s", pid);
close(procFd);
return;
}

while (read(mapFd, &entry, sizeof(entry)) == sizeof(entry)) {
/* Skip anonymous mappings */
if (entry.pr_mflags & MA_ANON)
continue;
/* Skip non-executable mappings */
if (!(entry.pr_mflags & MA_EXEC))
continue;
/* Solaris doesn't have w^x, so skip writable to avoid duplicate entries */
if (entry.pr_mflags & MA_WRITE)
continue;

(void) snprintf(linkPath, sizeof(linkPath), "path/%s", entry.pr_mapname);
if (readlinkat(procFd, linkPath, link, sizeof(link)) == -1) {
parse_psinfo(pid, procFd);
break;
}
}

(void) close(mapFd);
(void) close(procFd);
}

static void
print_all(void) {
DIR *dir;
struct dirent *entry;

dir = opendir("/proc");
if (dir == NULL)
err(1, "/proc");

while ((entry = readdir(dir)) != NULL)
if (isdigit(entry->d_name[0]))
print_proc(entry->d_name);

(void) closedir(dir);
}

int
main(int argc, char *argv[]) {
if (argc > 2)
errx(1, "Usage: %s [-v]\n", argv[0]);
if (argc > 1 && !strcmp(argv[1], "-v"))
verbose = 1;

printf("PID\tPPID\tUID\tUser\tCommand\n");
print_all();

return 0;
}

0 comments on commit edba488

Please sign in to comment.