[asterisk-commits] tilghman: branch 1.4 r97350 - in /branches/1.4/main: cli.c editline/readline.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jan 8 18:44:14 CST 2008


Author: tilghman
Date: Tue Jan  8 18:44:14 2008
New Revision: 97350

URL: http://svn.digium.com/view/asterisk?view=rev&rev=97350
Log:
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)

Modified:
    branches/1.4/main/cli.c
    branches/1.4/main/editline/readline.c

Modified: branches/1.4/main/cli.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/main/cli.c?view=diff&rev=97350&r1=97349&r2=97350
==============================================================================
--- branches/1.4/main/cli.c (original)
+++ branches/1.4/main/cli.c Tue Jan  8 18:44:14 2008
@@ -1248,7 +1248,7 @@
 
 static char *complete_fn_2(const char *line, const char *word, int pos, int state)
 {
-	char *c;
+	char *c, *d;
 	char filename[256];
 
 	if (pos != 1)
@@ -1259,17 +1259,20 @@
 	else
 		snprintf(filename, sizeof(filename), "%s/%s", ast_config_AST_MODULE_DIR, word);
 	
-	c = filename_completion_function(filename, state);
+	c = d = filename_completion_function(filename, state);
 	
 	if (c && word[0] != '/')
 		c += (strlen(ast_config_AST_MODULE_DIR) + 1);
-	
-	return c ? strdup(c) : c;
+	if (c)
+		c = strdup(c);
+	free(d);
+	
+	return c;
 }
 
 static char *complete_fn_3(const char *line, const char *word, int pos, int state)
 {
-	char *c;
+	char *c, *d;
 	char filename[256];
 
 	if (pos != 2)
@@ -1280,12 +1283,15 @@
 	else
 		snprintf(filename, sizeof(filename), "%s/%s", ast_config_AST_MODULE_DIR, word);
 	
-	c = filename_completion_function(filename, state);
+	c = d = filename_completion_function(filename, state);
 	
 	if (c && word[0] != '/')
 		c += (strlen(ast_config_AST_MODULE_DIR) + 1);
-	
-	return c ? strdup(c) : c;
+	if (c)
+		c = strdup(c);
+	free(d);
+	
+	return c;
 }
 
 static int group_show_channels(int fd, int argc, char *argv[])

Modified: branches/1.4/main/editline/readline.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/main/editline/readline.c?view=diff&rev=97350&r1=97349&r2=97350
==============================================================================
--- branches/1.4/main/editline/readline.c (original)
+++ branches/1.4/main/editline/readline.c Tue Jan  8 18:44:14 2008
@@ -1189,68 +1189,63 @@
 
 /*
  * return first found file name starting by the ``text'' or NULL if no
- * such file can be found
- * value of ``state'' is ignored
+ * such file can be found.
+ * The first ``state'' matches are ignored.
  *
  * it's caller's responsibility to free returned string
  */
 char *
 filename_completion_function(const char *text, int state)
 {
-	static DIR *dir = NULL;
-	static char *filename = NULL, *dirname = NULL;
-	static size_t filename_len = 0;
+	DIR *dir = NULL;
+	char *filename = NULL, *dirname = NULL;
+	size_t filename_len = 0;
 	struct dirent *entry;
 	char *temp;
 	size_t len;
-
-	if (state == 0 || dir == NULL) {
-		if (dir != NULL) {
-			closedir(dir);
-			dir = NULL;
-		}
-		temp = strrchr(text, '/');
-		if (temp) {
-			temp++;
-			filename = realloc(filename, strlen(temp) + 1);
-			(void) strcpy(filename, temp);
-			len = temp - text;	/* including last slash */
-			dirname = realloc(dirname, len + 1);
-			(void) strncpy(dirname, text, len);
-			dirname[len] = '\0';
-		} else {
-			filename = strdup(text);
-			dirname = NULL;
-		}
-
-		/* support for ``~user'' syntax */
-		if (dirname && *dirname == '~') {
-			temp = tilde_expand(dirname);
-			dirname = realloc(dirname, strlen(temp) + 1);
-			(void) strcpy(dirname, temp);	/* safe */
-			free(temp);	/* no longer needed */
-		}
-		/* will be used in cycle */
-		filename_len = strlen(filename);
-		if (filename_len == 0)
-			return (NULL);	/* no expansion possible */
-
-		dir = opendir(dirname ? dirname : ".");
-		if (!dir)
-			return (NULL);	/* cannot open the directory */
-	}
+	int count = 0;
+
+	temp = strrchr(text, '/');
+	if (temp) {
+		temp++;
+		filename = realloc(filename, strlen(temp) + 1);
+		(void) strcpy(filename, temp);
+		len = temp - text;	/* including last slash */
+		dirname = realloc(dirname, len + 1);
+		(void) strncpy(dirname, text, len);
+		dirname[len] = '\0';
+	} else {
+		filename = strdup(text);
+		dirname = NULL;
+	}
+
+	/* support for ``~user'' syntax */
+	if (dirname && *dirname == '~') {
+		temp = tilde_expand(dirname);
+		dirname = realloc(dirname, strlen(temp) + 1);
+		(void) strcpy(dirname, temp);	/* safe */
+		free(temp);	/* no longer needed */
+	}
+	/* will be used in cycle */
+	filename_len = strlen(filename);
+
+	dir = opendir(dirname ? dirname : ".");
+	if (!dir)
+		return (NULL);	/* cannot open the directory */
+
 	/* find the match */
 	while ((entry = readdir(dir)) != NULL) {
 		/* otherwise, get first entry where first */
 		/* filename_len characters are equal	  */
-		if (entry->d_name[0] == filename[0]
+		if (
 #if defined(__SVR4) || defined(__linux__)
-		    && strlen(entry->d_name) >= filename_len
+		    strlen(entry->d_name) >= filename_len
 #else
-		    && entry->d_namlen >= filename_len
+		    entry->d_namlen >= filename_len
 #endif
 		    && strncmp(entry->d_name, filename,
-			filename_len) == 0)
+			filename_len) == 0
+			&& (state-- == 0))
 			break;
 	}
 
@@ -1272,6 +1267,7 @@
 			strcat(temp, "/");	/* safe */
 	} else
 		temp = NULL;
+	closedir(dir);
 
 	return (temp);
 }




More information about the asterisk-commits mailing list