X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=src%2Fexec.c;h=d56c07fa9b2180d86624ff73d7b183fdbb909c66;hp=dd295e98a323cd806f1072ad814e7bb47af8fee3;hb=633c3966f770e4d46651a2fe219a18d8a9907a9f;hpb=5abe911631a15dd312d83db92c9dd9da9f13c9df diff --git a/src/exec.c b/src/exec.c index dd295e98..d56c07fa 100644 --- a/src/exec.c +++ b/src/exec.c @@ -18,7 +18,7 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: - * Florian octo Forster + * Florian octo Forster * Sebastian Harl * Peter Holik **/ @@ -270,13 +270,15 @@ static void set_environment (void) /* {{{ */ char buffer[1024]; #ifdef HAVE_SETENV - ssnprintf (buffer, sizeof (buffer), "%i", interval_g); + ssnprintf (buffer, sizeof (buffer), "%.3f", + CDTIME_T_TO_DOUBLE (plugin_get_interval ())); setenv ("COLLECTD_INTERVAL", buffer, /* overwrite = */ 1); ssnprintf (buffer, sizeof (buffer), "%s", hostname_g); setenv ("COLLECTD_HOSTNAME", buffer, /* overwrite = */ 1); #else - ssnprintf (buffer, sizeof (buffer), "COLLECTD_INTERVAL=%i", interval_g); + ssnprintf (buffer, sizeof (buffer), "COLLECTD_INTERVAL=%.3f", + CDTIME_T_TO_DOUBLE (plugin_get_interval ())); putenv (buffer); ssnprintf (buffer, sizeof (buffer), "COLLECTD_HOSTNAME=%s", hostname_g); @@ -285,71 +287,11 @@ static void set_environment (void) /* {{{ */ } /* }}} void set_environment */ __attribute__((noreturn)) -static void exec_child (program_list_t *pl) /* {{{ */ +static void exec_child (program_list_t *pl, int uid, int gid, int egid) /* {{{ */ { int status; - int uid; - int gid; - int egid; - - struct passwd *sp_ptr; - struct passwd sp; - char nambuf[2048]; char errbuf[1024]; - sp_ptr = NULL; - status = getpwnam_r (pl->user, &sp, nambuf, sizeof (nambuf), &sp_ptr); - if (status != 0) - { - ERROR ("exec plugin: Failed to get user information for user ``%s'': %s", - pl->user, sstrerror (errno, errbuf, sizeof (errbuf))); - exit (-1); - } - if (sp_ptr == NULL) - { - ERROR ("exec plugin: No such user: `%s'", pl->user); - exit (-1); - } - - uid = sp.pw_uid; - gid = sp.pw_gid; - if (uid == 0) - { - ERROR ("exec plugin: Cowardly refusing to exec program as root."); - exit (-1); - } - - /* The group configured in the configfile is set as effective group, because - * this way the forked process can (re-)gain the user's primary group. */ - egid = -1; - if (NULL != pl->group) - { - if ('\0' != *pl->group) { - struct group *gr_ptr = NULL; - struct group gr; - - status = getgrnam_r (pl->group, &gr, nambuf, sizeof (nambuf), &gr_ptr); - if (0 != status) - { - ERROR ("exec plugin: Failed to get group information " - "for group ``%s'': %s", pl->group, - sstrerror (errno, errbuf, sizeof (errbuf))); - exit (-1); - } - if (NULL == gr_ptr) - { - ERROR ("exec plugin: No such group: `%s'", pl->group); - exit (-1); - } - - egid = gr.gr_gid; - } - else - { - egid = gid; - } - } /* if (pl->group == NULL) */ - #if HAVE_SETGROUPS if (getuid () == 0) { @@ -427,6 +369,14 @@ static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err) int status; int pid; + int uid; + int gid; + int egid; + + struct passwd *sp_ptr; + struct passwd sp; + char nambuf[2048]; + if (pl->pid != 0) return (-1); @@ -454,6 +404,59 @@ static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err) return (-1); } + sp_ptr = NULL; + status = getpwnam_r (pl->user, &sp, nambuf, sizeof (nambuf), &sp_ptr); + if (status != 0) + { + ERROR ("exec plugin: Failed to get user information for user ``%s'': %s", + pl->user, sstrerror (errno, errbuf, sizeof (errbuf))); + return (-1); + } + if (sp_ptr == NULL) + { + ERROR ("exec plugin: No such user: `%s'", pl->user); + return (-1); + } + + uid = sp.pw_uid; + gid = sp.pw_gid; + if (uid == 0) + { + ERROR ("exec plugin: Cowardly refusing to exec program as root."); + return (-1); + } + + /* The group configured in the configfile is set as effective group, because + * this way the forked process can (re-)gain the user's primary group. */ + egid = -1; + if (NULL != pl->group) + { + if ('\0' != *pl->group) { + struct group *gr_ptr = NULL; + struct group gr; + + status = getgrnam_r (pl->group, &gr, nambuf, sizeof (nambuf), &gr_ptr); + if (0 != status) + { + ERROR ("exec plugin: Failed to get group information " + "for group ``%s'': %s", pl->group, + sstrerror (errno, errbuf, sizeof (errbuf))); + return (-1); + } + if (NULL == gr_ptr) + { + ERROR ("exec plugin: No such group: `%s'", pl->group); + return (-1); + } + + egid = gr.gr_gid; + } + else + { + egid = gid; + } + } /* if (pl->group == NULL) */ + pid = fork (); if (pid < 0) { @@ -491,7 +494,7 @@ static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err) close (fd_pipe_out[1]); } - /* Now connect the `out' pipe to STDOUT */ + /* Now connect the `err' pipe to STDERR */ if (fd_pipe_err[1] != STDERR_FILENO) { dup2 (fd_pipe_err[1], STDERR_FILENO); @@ -503,7 +506,7 @@ static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err) /* Unblock all signals */ reset_signal_mask (); - exec_child (pl); + exec_child (pl, uid, gid, egid); /* does not return */ } @@ -537,12 +540,9 @@ static int parse_line (char *buffer) /* {{{ */ return (handle_putnotif (stdout, buffer)); else { - /* For backwards compatibility */ - char tmp[1220]; - /* Let's annoy the user a bit.. */ - INFO ("exec plugin: Prepending `PUTVAL' to this line: %s", buffer); - ssnprintf (tmp, sizeof (tmp), "PUTVAL %s", buffer); - return (handle_putval (stdout, tmp)); + ERROR ("exec plugin: Unable to parse command, ignoring line: \"%s\"", + buffer); + return (-1); } } /* int parse_line }}} */ @@ -637,17 +637,22 @@ static void *exec_read_one (void *arg) /* {{{ */ if (len < 0) { - if (errno == EAGAIN || errno == EINTR) continue; + if (errno == EAGAIN || errno == EINTR) + continue; break; } else if (len == 0) { /* We've reached EOF */ - NOTICE ("exec plugin: Program `%s' has closed STDERR.", - pl->exec); - close (fd_err); + NOTICE ("exec plugin: Program `%s' has closed STDERR.", pl->exec); + + /* Remove file descriptor form select() set. */ FD_CLR (fd_err, &fdset); + copy = fdset; highest_fd = fd; + + /* Clean up file descriptor */ + close (fd_err); fd_err = -1; continue; } @@ -739,8 +744,8 @@ static void *exec_notification_one (void *arg) /* {{{ */ fprintf (fh, "Severity: %s\n" - "Time: %u\n", - severity, (unsigned int) n->time); + "Time: %.3f\n", + severity, CDTIME_T_TO_DOUBLE (n->time)); /* Print the optional fields */ if (strlen (n->host) > 0) @@ -823,7 +828,7 @@ static int exec_read (void) /* {{{ */ pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); - pthread_create (&t, &attr, exec_read_one, (void *) pl); + plugin_thread_create (&t, &attr, exec_read_one, (void *) pl); pthread_attr_destroy (&attr); } /* for (pl) */ @@ -867,7 +872,7 @@ static int exec_notification (const notification_t *n, /* {{{ */ pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); - pthread_create (&t, &attr, exec_notification_one, (void *) pln); + plugin_thread_create (&t, &attr, exec_notification_one, (void *) pln); pthread_attr_destroy (&attr); } /* for (pl) */