Merge pull request #1816 from octo/grpc-free-iter
[collectd.git] / src / processes.c
index 8e2443b..f029a6c 100644 (file)
 #  undef SAVE_FOB_64
 #endif
 
+# include <sys/user.h>
 # include <dirent.h>
+
+#ifndef MAXCOMLEN
+#  define MAXCOMLEN 16
+#endif
+
 /* #endif KERNEL_SOLARIS */
 
 #else
@@ -262,20 +268,19 @@ static void ps_list_register (const char *name, const char *regexp)
        procstat_t *ptr;
        int status;
 
-       new = (procstat_t *) malloc (sizeof (procstat_t));
+       new = calloc (1, sizeof (*new));
        if (new == NULL)
        {
-               ERROR ("processes plugin: ps_list_register: malloc failed.");
+               ERROR ("processes plugin: ps_list_register: calloc failed.");
                return;
        }
-       memset (new, 0, sizeof (procstat_t));
        sstrncpy (new->name, name, sizeof (new->name));
 
 #if HAVE_REGEX_H
        if (regexp != NULL)
        {
                DEBUG ("ProcessMatch: adding \"%s\" as criteria to process %s.", regexp, name);
-               new->re = (regex_t *) malloc (sizeof (regex_t));
+               new->re = malloc (sizeof (*new->re));
                if (new->re == NULL)
                {
                        ERROR ("processes plugin: ps_list_register: malloc failed.");
@@ -361,29 +366,25 @@ static int ps_list_match (const char *name, const char *cmdline, procstat_t *ps)
        return (0);
 } /* int ps_list_match */
 
-static void ps_update_counter (
-        _Bool init,
-        derive_t *group_counter,
-        derive_t *curr_counter, unsigned long *curr_value,
-        derive_t new_counter, unsigned long new_value) {
-    if (init)
-    {
-        *curr_value = new_value;
-        *curr_counter += new_value;
-        *group_counter += new_value;
-        return;
-    }
-
-    if (new_counter < *curr_counter)
-    {
-        *curr_value = new_counter + (ULONG_MAX - *curr_counter);
-    }
-    else
-    {
-        *curr_value = new_counter - *curr_counter;
-    }
-    *curr_counter = new_counter;
-    *group_counter += *curr_value;
+static void ps_update_counter (_Bool init, derive_t *group_counter,
+                               derive_t *curr_counter, unsigned long *curr_value,
+                               derive_t new_counter, unsigned long new_value)
+{
+       if (init)
+       {
+               *curr_value = new_value;
+               *curr_counter += new_value;
+               *group_counter += new_value;
+               return;
+       }
+
+       if (new_counter < *curr_counter)
+               *curr_value = new_counter + (ULONG_MAX - *curr_counter);
+       else
+               *curr_value = new_counter - *curr_counter;
+
+       *curr_counter = new_counter;
+       *group_counter += *curr_value;
 }
 
 /* add process entry to 'instances' of process 'name' (or refresh it) */
@@ -397,7 +398,7 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t
 
        for (ps = list_head_g; ps != NULL; ps = ps->next)
        {
-        _Bool want_init;
+               _Bool want_init;
 
                if ((ps_list_match (name, cmdline, ps)) == 0)
                        continue;
@@ -410,10 +411,9 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t
                {
                        procstat_entry_t *new;
 
-                       new = (procstat_entry_t *) malloc (sizeof (procstat_entry_t));
+                       new = calloc (1, sizeof (*new));
                        if (new == NULL)
                                return;
-                       memset (new, 0, sizeof (procstat_entry_t));
                        new->id = entry->id;
 
                        if (pse == NULL)
@@ -540,6 +540,12 @@ static int ps_config (oconfig_item_t *ci)
 {
        int i;
 
+#if KERNEL_LINUX
+       const size_t max_procname_len = 15;
+#elif KERNEL_SOLARIS || KERNEL_FREEBSD
+       const size_t max_procname_len = MAXCOMLEN -1;
+#endif
+
        for (i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *c = ci->children + i;
 
@@ -560,6 +566,15 @@ static int ps_config (oconfig_item_t *ci)
                                                c->children_num, c->values[0].value.string);
                        }
 
+#if KERNEL_LINUX || KERNEL_SOLARIS || KERNEL_FREEBSD
+                       if (strlen (c->values[0].value.string) > max_procname_len) {
+                               WARNING ("processes plugin: this platform has a %zu character limit "
+                                               "to process names. The `Process \"%s\"' option will "
+                                               "not work as expected.",
+                                               max_procname_len, c->values[0].value.string);
+                       }
+#endif
+
                        ps_list_register (c->values[0].value.string, NULL);
                }
                else if (strcasecmp (c->key, "ProcessMatch") == 0)
@@ -863,8 +878,8 @@ static procstat_t *ps_read_tasks_status (long pid, procstat_t *ps)
                if (fclose (fh))
                {
                        char errbuf[1024];
-                               WARNING ("processes: fclose: %s",
-                                       sstrerror (errno, errbuf, sizeof (errbuf)));
+                       WARNING ("processes: fclose: %s",
+                               sstrerror (errno, errbuf, sizeof (errbuf)));
                }
        }
        closedir (dh);
@@ -1040,13 +1055,11 @@ static int ps_read_process (long pid, procstat_t *ps, char *state)
         * strchr(3) and strrchr(3) to avoid pointer arithmetic which would
         * otherwise be required to determine name_len. */
        name_start_pos = 0;
-       while ((buffer[name_start_pos] != '(')
-                       && (name_start_pos < buffer_len))
+       while (name_start_pos < buffer_len && buffer[name_start_pos] != '(')
                name_start_pos++;
 
        name_end_pos = buffer_len;
-       while ((buffer[name_end_pos] != ')')
-                       && (name_end_pos > 0))
+       while (name_end_pos > 0 && buffer[name_end_pos] != ')')
                name_end_pos--;
 
        /* Either '(' or ')' is not found or they are in the wrong order.
@@ -1094,7 +1107,7 @@ static int ps_read_process (long pid, procstat_t *ps, char *state)
                        ps->vmem_code = -1;
                        DEBUG("ps_read_process: did not get vmem data for pid %li", pid);
                }
-               if (ps->num_lwp <= 0)
+               if (ps->num_lwp == 0)
                        ps->num_lwp = 1;
                ps->num_proc = 1;
        }
@@ -1218,7 +1231,7 @@ static char *ps_get_cmdline (long pid, char *name, char *buf, size_t buf_len)
                buf_ptr += status;
                len     -= status;
 
-               if (len <= 0)
+               if (len == 0)
                        break;
        }
 
@@ -1255,7 +1268,7 @@ static char *ps_get_cmdline (long pid, char *name, char *buf, size_t buf_len)
        return buf;
 } /* char *ps_get_cmdline (...) */
 
-static int read_fork_rate ()
+static int read_fork_rate (void)
 {
        FILE *proc_stat;
        char buffer[1024];
@@ -1348,18 +1361,15 @@ static int ps_read_process(long pid, procstat_t *ps, char *state)
        snprintf(f_usage, sizeof (f_usage), "/proc/%li/usage", pid);
 
 
-       buffer = malloc(sizeof (pstatus_t));
-       memset(buffer, 0, sizeof (pstatus_t));
+       buffer = calloc(1, sizeof (pstatus_t));
        read_file_contents(filename, buffer, sizeof (pstatus_t));
        myStatus = (pstatus_t *) buffer;
 
-       buffer = malloc(sizeof (psinfo_t));
-       memset(buffer, 0, sizeof(psinfo_t));
+       buffer = calloc(1, sizeof (psinfo_t));
        read_file_contents(f_psinfo, buffer, sizeof (psinfo_t));
        myInfo = (psinfo_t *) buffer;
 
-       buffer = malloc(sizeof (prusage_t));
-       memset(buffer, 0, sizeof(prusage_t));
+       buffer = calloc(1, sizeof (prusage_t));
        read_file_contents(f_usage, buffer, sizeof (prusage_t));
        myUsage = (prusage_t *) buffer;
 
@@ -1369,6 +1379,10 @@ static int ps_read_process(long pid, procstat_t *ps, char *state)
                ps->num_proc = 0;
                ps->num_lwp = 0;
                *state = (char) 'Z';
+
+               sfree(myStatus);
+               sfree(myInfo);
+               sfree(myUsage);
                return (0);
        } else {
                ps->num_proc = 1;
@@ -1450,7 +1464,7 @@ static int ps_read_process(long pid, procstat_t *ps, char *state)
  * are retrieved from kstat (module cpu, name sys, class misc, stat nthreads).
  * The result is the sum for all the threads created on each cpu
  */
-static int read_fork_rate()
+static int read_fork_rate (void)
 {
        extern kstat_ctl_t *kc;
        kstat_t *ksp_chain = NULL;