memory leaks: Memory leak cleanup patch by Corey Farrell (second set)
[asterisk/asterisk.git] / main / asterisk.c
index 7e5ddac..2e5ffa7 100644 (file)
@@ -247,6 +247,7 @@ int daemon(int, int);  /* defined in libresolv of all places */
 #include "asterisk/stasis_endpoints.h"
 #include "asterisk/stasis_system.h"
 #include "asterisk/security_events.h"
+#include "asterisk/endpoints.h"
 
 #include "../defaults.h"
 
@@ -1974,11 +1975,17 @@ static void really_quit(int num, shutdown_nice_t niceness, int restart)
                close(ast_socket);
                ast_socket = -1;
                unlink(ast_config_AST_SOCKET);
+               pthread_kill(lthread, SIGURG);
+               pthread_join(lthread, NULL);
        }
        if (ast_consock > -1)
                close(ast_consock);
        if (!ast_opt_remote)
                unlink(ast_config_AST_PID);
+       if (sig_alert_pipe[0])
+               close(sig_alert_pipe[0]);
+       if (sig_alert_pipe[1])
+               close(sig_alert_pipe[1]);
        printf("%s", term_quit());
        if (restart) {
                int i;
@@ -2056,14 +2063,12 @@ static const char *fix_header(char *outbuf, int maxout, const char *s, char leve
 }
 
 struct console_state_data {
-       int newline;
        char verbose_line_level;
 };
 
 static int console_state_init(void *ptr)
 {
        struct console_state_data *state = ptr;
-       state->newline = 1;
        state->verbose_line_level = 0;
        return 0;
 }
@@ -2076,42 +2081,40 @@ AST_THREADSTORAGE_CUSTOM(console_state, console_state_init, ast_free_ptr);
 #define VERBOSE_MAGIC2LEVEL(x) (((char) -*(signed char *) (x)) - 1)
 #define VERBOSE_HASMAGIC(x)    (*(signed char *) (x) < 0)
 
-static int console_log_verbose(const char *s)
+static int console_print(const char *s, int local)
 {
-       /* verbose level of 0 evaluates to a magic of -1, 1 to -2, etc...
-          search up to -7 (level = 6) as this is currently the largest
-          level used */
-       static const char find_set[9] = { -1, -2, -3, -4, -5, -6, -7, '\n'};
-
        struct console_state_data *state =
                ast_threadstorage_get(&console_state, sizeof(*state));
 
        char prefix[80];
-       const char *c = s;
-       int res = 0;
+       const char *c;
+       int num, res = 0;
+       unsigned int newline;
 
        do {
                if (VERBOSE_HASMAGIC(s)) {
-                       /* if it has one always use the given line's level,
-                          otherwise we'll use the last line's level */
+                       /* always use the given line's level, otherwise
+                          we'll use the last line's level */
                        state->verbose_line_level = VERBOSE_MAGIC2LEVEL(s);
                        /* move past magic */
                        s++;
-               }
-
-               c = fix_header(prefix, sizeof(prefix), s,
-                              state->verbose_line_level);
 
-               if (!state->newline) {
-                       /* don't use the prefix if line continuation */
+                       if (local) {
+                               s = fix_header(prefix, sizeof(prefix), s,
+                                              state->verbose_line_level);
+                       }
+               } else {
                        *prefix = '\0';
                }
+               c = s;
 
-               /* for a given line separate on verbose magic and newlines */
-               if (!(s = strpbrk(c, find_set))) {
-                       s = strchr(c, '\0');
-               } else if (*s == '\n') {
+               /* for a given line separate on verbose magic, newline, and eol */
+               if ((s = strchr(c, '\n'))) {
                        ++s;
+                       newline = 1;
+               } else {
+                       s = strchr(c, '\0');
+                       newline = 0;
                }
 
                /* check if we should write this line after calculating begin/end
@@ -2121,21 +2124,28 @@ static int console_log_verbose(const char *s)
                        continue;
                }
 
-               state->newline = *(s - 1) == '\n';
-               if (!ast_strlen_zero(prefix)) {
+               if (local && !ast_strlen_zero(prefix)) {
                        fputs(prefix, stdout);
                }
 
-               fwrite(c, sizeof(char), s - c, stdout);
+               num = s - c;
+               if (fwrite(c, sizeof(char), num, stdout) < num) {
+                       break;
+               }
 
                if (!res) {
                        /* if at least some info has been written
                           we'll want to return true */
                        res = 1;
                }
-               c = s;
        } while (*s);
 
+       if (newline) {
+               /* if ending on a newline then reset last level to zero
+                   since what follows may be not be logging output */
+               state->verbose_line_level = 0;
+       }
+
        if (res) {
                fflush(stdout);
        }
@@ -2145,7 +2155,7 @@ static int console_log_verbose(const char *s)
 
 static void console_verboser(const char *s)
 {
-       if (!console_log_verbose(s)) {
+       if (!console_print(s, 1)) {
                return;
        }
 
@@ -2632,7 +2642,7 @@ static int ast_el_read_char(EditLine *editline, char *cp)
                                }
                        }
 
-                       console_log_verbose(buf);
+                       console_print(buf, 0);
 
                        if ((res < EL_BUF_SIZE - 1) && ((buf[res-1] == '\n') || (buf[res-2] == '\n'))) {
                                *cp = CC_REFRESH;
@@ -2774,45 +2784,62 @@ static char *cli_prompt(EditLine *editline)
        return ast_str_buffer(prompt);
 }
 
+static void destroy_match_list(char **match_list, int matches)
+{
+       if (match_list) {
+               int idx;
+
+               for (idx = 0; idx < matches; ++idx) {
+                       ast_free(match_list[idx]);
+               }
+               ast_free(match_list);
+       }
+}
+
 static char **ast_el_strtoarr(char *buf)
 {
-       char **match_list = NULL, **match_list_tmp, *retstr;
-       size_t match_list_len;
+       char *retstr;
+       char **match_list = NULL;
+       char **new_list;
+       size_t match_list_len = 1;
        int matches = 0;
 
-       match_list_len = 1;
-       while ( (retstr = strsep(&buf, " ")) != NULL) {
-
-               if (!strcmp(retstr, AST_CLI_COMPLETE_EOF))
+       while ((retstr = strsep(&buf, " "))) {
+               if (!strcmp(retstr, AST_CLI_COMPLETE_EOF)) {
                        break;
+               }
                if (matches + 1 >= match_list_len) {
                        match_list_len <<= 1;
-                       if ((match_list_tmp = ast_realloc(match_list, match_list_len * sizeof(char *)))) {
-                               match_list = match_list_tmp;
-                       } else {
-                               if (match_list)
-                                       ast_free(match_list);
-                               return (char **) NULL;
+                       new_list = ast_realloc(match_list, match_list_len * sizeof(char *));
+                       if (!new_list) {
+                               destroy_match_list(match_list, matches);
+                               return NULL;
                        }
+                       match_list = new_list;
                }
 
-               match_list[matches++] = ast_strdup(retstr);
+               retstr = ast_strdup(retstr);
+               if (!retstr) {
+                       destroy_match_list(match_list, matches);
+                       return NULL;
+               }
+               match_list[matches++] = retstr;
        }
 
-       if (!match_list)
-               return (char **) NULL;
+       if (!match_list) {
+               return NULL;
+       }
 
        if (matches >= match_list_len) {
-               if ((match_list_tmp = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) {
-                       match_list = match_list_tmp;
-               } else {
-                       if (match_list)
-                               ast_free(match_list);
-                       return (char **) NULL;
+               new_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *));
+               if (!new_list) {
+                       destroy_match_list(match_list, matches);
+                       return NULL;
                }
+               match_list = new_list;
        }
 
-       match_list[matches] = (char *) NULL;
+       match_list[matches] = NULL;
 
        return match_list;
 }
@@ -2913,7 +2940,9 @@ static char *cli_complete(EditLine *editline, int ch)
 
                if (nummatches > 0) {
                        char *mbuf;
+                       char *new_mbuf;
                        int mlen = 0, maxmbuf = 2048;
+
                        /* Start with a 2048 byte buffer */
                        if (!(mbuf = ast_malloc(maxmbuf))) {
                                *((char *) lf->cursor) = savechr;
@@ -2927,10 +2956,13 @@ static char *cli_complete(EditLine *editline, int ch)
                                if (mlen + 1024 > maxmbuf) {
                                        /* Every step increment buffer 1024 bytes */
                                        maxmbuf += 1024;
-                                       if (!(mbuf = ast_realloc(mbuf, maxmbuf))) {
+                                       new_mbuf = ast_realloc(mbuf, maxmbuf);
+                                       if (!new_mbuf) {
+                                               ast_free(mbuf);
                                                *((char *) lf->cursor) = savechr;
                                                return (char *)(CC_ERROR);
                                        }
+                                       mbuf = new_mbuf;
                                }
                                /* Only read 1024 bytes at a time */
                                res = read(ast_consock, mbuf + mlen, 1024);
@@ -4315,6 +4347,11 @@ int main(int argc, char *argv[])
 
        ast_channels_init();
 
+       if (ast_endpoint_init()) {
+               printf ("%s", term_quit());
+               exit(1);
+       }
+
        if ((moduleresult = load_modules(1))) {         /* Load modules, pre-load only */
                printf("%s", term_quit());
                exit(moduleresult == -2 ? 2 : 1);