sites

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit abeaf4613650b042ce0793bbf93f5960524ac46a
parent 0eff4d4ceebe4ee808707239f7eb5712abf3117a
Author: Connor Lane Smith <cls@lubutu.com>
Date:   Sun, 12 Sep 2010 01:51:45 +0100

added alternative 100 loc dmenu_path.c
Diffstat:
Atools.suckless.org/dmenu/patches/dmenu_path-cls.c | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtools.suckless.org/dmenu/patches/dmenu_path.md | 15++++++---------
2 files changed, 106 insertions(+), 9 deletions(-)

diff --git a/tools.suckless.org/dmenu/patches/dmenu_path-cls.c b/tools.suckless.org/dmenu/patches/dmenu_path-cls.c @@ -0,0 +1,100 @@ +#include <dirent.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> + +#define CACHE ".dmenu_cache" + +static int qstrcmp(const void *a, const void *b); +static void die(const char *s); +static void scan(void); +static int uptodate(void); + +static char **items = NULL; +static const char *HOME, *PATH; +static size_t count = 0; + +int +main(void) { + if(!(HOME = getenv("HOME"))) + die("no $HOME"); + if(!(PATH = getenv("PATH"))) + die("no $PATH"); + if(chdir(HOME) < 0) + die("chdir failed"); + if(uptodate()) { + execlp("cat", "cat", CACHE, NULL); + die("exec failed"); + } + scan(); + return EXIT_SUCCESS; +} + +void +die(const char *s) { + fprintf(stderr, "dmenu_path: %s\n", s); + exit(EXIT_FAILURE); +} + +int +qstrcmp(const void *a, const void *b) { + return strcmp(*(const char **)a, *(const char **)b); +} + +void +scan(void) { + char buf[PATH_MAX]; + char *dir, *path; + size_t i; + struct dirent *ent; + DIR *dp; + FILE *cache; + + if(!(path = strdup(PATH))) + die("strdup failed"); + for(dir = strtok(path, ":"); dir; dir = strtok(NULL, ":")) { + if(!(dp = opendir(dir))) + continue; + while((ent = readdir(dp))) { + snprintf(buf, sizeof buf, "%s/%s", dir, ent->d_name); + if(ent->d_name[0] == '.' || access(buf, X_OK) < 0) + continue; + if(!(items = realloc(items, ++count * sizeof *items))) + die("malloc failed"); + if(!(items[count-1] = strdup(ent->d_name))) + die("strdup failed"); + } + closedir(dp); + } + qsort(items, count, sizeof *items, qstrcmp); + if(!(cache = fopen(CACHE, "w"))) + die("open failed"); + for(i = 0; i < count; i++) { + if(i > 0 && !strcmp(items[i], items[i-1])) + continue; + fprintf(cache, "%s\n", items[i]); + fprintf(stdout, "%s\n", items[i]); + } + fclose(cache); + free(path); +} + +int +uptodate(void) { + char *dir, *path; + time_t mtime; + struct stat st; + + if(stat(CACHE, &st) < 0) + return 0; + mtime = st.st_mtime; + if(!(path = strdup(PATH))) + die("strdup failed"); + for(dir = strtok(path, ":"); dir; dir = strtok(NULL, ":")) + if(!stat(dir, &st) && st.st_mtime > mtime) + return 0; + free(path); + return 1; +} diff --git a/tools.suckless.org/dmenu/patches/dmenu_path.md b/tools.suckless.org/dmenu/patches/dmenu_path.md @@ -1,14 +1,11 @@ -DMENU_PATH -=============== +DMENU_PATH.C +============ -This is a C rewrite for dmenu_path +The mainline dmenu_path is a shell script, which means it can be slow. Faster +implementations have been written in C. Download -------- -* [dmenu_path.c](dmenu_path.c) - - -Author ------- -* Elmo Todurov <todurov@gmail.com> +* [376 LOC](dmenu_path.c) by Elmo Todurov - <todurov@gmail.com> +* [100 LOC](dmenu_path-cls.c) by Connor Lane Smith - <cls@lubutu.com>