POSIX forbids calling functions which are not thread-safe like
setenv() after fork() in multi-threaded programs. It happens to
work just fine with some libc implementations, but it causes a
deadlock in the child process with uClibc for example.
The proper way to pass new environment variables to the child
process is to update parent's environment before the fork(), so
that the child inherits the updated environment and then undo the
changes in the parent process again.
Signed-off-by: Florian Forster <octo@collectd.org>
#endif
} /* }}} void set_environment */
#endif
} /* }}} void set_environment */
+static void unset_environment(void) /* {{{ */
+{
+#ifdef HAVE_SETENV
+ unsetenv("COLLECTD_INTERVAL");
+ unsetenv("COLLECTD_HOSTNAME");
+#else
+ snprintf(env_interval, sizeof(env_interval), "COLLECTD_INTERVAL");
+ putenv(env_interval);
+ snprintf(env_hostname, sizeof(env_hostname), "COLLECTD_HOSTNAME");
+ putenv(env_hostname);
+#endif
+} /* }}} void unset_environment */
+
__attribute__((noreturn)) static void exec_child(program_list_t *pl, int uid,
int gid, int egid) /* {{{ */
{
__attribute__((noreturn)) static void exec_child(program_list_t *pl, int uid,
int gid, int egid) /* {{{ */
{
pid = fork();
if (pid < 0) {
ERROR("exec plugin: fork failed: %s",
pid = fork();
if (pid < 0) {
ERROR("exec plugin: fork failed: %s",
/* Unblock all signals */
reset_signal_mask();
/* Unblock all signals */
reset_signal_mask();
close(fd_pipe_in[0]);
close(fd_pipe_out[1]);
close(fd_pipe_err[1]);
close(fd_pipe_in[0]);
close(fd_pipe_out[1]);
close(fd_pipe_err[1]);
close_pipe(fd_pipe_in);
close_pipe(fd_pipe_out);
close_pipe(fd_pipe_err);
close_pipe(fd_pipe_in);
close_pipe(fd_pipe_out);
close_pipe(fd_pipe_err);