Revert "Return the path of the deepest accessible child"

This reverts commit 1bd171cc95.
This commit is contained in:
Adrien Schildknecht 2014-12-21 02:21:13 +01:00
parent d0b4df4639
commit f233359660

116
xcwd.c
View File

@ -1,4 +1,4 @@
/* This is xcwd written by Adrien Schildknecht (c) 2013-2014 /* This is xcwd written by Adrien Schildknecht (c) 2013
* Email: adrien+dev@schischi.me * Email: adrien+dev@schischi.me
* Feel free to copy and redistribute in terms of the * Feel free to copy and redistribute in terms of the
* BSD license * BSD license
@ -22,21 +22,19 @@
# include <libutil.h> # include <libutil.h>
#endif #endif
//#define DEBUG #define DEBUG 0
#define XA_STRING (XInternAtom(dpy, "STRING", 0)) #define XA_STRING (XInternAtom(dpy, "STRING", 0))
#define XA_CARDINAL (XInternAtom(dpy, "CARDINAL", 0)) #define XA_CARDINAL (XInternAtom(dpy, "CARDINAL", 0))
#define XA_WM_STATE (XInternAtom(dpy, "WM_STATE", 0)) #define XA_WM_STATE (XInternAtom(dpy, "WM_STATE", 0))
#ifdef DEBUG #define LOG(fmt, ...) \
#define LOG(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) do { if (DEBUG) fprintf(stderr, fmt, __VA_ARGS__); } while (0)
#else
#define LOG(fmt, ...) do { } while (0)
#endif
Display *dpy; Display *dpy;
struct proc_list { typedef struct processes_s *processes_t;
struct processes_s {
struct proc_s { struct proc_s {
long pid; long pid;
long ppid; long ppid;
@ -48,18 +46,18 @@ struct proc_list {
size_t n; size_t n;
}; };
static int process_name_cmp(const void *p1, const void *p2) int nameCmp(const void *p1, const void *p2)
{ {
return strcasecmp(((struct proc_s *)p1)->name, return strcasecmp(((struct proc_s *)p1)->name,
((struct proc_s *)p2)->name); ((struct proc_s *)p2)->name);
} }
static int process_ppid_cmp(const void *p1, const void *p2) int ppidCmp(const void *p1, const void *p2)
{ {
return ((struct proc_s *)p1)->ppid - ((struct proc_s *)p2)->ppid; return ((struct proc_s *)p1)->ppid - ((struct proc_s *)p2)->ppid;
} }
static Window focused_window(void) static Window focusedWindow()
{ {
Atom type; Atom type;
Window focuswin, root, *children; Window focuswin, root, *children;
@ -95,7 +93,7 @@ static Window focused_window(void)
return 0; return 0;
} }
static long pid_of_window(Window win) static long windowPid(Window focuswin)
{ {
Atom nameAtom = XInternAtom(dpy, "_NET_WM_PID", 1); Atom nameAtom = XInternAtom(dpy, "_NET_WM_PID", 1);
Atom type; Atom type;
@ -104,7 +102,7 @@ static long pid_of_window(Window win)
unsigned long nitems, after; unsigned long nitems, after;
unsigned char *data; unsigned char *data;
status = XGetWindowProperty(dpy, win, nameAtom, 0, 1024, 0, status = XGetWindowProperty(dpy, focuswin, nameAtom, 0, 1024, 0,
XA_CARDINAL, &type, &format, &nitems, &after, &data); XA_CARDINAL, &type, &format, &nitems, &after, &data);
if (status == Success && data) { if (status == Success && data) {
pid = *((long*)data); pid = *((long*)data);
@ -116,7 +114,7 @@ static long pid_of_window(Window win)
return pid; return pid;
} }
static char* window_strings(Window win, long unsigned int *size, char *hint) static char* windowStrings(Window focuswin, long unsigned int *size, char* hint)
{ {
Atom nameAtom = XInternAtom(dpy, hint, 1); Atom nameAtom = XInternAtom(dpy, hint, 1);
Atom type; Atom type;
@ -126,7 +124,7 @@ static char* window_strings(Window win, long unsigned int *size, char *hint)
unsigned char *data = 0; unsigned char *data = 0;
char *ret = NULL; char *ret = NULL;
if (XGetWindowProperty(dpy, win, nameAtom, 0, 1024, 0, AnyPropertyType, if (XGetWindowProperty(dpy, focuswin, nameAtom, 0, 1024, 0, AnyPropertyType,
&type, &format, size, &after, &data) == Success) { &type, &format, size, &after, &data) == Success) {
if (data) { if (data) {
if (type == XA_STRING) { if (type == XA_STRING) {
@ -146,22 +144,22 @@ static char* window_strings(Window win, long unsigned int *size, char *hint)
return ret; return ret;
} }
static void processes_free(struct proc_list * p) static void freeProcesses(processes_t p)
{ {
free(p->ps); free(p->ps);
free(p); free(p);
} }
static struct proc_list * processes_list(void) static processes_t getProcesses(void)
{ {
struct proc_list * p = NULL; processes_t p = NULL;
#ifdef LINUX #ifdef LINUX
glob_t globbuf; glob_t globbuf;
unsigned int i, j, k; unsigned int i, j, k;
char line[201] = {0}; char line[201] = {0};
glob("/proc/[0-9]*", GLOB_NOSORT, NULL, &globbuf); glob("/proc/[0-9]*", GLOB_NOSORT, NULL, &globbuf);
p = malloc(sizeof(struct proc_list)); p = malloc(sizeof(struct processes_s));
p->ps = malloc(globbuf.gl_pathc * sizeof(struct proc_s)); p->ps = malloc(globbuf.gl_pathc * sizeof(struct proc_s));
LOG("Found %zu processes\n", globbuf.gl_pathc); LOG("Found %zu processes\n", globbuf.gl_pathc);
@ -175,8 +173,7 @@ static struct proc_list * processes_list(void)
tn = fopen(name, "r"); tn = fopen(name, "r");
if (tn == NULL) if (tn == NULL)
continue; continue;
if (fread(line, 200, 1, tn) == 0) fread(line, 200, 1, tn);
continue;
p->ps[j].pid = atoi(strtok(line, " ")); p->ps[j].pid = atoi(strtok(line, " "));
k = snprintf(p->ps[j].name, 32, "%s", strtok(NULL, " ") + 1); k = snprintf(p->ps[j].name, 32, "%s", strtok(NULL, " ") + 1);
p->ps[j].name[k - 1] = 0; p->ps[j].name[k - 1] = 0;
@ -192,7 +189,7 @@ static struct proc_list * processes_list(void)
#endif #endif
#ifdef BSD #ifdef BSD
unsigned int count; unsigned int count;
p = malloc(sizeof(struct proc_list)); p = malloc(sizeof(struct processes_s));
struct kinfo_proc *kp; struct kinfo_proc *kp;
size_t len = 0; size_t len = 0;
int name[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PROC, 0 }; int name[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PROC, 0 };
@ -228,7 +225,7 @@ static struct proc_list * processes_list(void)
return p; return p;
} }
static int read_process_path(struct proc_s *proc) static int readPath(struct proc_s *proc)
{ {
#ifdef LINUX #ifdef LINUX
char buf[255]; char buf[255];
@ -259,40 +256,35 @@ static int read_process_path(struct proc_s *proc)
return 1; return 1;
} }
static int child_cwd(struct proc_list * p, struct proc_s *key) static int cwdOfDeepestChild(processes_t p, long pid)
{ {
int i; int i;
struct proc_s *res = (struct proc_s *)bsearch(key, p->ps, p->n, struct proc_s key = { .pid = pid, .ppid = pid},
sizeof(struct proc_s), process_ppid_cmp); *res = NULL, *lastRes = NULL;
struct proc_s new_key = { .pid = key->ppid };
if (res == NULL) { do {
LOG("--> %ld pid\n", key->pid); if(res) {
return read_process_path(key); lastRes = res;
key.ppid = res->pid;
}
res = (struct proc_s *)bsearch(&key, p->ps, p->n,
sizeof(struct proc_s), ppidCmp);
} while(res);
if(!lastRes) {
return readPath(&key);
} }
for(i = 0; res != p->ps && (res - i)->ppid == res->ppid; ++i) {
new_key.ppid = (res - i)->pid; for(i = 0; lastRes != p->ps && (lastRes - i)->ppid == lastRes->ppid; ++i)
LOG("--> %ld ppid\n", new_key.ppid); if(readPath((lastRes - i)))
if(child_cwd(p, &new_key))
return 1; return 1;
} for(i = 1; lastRes != p->ps + p->n && (lastRes + i)->ppid == lastRes->ppid; ++i)
for(i = 1; res != p->ps + p->n && (res + i)->ppid == res->ppid; ++i) { if(readPath((lastRes + i)))
new_key.ppid = (res + i)->pid;
LOG("--> %ld ppid\n", new_key.ppid);
if(child_cwd(p, &new_key))
return 1; return 1;
} return 0;
return read_process_path(key);
} }
static int deepest_child_cwd(struct proc_list * p, long pid) int getHomeDirectory()
{
struct proc_s key = { .pid = pid, .ppid = pid};
return child_cwd(p, &key);
}
int get_home_dir(void)
{ {
LOG("%s", "getenv $HOME...\n"); LOG("%s", "getenv $HOME...\n");
fprintf(stdout, "%s\n", getenv("HOME")); fprintf(stdout, "%s\n", getenv("HOME"));
@ -304,32 +296,32 @@ int main(int argc, const char *argv[])
(void)argc; (void)argc;
(void)argv; (void)argv;
struct proc_list * p; processes_t p;
long pid; long pid;
int ret = EXIT_SUCCESS; int ret = EXIT_SUCCESS;
Window w = focused_window(); Window w = focusedWindow();
if (w == None) if (w == None)
return get_home_dir(); return getHomeDirectory();
pid = pid_of_window(w); pid = windowPid(w);
p = processes_list(); p = getProcesses();
if(!p) if(!p)
return get_home_dir(); return getHomeDirectory();
if(pid != -1) if(pid != -1)
qsort(p->ps, p->n, sizeof(struct proc_s), process_ppid_cmp); qsort(p->ps, p->n, sizeof(struct proc_s), ppidCmp);
else { else {
long unsigned int size; long unsigned int size;
unsigned int i; unsigned int i;
char* strings; char* strings;
struct proc_s *res = NULL, key; struct proc_s *res = NULL, key;
qsort(p->ps, p->n, sizeof(struct proc_s), process_name_cmp); qsort(p->ps, p->n, sizeof(struct proc_s), nameCmp);
strings = window_strings(w, &size, "WM_CLASS"); strings = windowStrings(w, &size, "WM_CLASS");
for(i = 0; i < size; i += strlen(strings + i) + 1) { for(i = 0; i < size; i += strlen(strings + i) + 1) {
LOG("pidof %s\n", strings + i); LOG("pidof %s\n", strings + i);
strcpy(key.name, strings + i); strcpy(key.name, strings + i);
res = (struct proc_s *)bsearch(&key, p->ps, p->n, res = (struct proc_s *)bsearch(&key, p->ps, p->n,
sizeof(struct proc_s), process_name_cmp); sizeof(struct proc_s), nameCmp);
if(res) if(res)
break; break;
} }
@ -340,9 +332,9 @@ int main(int argc, const char *argv[])
if (size) if (size)
free(strings); free(strings);
} }
if (pid == -1 || !deepest_child_cwd(p, pid)) if (pid == -1 || !cwdOfDeepestChild(p, pid))
ret = get_home_dir(); ret = getHomeDirectory();
processes_free(p); freeProcesses(p);
return ret; return ret;
} }