Merged revisions 97350 via svnmerge from

https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r97350 | tilghman | 2008-01-08 18:44:14 -0600 (Tue, 08 Jan 2008) | 5 lines

Allow filename completion on zero-length modules, remove a memory leak, remove
a file descriptor leak, and make filename completion thread-safe.
Patched and tested by tilghman.
(Closes issue #11681)

........


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@97364 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Tilghman Lesher
2008-01-09 00:51:59 +00:00
parent c1eaacc3df
commit 43a172de57
2 changed files with 45 additions and 47 deletions

View File

@@ -121,7 +121,7 @@ static AST_RWLIST_HEAD_STATIC(helpers, ast_cli_entry);
static char *complete_fn(const char *word, int state) static char *complete_fn(const char *word, int state)
{ {
char *c; char *c, *d;
char filename[256]; char filename[256];
if (word[0] == '/') if (word[0] == '/')
@@ -129,13 +129,15 @@ static char *complete_fn(const char *word, int state)
else else
snprintf(filename, sizeof(filename), "%s/%s", ast_config_AST_MODULE_DIR, word); snprintf(filename, sizeof(filename), "%s/%s", ast_config_AST_MODULE_DIR, word);
/* XXX the following function is not reentrant, so we better not use it */ c = d = filename_completion_function(filename, state);
c = filename_completion_function(filename, state);
if (c && word[0] != '/') if (c && word[0] != '/')
c += (strlen(ast_config_AST_MODULE_DIR) + 1); c += (strlen(ast_config_AST_MODULE_DIR) + 1);
if (c)
c = ast_strdup(c);
free(d);
return c ? ast_strdup(c) : c; return c;
} }
static char *handle_load(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) static char *handle_load(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)

View File

@@ -1189,26 +1189,22 @@ tilde_expand(char *txt)
/* /*
* return first found file name starting by the ``text'' or NULL if no * return first found file name starting by the ``text'' or NULL if no
* such file can be found * such file can be found.
* value of ``state'' is ignored * The first ``state'' matches are ignored.
* *
* it's caller's responsibility to free returned string * it's caller's responsibility to free returned string
*/ */
char * char *
filename_completion_function(const char *text, int state) filename_completion_function(const char *text, int state)
{ {
static DIR *dir = NULL; DIR *dir = NULL;
static char *filename = NULL, *dirname = NULL; char *filename = NULL, *dirname = NULL;
static size_t filename_len = 0; size_t filename_len = 0;
struct dirent *entry; struct dirent *entry;
char *temp; char *temp;
size_t len; size_t len;
int count = 0;
if (state == 0 || dir == NULL) {
if (dir != NULL) {
closedir(dir);
dir = NULL;
}
temp = strrchr(text, '/'); temp = strrchr(text, '/');
if (temp) { if (temp) {
temp++; temp++;
@@ -1232,25 +1228,24 @@ filename_completion_function(const char *text, int state)
} }
/* will be used in cycle */ /* will be used in cycle */
filename_len = strlen(filename); filename_len = strlen(filename);
if (filename_len == 0)
return (NULL); /* no expansion possible */
dir = opendir(dirname ? dirname : "."); dir = opendir(dirname ? dirname : ".");
if (!dir) if (!dir)
return (NULL); /* cannot open the directory */ return (NULL); /* cannot open the directory */
}
/* find the match */ /* find the match */
while ((entry = readdir(dir)) != NULL) { while ((entry = readdir(dir)) != NULL) {
/* otherwise, get first entry where first */ /* otherwise, get first entry where first */
/* filename_len characters are equal */ /* filename_len characters are equal */
if (entry->d_name[0] == filename[0] if (
#if defined(__SVR4) || defined(__linux__) #if defined(__SVR4) || defined(__linux__)
&& strlen(entry->d_name) >= filename_len strlen(entry->d_name) >= filename_len
#else #else
&& entry->d_namlen >= filename_len entry->d_namlen >= filename_len
#endif #endif
&& strncmp(entry->d_name, filename, && strncmp(entry->d_name, filename,
filename_len) == 0) filename_len) == 0
&& (state-- == 0))
break; break;
} }
@@ -1272,6 +1267,7 @@ filename_completion_function(const char *text, int state)
strcat(temp, "/"); /* safe */ strcat(temp, "/"); /* safe */
} else } else
temp = NULL; temp = NULL;
closedir(dir);
return (temp); return (temp);
} }