Created
September 10, 2022 21:12
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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