diff --git a/src/killall5.c b/src/killall5.c
index 5937d98..f6b14b1 100644
--- a/src/killall5.c
+++ b/src/killall5.c
@@ -40,10 +40,27 @@
  *		along with this program; if not, write to the Free Software
  *		Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
+#ifdef __sun__
+    #define __EXTENSIONS__
+    /* PATH_MAX */
+    #include <limits.h>
+
+    #include <sys/ucontext.h>
+    #include <procfs.h>
+    #include <fcntl.h>
+    #include <sys/types32.h>
+    #include <assert.h>
+
+    #define va_list __va_list
+    #include <procfs.h>
+#endif
+
 #include <dirent.h>
 #include <errno.h>
 #include <getopt.h>
-#include <mntent.h>
+#ifndef __sun__
+    #include <mntent.h>
+#endif
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -181,6 +198,12 @@ static inline void xmemalign(void **memptr, size_t alignment, size_t size)
  */
 int mount_proc(void)
 {
+    #ifdef __sun__
+        const char* checkProc = "/proc/0";
+    #else
+        const char* checkProc = "/proc/version";
+    #endif
+
 	struct stat	st;
 	char		*args[] = { "mount", "-t", "proc", "proc", "/proc", 0 };
 	pid_t		pid, rc;
@@ -188,7 +211,7 @@ int mount_proc(void)
 	int		did_mount = 0;
 
 	/* Stat /proc/version to see if /proc is mounted. */
-	if (stat("/proc/version", &st) < 0 && errno == ENOENT) {
+	if (stat(checkProc, &st) < 0 && errno == ENOENT) {
 
 		/* It's not there, so mount it. */
 		if ((pid = fork()) < 0) {
@@ -215,7 +238,7 @@ int mount_proc(void)
 	}
 
 	/* See if mount succeeded. */
-	if (stat("/proc/version", &st) < 0) {
+	if (stat(checkProc, &st) < 0) {
 		if (errno == ENOENT)
 			nsyslog(LOG_ERR, "/proc not mounted, failed to mount.");
 		else
@@ -237,6 +260,9 @@ static inline int isnetfs(const char * type)
 	return 0;
 }
 
+#ifdef __sun__
+    void init_nfs(void) { }
+#else
 /*
  *     Remember all NFS typed partitions.
  */
@@ -302,6 +328,7 @@ void init_nfs(void)
 	}
 	endmntent(mnt);
 }
+#endif /* not __sun__ */
 
 static void clear_shadow(SHADOW *restrict shadow)
 {
@@ -443,6 +470,229 @@ int readarg(FILE *fp, char *buf, int sz)
 	return (c == EOF && f == 0) ? c : f;
 }
 
+
+
+#ifdef __sun__
+
+static int openProcFile(const char* format, int pid)
+{
+    char procfile[100];
+    snprintf(procfile, 100, format, pid);
+    int fd;
+    if ((fd = open(procfile, O_RDONLY)) < 0) {
+        fprintf(stderr, "Error opening %s", procfile);
+        perror(" ");
+        exit(1);
+    }
+    return fd;
+}
+
+static int readStringFromAs(int asFd, uint64_t offset, char** strOut, int strOutSize)
+{
+    char* initStr = *strOut;
+    if (pread(asFd, initStr, strOutSize, offset) < 0) {
+        return 0;
+    }
+    initStr[strOutSize] = '\0';
+    int length = strlen(initStr);
+    if (length == strOutSize) {
+        // need a bigger buffer.
+        strOutSize *= 2;
+        *strOut = realloc(initStr, strOutSize);
+        assert(*strOut);
+        return readStringFromAs(asFd, offset, strOut, strOutSize);
+    }
+    return length;
+}
+
+static char* getArguments(psinfo_t* psinfo)
+{
+    int asFd = openProcFile("/proc/%d/as", psinfo->pr_pid);
+
+    uintptr_t addrArgs = psinfo->pr_argv;
+    int argCount = psinfo->pr_argc;
+
+    // argPointers point to the arguments in the process's memory space.
+    // args point to the copies of them in our memory space.
+    uintptr_t* argPointers = malloc(argCount * sizeof(uintptr_t));
+    char** args = malloc(argCount * sizeof(uintptr_t));
+    assert(argPointers && args);
+    if (psinfo->pr_dmodel == PR_MODEL_NATIVE) {
+        pread(asFd, argPointers, argCount * sizeof(uintptr_t), addrArgs);
+    } else {
+        // we are 64-bit, target is 32-bit
+        caddr32_t* argPointers32 = (caddr32_t*) argPointers;
+        pread(asFd, argPointers32, argCount * sizeof(caddr32_t), addrArgs);
+        // convert from 32-bit to 64-bit in place
+        for (int i = argCount - 1; i >= 0; --i) {
+            argPointers[i] = argPointers32[i];
+        }
+    }
+
+    int totalLength = 0;
+    for (int i = 0; i < argCount; i++) {
+        char* arg = malloc(16);
+        assert(arg);
+        totalLength += readStringFromAs(asFd, argPointers[i], &arg, 16);
+        args[i] = arg;
+    }
+
+    close(asFd);
+
+    // Merge everything into one buffer representing a list of null terminated strings.
+    char* out = malloc(totalLength + argCount + 4);
+    assert(out);
+    memcpy(out, &argCount, 4);
+    int index = 4;
+    for (int i = 0; i < argCount; i++) {
+        int length = strlen(args[i]);
+        memcpy(out + index, args[i], length+1);
+        index += length+1;
+        free(args[i]);
+    }
+    free(argPointers);
+
+    return out;
+}
+
+static char* baseName(char* name)
+{
+    if (!name) { return NULL; }
+    char* base = strrchr(name, '/');
+    return (base) ? base+1 : name;
+}
+
+static void getNfsInodeNumberAndDevice(int do_stat, psinfo_t* psinfo, struct proc* procOut)
+{
+    char path[PATH_MAX+1];
+
+    snprintf(path, sizeof(path), "/proc/%d/path/a.out", psinfo->pr_pid);
+
+	procOut->nfs = 0;
+    if (do_stat == DO_NETFS) {
+        char buff[PATH_MAX+1];
+        procOut->nfs = check4nfs(path, buff);
+    } else if (do_stat != DO_STAT) {
+        return;
+    }
+
+    struct stat st = { .st_dev = 0 };
+
+    if (stat(path, &st)) { fprintf(stderr, "Failed to stat [%s]\n", path); }
+
+    procOut->dev = st.st_dev;
+    procOut->ino = st.st_ino;
+}
+
+static void getProcInfo(int pid, int do_stat, struct proc* procOut)
+{
+    psinfo_t psinfo;
+    {
+        int psinfoFd = openProcFile("%d/psinfo", pid);
+        read(psinfoFd, &psinfo, sizeof(psinfo_t));
+        close(psinfoFd);
+    }
+
+    // argv0, argv1
+    procOut->argv0 = procOut->argv1 = NULL;
+    {
+        char* args = getArguments(&psinfo);
+        int argCount;
+        memcpy(&argCount, args, 4);
+        char* argv = args+4;
+        for (int i = 0; i < argCount; i++) {
+            if (i == 0) {
+                procOut->argv0 = strdup(argv);
+                assert(procOut->argv0);
+            } else if (argv[0] != '-') {
+                procOut->argv1 = strdup(argv);
+                assert(procOut->argv1);
+                break;
+            }
+            argv += strlen(argv) + 1;
+        }
+        free(args);
+    }
+
+    // argv0base, argv1base
+    procOut->argv0base = baseName(procOut->argv0);
+    procOut->argv1base = baseName(procOut->argv1);
+
+    // statname is compared to argv1base used to decide if it's executing a script.
+    procOut->statname = strdup(psinfo.pr_fname);
+
+    // Is it a kernel thread or zombie.
+    // Linux detects this by checking the upper and lower bounds of the address space.
+    // From some basic testing I see that Illumos sets the size of obvious kernel threads
+    // such as sched to 0 so we'll assume that kernel threads are defined by image size
+    // being zero.
+    procOut->kernel = (psinfo.pr_size == 0);
+
+    if (!procOut->kernel) {
+        // nfs, ino, dev
+        getNfsInodeNumberAndDevice(do_stat, &psinfo, procOut);
+    }
+
+    procOut->pid = psinfo.pr_pid;
+    procOut->sid = psinfo.pr_sid;
+}
+
+void freeProcList()
+{
+    PROC* p;
+	PROC* n = plist;
+	for (p = plist; n; p = n) {
+		n = p->next;
+		if (p->argv0) { free(p->argv0); }
+		if (p->argv1) { free(p->argv1); }
+		if (p->statname) { free(p->statname); }
+		free(p);
+	}
+	plist = NULL;
+}
+
+int readproc(int do_stat)
+{
+	/* Open the /proc directory. */
+	if (chdir("/proc") == -1) {
+		nsyslog(LOG_ERR, "chdir /proc failed");
+		return -1;
+	}
+    DIR* procDir;
+	if ((procDir = opendir(".")) == NULL) {
+		nsyslog(LOG_ERR, "cannot opendir(/proc)");
+		return -1;
+	}
+
+	/* Free the already existing process list. */
+    freeProcList();
+
+	/* Walk through the directory. */
+    struct dirent* d;
+	while ((d = readdir(procDir)) != NULL) {
+
+		/* See if this is a process */
+        int pid;
+		if ((pid = atoi(d->d_name)) == 0) { continue; }
+
+		/* Get a PROC struct . */
+		PROC* p = xmalloc(sizeof(PROC));
+		memset(p, 0, sizeof(PROC));
+
+        getProcInfo(pid, do_stat, p);
+
+		/* Link it into the list. */
+		p->next = plist;
+		plist = p;
+    }
+    closedir(procDir);
+
+	/* Done. */
+	return 0;
+}
+
+#else /* __sun__ */
+
 /*
  *	Read the proc filesystem.
  *	CWD must be /proc to avoid problems if / is affected by the killing (ie depend on fuse).
@@ -630,6 +880,7 @@ int readproc(int do_stat)
 	/* Done. */
 	return 0;
 }
+#endif /* not __sun__ */
 
 PIDQ_HEAD *init_pid_q(PIDQ_HEAD *q)
 {
