static void spawn_haproxy(char **pid_strv, int nb_pid) { char haproxy_bin[512]; pid_t pid; int main_argc; char **main_argv; main_argc = wrapper_argc - 1; main_argv = wrapper_argv + 1; //pid = fork(); pid=0; if (!pid) { /* 3 for "haproxy -Ds -sf" */ char **argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *)); int i; int argno = 0; locate_haproxy(haproxy_bin, 512); argv[argno++] = haproxy_bin; for (i = 0; i < main_argc; ++i) argv[argno++] = main_argv[i]; argv[argno++] = "-Ds"; if (nb_pid > 0) { argv[argno++] = "-sf"; for (i = 0; i < nb_pid; ++i) argv[argno++] = pid_strv[i]; } argv[argno] = NULL; fprintf(stderr, SD_DEBUG "haproxy-systemd-wrapper: executing "); for (i = 0; argv[i]; ++i) fprintf(stderr, "%s ", argv[i]); fprintf(stderr, "\n"); execv(argv[0], argv); exit(0); } }
/* Note: this function must not exit in case of error (except in the child), as * it is only dedicated the starting a new haproxy process. By keeping the * process alive it will ensure that future signal delivery may get rid of * the issue. If the first startup fails, the wrapper will notice it and * return an error thanks to wait() returning ECHILD. */ static void spawn_haproxy(char **pid_strv, int nb_pid) { char haproxy_bin[512]; pid_t pid; int main_argc; char **main_argv; int pipefd[2]; char fdstr[20]; int ret; main_argc = wrapper_argc - 1; main_argv = wrapper_argv + 1; if (pipe(pipefd) != 0) { fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: failed to create a pipe, please try again later.\n"); return; } pid = fork(); if (!pid) { char **argv; int i; int argno = 0; /* 3 for "haproxy -Ds -sf" */ argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *)); if (!argv) { fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: failed to calloc(), please try again later.\n"); exit(1); } reset_signal_handler(); close(pipefd[0]); /* close the read side */ snprintf(fdstr, sizeof(fdstr), "%d", pipefd[1]); if (setenv("HAPROXY_WRAPPER_FD", fdstr, 1) != 0) { fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: failed to setenv(), please try again later.\n"); exit(1); } locate_haproxy(haproxy_bin, 512); argv[argno++] = haproxy_bin; for (i = 0; i < main_argc; ++i) argv[argno++] = main_argv[i]; argv[argno++] = "-Ds"; if (nb_pid > 0) { argv[argno++] = "-sf"; for (i = 0; i < nb_pid; ++i) argv[argno++] = pid_strv[i]; } argv[argno] = NULL; fprintf(stderr, SD_DEBUG "haproxy-systemd-wrapper: executing "); for (i = 0; argv[i]; ++i) fprintf(stderr, "%s ", argv[i]); fprintf(stderr, "\n"); execv(argv[0], argv); fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: execv(%s) failed, please try again later.\n", argv[0]); exit(1); } else if (pid == -1) { fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: failed to fork(), please try again later.\n"); } /* The parent closes the write side and waits for the child to close it * as well. Also deal the case where the fd would unexpectedly be 1 or 2 * by silently draining all data. */ close(pipefd[1]); do { char c; ret = read(pipefd[0], &c, sizeof(c)); } while ((ret > 0) || (ret == -1 && errno == EINTR)); /* the child has finished starting up */ close(pipefd[0]); }