Skip to content

Instantly share code, notes, and snippets.

@koonix
Created September 10, 2022 21:12
Show Gist options
  • Save koonix/3bf5d6e1bff4e4391a5f5b58eacdb9e7 to your computer and use it in GitHub Desktop.
Save koonix/3bf5d6e1bff4e4391a5f5b58eacdb9e7 to your computer and use it in GitHub Desktop.
find the cwd of the currently focused window (in order to spawn another command in that cwd) in dwm. not finished yet.
#include <stdio.h>
#include <glob.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define LENGTH(X) (sizeof(X) / sizeof(X[0]))
void getproccwd(const unsigned int pid, char *cwd, const unsigned int size);
void getdesc(const unsigned int pid, int *desc, const unsigned int size);
int descappend(const unsigned int pid, int *desc, const unsigned int size);
int readfile(const char *path, char *ret, const unsigned int size);
int PID = 1;
int main(void)
{
char cwd[1024];
getproccwd(PID, cwd, sizeof(cwd));
printf("%s\n", cwd);
}
void getproccwd(const unsigned int pid, char *cwd, const unsigned int size)
{
int desc[32] = { -1 };
getdesc(pid, desc, sizeof(desc));
for (int i = 0; i < LENGTH(desc) && desc[i] >= 0; i++) {
char path[32];
snprintf(path, sizeof(path), "/proc/%u/cwd", desc[i]);
ssize_t len;
if ((len = readlink(path, cwd, size - 1)) <= 0)
continue;
cwd[len] = '\0';
if (strncmp(cwd, getenv("HOME"), size) != 0)
return;
}
cwd[0] = '\0';
}
void getdesc(const unsigned int pid, int *desc, const unsigned int size)
{
char ptrn[64];
glob_t gl;
int gl_ret;
snprintf(ptrn, sizeof(ptrn), "/proc/%u/task/[0-9]*/children", pid);
gl_ret = glob(ptrn, GLOB_NOSORT, NULL, &gl);
if (gl_ret == GLOB_NOMATCH || gl_ret == GLOB_ABORTED || gl_ret == GLOB_NOSPACE)
return;
for (int i = 0; i < gl.gl_pathc; i++) {
char pids[128];
if (!(readfile(gl.gl_pathv[i], pids, sizeof(pids))))
continue;
char *state = NULL;
char *chpidstr = strtok_r(pids, " ", &state);
for (; chpidstr; chpidstr = strtok_r(NULL, " ", &state)) {
unsigned int chpid = (unsigned int)strtoul(chpidstr, NULL, 10);
if (!(descappend(chpid, desc, size))) {
globfree(&gl);
return;
}
getdesc(chpid, desc, size);
}
}
globfree(&gl);
}
int descappend(const unsigned int pid, int *desc, const unsigned int size)
{
unsigned int i = 0;
unsigned int count = size / sizeof(int);
for (; i < count && desc[i] >= 0; i++);
if (i >= count)
return 0;
desc[i++] = pid;
if (i < count)
desc[i] = -1;
return 1;
}
int readfile(const char *path, char *ret, const unsigned int size)
{
unsigned int i = 0;
int c;
FILE *f;
if (!(f = fopen(path, "r")))
return 0;
while (i < (size / sizeof(char)) - 1 && ((c = fgetc(f)) != EOF))
ret[i++] = c;
fclose(f);
ret[i] = '\0';
return 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment