]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Cleanup CLI resources on exit and CLI command registration errors.
authorRichard Mudgett <rmudgett@digium.com>
Mon, 3 Dec 2012 19:16:20 +0000 (19:16 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Mon, 3 Dec 2012 19:16:20 +0000 (19:16 +0000)
(issue ASTERISK-20649)
Reported by: Corey Farrell
Patches:
      cli-leaks-1_8-10.patch (license #5909) patch uploaded by Corey Farrell
      cli-leaks-11-trunk.patch (license #5909) patch uploaded by Corey Farrell
      Modified
........

Merged revisions 377073 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 377074 from http://svn.asterisk.org/svn/asterisk/branches/10

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/11@377075 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/cli.c

index e5118ede678fa8efb1fec46578a241cac389173a..782d41363c7c6909dc135084791cc3f9ba930573 100644 (file)
@@ -1888,10 +1888,16 @@ int ast_cli_perms_init(int reload)
        return 0;
 }
 
+static void cli_shutdown(void)
+{
+       ast_cli_unregister_multiple(cli_cli, ARRAY_LEN(cli_cli));
+}
+
 /*! \brief initialize the _full_cmd string in * each of the builtins. */
 void ast_builtins_init(void)
 {
        ast_cli_register_multiple(cli_cli, ARRAY_LEN(cli_cli));
+       ast_register_atexit(cli_shutdown);
 }
 
 /*!
@@ -2056,6 +2062,18 @@ static char *find_best(const char *argv[])
        return cmdline;
 }
 
+static int cli_is_registered(struct ast_cli_entry *e)
+{
+       struct ast_cli_entry *cur = NULL;
+
+       while ((cur = cli_next(cur))) {
+               if (cur == e) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
 static int __ast_cli_unregister(struct ast_cli_entry *e, struct ast_cli_entry *ed)
 {
        if (e->inuse) {
@@ -2087,6 +2105,15 @@ static int __ast_cli_register(struct ast_cli_entry *e, struct ast_cli_entry *ed)
        char **dst = (char **)e->cmda;  /* need to cast as the entry is readonly */
        char *s;
 
+       AST_RWLIST_WRLOCK(&helpers);
+
+       if (cli_is_registered(e)) {
+               ast_log(LOG_WARNING, "Command '%s' already registered (the same ast_cli_entry)\n",
+                       S_OR(e->_full_cmd, e->command));
+               ret = 0;  /* report success */
+               goto done;
+       }
+
        memset(&a, '\0', sizeof(a));
        e->handler(e, CLI_INIT, &a);
        /* XXX check that usage and command are filled up */
@@ -2102,14 +2129,16 @@ static int __ast_cli_register(struct ast_cli_entry *e, struct ast_cli_entry *ed)
        }
        *dst++ = NULL;
 
-       AST_RWLIST_WRLOCK(&helpers);
-
        if (find_cli(e->cmda, 1)) {
-               ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n", S_OR(e->_full_cmd, e->command));
+               ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n",
+                       S_OR(e->_full_cmd, e->command));
                goto done;
        }
-       if (set_full_cmd(e))
+       if (set_full_cmd(e)) {
+               ast_log(LOG_WARNING, "Error registering CLI Command '%s'\n",
+                       S_OR(e->_full_cmd, e->command));
                goto done;
+       }
 
        lf = e->cmdlen;
        AST_RWLIST_TRAVERSE_SAFE_BEGIN(&helpers, cur, list) {
@@ -2129,6 +2158,10 @@ static int __ast_cli_register(struct ast_cli_entry *e, struct ast_cli_entry *ed)
 
 done:
        AST_RWLIST_UNLOCK(&helpers);
+       if (ret) {
+               ast_free(e->command);
+               e->command = NULL;
+       }
 
        return ret;
 }