Use dirent.h instead of fts.h for launcher completion because of compatibility
This commit is contained in:
parent
a37c01c56d
commit
235935f36f
105
src/launcher.c
105
src/launcher.c
@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <fts.h>
|
#include <dirent.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
|
||||||
@ -15,18 +15,18 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
fts_alphasort(const FTSENT **a, const FTSENT **b)
|
qsort_string_compare(const void * a, const void * b)
|
||||||
{
|
{
|
||||||
return (strcmp((*a)->fts_name, (*b)->fts_name));
|
return (strcmp(*(char **)a, *(char **)b));
|
||||||
}
|
}
|
||||||
|
|
||||||
static char **
|
static char **
|
||||||
complete_on_command(char *start)
|
complete_on_command(char *start)
|
||||||
{
|
{
|
||||||
|
struct dirent *content;
|
||||||
|
DIR *dir;
|
||||||
char **paths, *path, *p, **namelist = NULL;
|
char **paths, *path, *p, **namelist = NULL;
|
||||||
int count;
|
int i, count;
|
||||||
FTS *tree;
|
|
||||||
FTSENT *node;
|
|
||||||
|
|
||||||
if(!(path = getenv("PATH")) || !start)
|
if(!(path = getenv("PATH")) || !start)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -46,40 +46,31 @@ complete_on_command(char *start)
|
|||||||
|
|
||||||
paths[count] = NULL;
|
paths[count] = NULL;
|
||||||
|
|
||||||
if(!(tree = fts_open(paths, FTS_NOCHDIR, fts_alphasort)))
|
/* recursively open PATH */
|
||||||
|
for(i = count = 0; paths[i]; ++i)
|
||||||
{
|
{
|
||||||
warnl("fts_open");
|
if(!(dir = opendir(paths[i])))
|
||||||
free(paths);
|
continue;
|
||||||
free(path);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
count = 0;
|
while((content = readdir(dir)))
|
||||||
while((node = fts_read(tree)))
|
|
||||||
{
|
|
||||||
if(node->fts_level > 0)
|
|
||||||
fts_set(tree, node, FTS_SKIP);
|
|
||||||
|
|
||||||
if(node->fts_level
|
|
||||||
&& (node->fts_info & FTS_F)
|
|
||||||
&& (node->fts_info & FTS_NS)
|
|
||||||
&& (node->fts_statp->st_mode & S_IXOTH)
|
|
||||||
&& !strncmp(node->fts_name, start, strlen(start)))
|
|
||||||
{
|
{
|
||||||
namelist = xrealloc(namelist, ++count, sizeof(*namelist));
|
if(strncmp(content->d_name, ".", 1)
|
||||||
namelist[count - 1] = xstrdup(node->fts_name + strlen(start));
|
&& !strncmp(content->d_name, start, strlen(start)))
|
||||||
|
{
|
||||||
|
namelist = xrealloc(namelist, ++count, sizeof(*namelist));
|
||||||
|
namelist[count - 1] = xstrdup(content->d_name + strlen(start));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
closedir(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(count)
|
if(count)
|
||||||
{
|
{
|
||||||
|
qsort(namelist, count, sizeof(char *), qsort_string_compare);
|
||||||
namelist = xrealloc(namelist, ++count, sizeof(*namelist));
|
namelist = xrealloc(namelist, ++count, sizeof(*namelist));
|
||||||
namelist[count - 1] = NULL;
|
namelist[count - 1] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fts_close(tree))
|
|
||||||
warnl("fts_close");
|
|
||||||
|
|
||||||
free(paths);
|
free(paths);
|
||||||
free(path);
|
free(path);
|
||||||
|
|
||||||
@ -93,12 +84,12 @@ complete_on_command(char *start)
|
|||||||
static char **
|
static char **
|
||||||
complete_on_files(char *start)
|
complete_on_files(char *start)
|
||||||
{
|
{
|
||||||
char *p, *home, *path, *dirname = NULL, *paths[2], **namelist = NULL;
|
struct dirent *content = NULL;
|
||||||
int count;
|
struct stat st;
|
||||||
FTS *tree;
|
DIR *dir;
|
||||||
FTSENT *node;
|
char *home, *path, *dirname = NULL;
|
||||||
|
char **namelist = NULL, *filepath, *p = start;
|
||||||
p = start;
|
int count = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Search the directory to open and set
|
* Search the directory to open and set
|
||||||
@ -135,28 +126,33 @@ complete_on_files(char *start)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
paths[0] = path;
|
if((dir = opendir(path)))
|
||||||
paths[1] = NULL;
|
|
||||||
|
|
||||||
if(!(tree = fts_open(paths, FTS_NOCHDIR, fts_alphasort)))
|
|
||||||
{
|
{
|
||||||
warnl("fts_open");
|
while((content = readdir(dir)))
|
||||||
free(dirname);
|
|
||||||
free(path);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
while((node = fts_read(tree)))
|
|
||||||
{
|
|
||||||
if(node->fts_level > 0)
|
|
||||||
fts_set(tree, node, FTS_SKIP);
|
|
||||||
|
|
||||||
if(node->fts_level && !strncmp(node->fts_name, p, strlen(p)))
|
|
||||||
{
|
{
|
||||||
namelist = xrealloc(namelist, ++count, sizeof(*namelist));
|
if(!strcmp(content->d_name, ".")
|
||||||
namelist[count - 1] = xstrdup(node->fts_name + strlen(p));
|
|| !strcmp(content->d_name, "..")
|
||||||
|
|| strncmp(content->d_name, p, strlen(p)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* If it's a directory append '/' to the completion */
|
||||||
|
xasprintf(&filepath, "%s/%s", path, content->d_name);
|
||||||
|
|
||||||
|
if(filepath && stat(filepath, &st) != -1)
|
||||||
|
{
|
||||||
|
namelist = xrealloc(namelist, ++count, sizeof(*namelist));
|
||||||
|
|
||||||
|
if(S_ISDIR(st.st_mode))
|
||||||
|
xasprintf(&namelist[count - 1], "%s/", content->d_name + strlen(p));
|
||||||
|
else
|
||||||
|
namelist[count - 1] = xstrdup(content->d_name + strlen(p));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
warnl("%s", filepath);
|
||||||
|
|
||||||
|
free(filepath);
|
||||||
}
|
}
|
||||||
|
closedir(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(count)
|
if(count)
|
||||||
@ -165,9 +161,6 @@ complete_on_files(char *start)
|
|||||||
namelist[count - 1] = NULL;
|
namelist[count - 1] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fts_close(tree))
|
|
||||||
warnl("fts_close");
|
|
||||||
|
|
||||||
free(dirname);
|
free(dirname);
|
||||||
free(path);
|
free(path);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user