summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Adrien Schildknecht <adrien+dev@schischi.me>2013-07-02 02:54:09 +0200
committerGravatar Adrien Schildknecht <adrien+dev@schischi.me>2013-07-02 02:54:09 +0200
commit652117ebfe3ad17d16a148bd65e2ad55c2308f1f (patch)
treea7ccd7a9310d6bb59467b9fbbf68a913bb959836
parent8efe17cc9992de696090841cd72b2f8c3fd29969 (diff)
parent3d0a0b310187950c21731a0a37fe5341f860d9e7 (diff)
Merge branch 'bsd'
-rw-r--r--Makefile16
-rw-r--r--xcwd.c80
2 files changed, 83 insertions, 13 deletions
diff --git a/Makefile b/Makefile
index 15b6b80..ef4252b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,22 @@
CFILES=xcwd.c
CC=gcc
-CFLAGS=-Wall -Werror -Wextra -pedantic -std=gnu99 -O2
+CFLAGS=-Wall -Werror -Wextra -std=gnu99 -O2
LDFLAGS=-lX11
EXE="xcwd"
-O=${CFILES:.c=.o}
prefix=/usr/
+UNAME:=$(shell uname)
+O=${CFILES:.c=.o}
+
+ifeq ($(UNAME), Linux)
+ CFLAGS += -DLINUX
+else
+ ifeq ($(UNAME), FreeBSD)
+ CFLAGS += -I/usr/local/include/ -DBSD
+ LDFLAGS += -L/usr/local/lib -lutil
+ else
+ $(error Operating System not supported.)
+ endif
+endif
${EXE}: clean ${O}
${CC} -o $@ ${O} ${CFLAGS} ${LDFLAGS}
diff --git a/xcwd.c b/xcwd.c
index 75aa3ea..8a4e9aa 100644
--- a/xcwd.c
+++ b/xcwd.c
@@ -1,4 +1,4 @@
-/* This is fcwd written by Adrien Schildknecht (c) 2013
+/* This is xcwd written by Adrien Schildknecht (c) 2013
* Email: adrien+dev@schischi.me
* Feel free to copy and redistribute in terms of the
* BSD license
@@ -8,11 +8,20 @@
#include <stdio.h>
#include <string.h>
#include <strings.h>
-#include <unistd.h>
-#include <glob.h>
-#include <sys/stat.h>
#include <X11/Xlib.h>
+#ifdef LINUX
+# include <sys/stat.h>
+# include <glob.h>
+# include <unistd.h>
+#endif
+
+#ifdef BSD
+# include <sys/sysctl.h>
+# include <sys/user.h>
+# include <libutil.h>
+#endif
+
#define DEBUG 0
#define XA_STRING (XInternAtom(dpy, "STRING", 0))
@@ -30,6 +39,9 @@ struct processes_s {
long pid;
long ppid;
char name[32];
+#ifdef BSD
+ char cwd[MAXPATHLEN];
+#endif
} *ps;
size_t n;
};
@@ -138,9 +150,10 @@ static void freeProcesses(processes_t p)
static processes_t getProcesses(void)
{
+ processes_t p = NULL;
+#ifdef LINUX
glob_t globbuf;
unsigned int i, j;
- processes_t p;
glob("/proc/[0-9]*", GLOB_NOSORT, NULL, &globbuf);
p = malloc(sizeof(struct processes_s));
@@ -158,7 +171,7 @@ static processes_t getProcesses(void)
if (tn == NULL)
continue;
if(fscanf(tn, "%ld (%32[^)] %*3c %ld", &p->ps[j].pid,
- p->ps[j].name, &p->ps[j].ppid) != 3)
+ p->ps[j].name, &p->ps[j].ppid) != 3)
return NULL;
LOG("\t%-20s\tpid=%6ld\tppid=%6ld\n", p->ps[j].name, p->ps[j].pid,
p->ps[j].ppid);
@@ -167,16 +180,53 @@ static processes_t getProcesses(void)
}
p->n = j;
globfree(&globbuf);
+#endif
+#ifdef BSD
+ unsigned int count;
+ p = malloc(sizeof(struct processes_s));
+ struct kinfo_proc *kp;
+ size_t len = 0;
+ int name[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PROC, 0 };
+ int error;
+ error = sysctl(name, 4, NULL, &len, NULL, 0);
+ kp = malloc(len);
+ error = sysctl(name, 4, kp, &len, NULL, 0);
+ count = len / sizeof(*kp);
+ p->ps = malloc(sizeof(struct proc_s) * count);
+ p->n = count;
+
+ unsigned int i;
+ for(i = 0; i < count; ++i) {
+ struct kinfo_file *files, *kif;
+ int cnt, j;
+ if(kp[i].ki_fd == NULL)
+ continue;
+ files = kinfo_getfile(kp[i].ki_pid, &cnt);
+ for(j = 0; j < cnt; ++j) {
+ kif = &files[j];
+ if(kif->kf_fd != KF_FD_TYPE_CWD)
+ continue;
+ p->ps[i].pid = kp[i].ki_pid;
+ p->ps[i].ppid = kp[i].ki_ppid;
+ strncpy(p->ps[i].name, kp[i].ki_tdname, 32);
+ strncpy(p->ps[i].cwd, kif->kf_path, MAXPATHLEN);
+ LOG("\t%-20s\tpid=%6ld\tppid=%6ld\n", p->ps[j].name, p->ps[j].pid,
+ p->ps[j].ppid);
+ }
+
+ }
+#endif
return p;
}
-static int readPath(long pid)
+static int readPath(struct proc_s *proc)
{
+#ifdef LINUX
char buf[255];
char path[64];
ssize_t len;
- snprintf(path, sizeof(path), "/proc/%ld/cwd", pid);
+ snprintf(path, sizeof(path), "/proc/%ld/cwd", proc->pid);
if ((len = readlink(path, buf, 255)) != -1)
buf[len] = '\0';
if(len <= 0) {
@@ -185,6 +235,14 @@ static int readPath(long pid)
}
LOG("Read %s\n", path);
fprintf(stdout, "%s\n", buf);
+#endif
+#ifdef BSD
+ if(!strlen(proc->cwd)) {
+ LOG("%ld cwd is empty\n", proc->pid);
+ return 0;
+ }
+ fprintf(stdout, "%s\n", proc->cwd);
+#endif
return 1;
}
@@ -203,15 +261,15 @@ static void cwdOfDeepestChild(processes_t p, long pid)
} while(res);
if(!lastRes) {
- readPath(pid);
+ readPath(&key);
return;
}
for(i = 0; lastRes != p->ps && (lastRes - i)->ppid == lastRes->ppid; ++i)
- if(readPath((lastRes - i)->pid))
+ if(readPath((lastRes - i)))
return;
for(i = 1; lastRes != p->ps + p->n && (lastRes + i)->ppid == lastRes->ppid; ++i)
- if(readPath((lastRes + i)->pid))
+ if(readPath((lastRes + i)))
return;
}