mirror of
https://github.com/sogou/workflow.git
synced 2026-02-08 01:33:17 +08:00
131 lines
2.4 KiB
C
131 lines
2.4 KiB
C
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/socket.h>
|
|
#include <netdb.h>
|
|
#include <signal.h>
|
|
|
|
int flag = 0;
|
|
|
|
void sig_handler(int signo)
|
|
{
|
|
if (signo == SIGUSR1)
|
|
flag = 1;
|
|
else if (signo == SIGINT || signo == SIGTERM)
|
|
flag = 2;
|
|
}
|
|
|
|
int main(int argc, const char *argv[])
|
|
{
|
|
if (argc != 3)
|
|
{
|
|
fprintf(stderr, "USAGE: %s EXEC_PROCESS PORT\n"
|
|
"Bootstrap for workflow server to restart gracefully.\n",
|
|
argv[0]);
|
|
exit(1);
|
|
}
|
|
|
|
unsigned short port = atoi(argv[2]);
|
|
int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
|
|
struct sockaddr_in sin;
|
|
|
|
memset(&sin, 0, sizeof sin);
|
|
sin.sin_family = AF_INET;
|
|
sin.sin_port = htons(port);
|
|
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
if (bind(listen_fd, (struct sockaddr *)&sin, sizeof sin) < 0)
|
|
{
|
|
close(listen_fd);
|
|
perror("bind error");
|
|
exit(1);
|
|
}
|
|
|
|
pid_t pid;
|
|
int pipe_fd[2];
|
|
ssize_t len;
|
|
char buf[100];
|
|
int status;
|
|
int ret;
|
|
|
|
char listen_fd_str[10] = { 0 };
|
|
char write_fd_str[10] = { 0 };
|
|
sprintf(listen_fd_str, "%d", listen_fd);
|
|
|
|
signal(SIGINT, sig_handler);
|
|
signal(SIGTERM, sig_handler);
|
|
signal(SIGUSR1, sig_handler);
|
|
|
|
while (flag < 2)
|
|
{
|
|
if (pipe(pipe_fd) == -1)
|
|
{
|
|
perror("open pipe error");
|
|
exit(1);
|
|
}
|
|
|
|
memset(write_fd_str, 0, sizeof write_fd_str);
|
|
sprintf(write_fd_str, "%d", pipe_fd[1]);
|
|
|
|
pid = fork();
|
|
if (pid < 0)
|
|
{
|
|
perror("fork error");
|
|
close(pipe_fd[0]);
|
|
close(pipe_fd[1]);
|
|
break;
|
|
}
|
|
else if (pid == 0)
|
|
{
|
|
close(pipe_fd[0]);
|
|
execlp(argv[1], argv[1], listen_fd_str, write_fd_str, NULL);
|
|
}
|
|
else
|
|
{
|
|
close(pipe_fd[1]);
|
|
|
|
status = 0;
|
|
ret = 0;
|
|
flag = 0;
|
|
fprintf(stderr, "Bootstrap daemon running with server pid-%d. "
|
|
"Send SIGUSR1 to RESTART or SIGTERM to STOP.\n", pid);
|
|
|
|
while (1)
|
|
{
|
|
ret = waitpid(pid, &status, WNOHANG);
|
|
if (ret == -1 || !WIFEXITED(status) || flag != 0)
|
|
break;
|
|
|
|
sleep(3);
|
|
}
|
|
|
|
if (ret != -1 && WIFEXITED(status))
|
|
{
|
|
signal(SIGCHLD, SIG_IGN);
|
|
|
|
kill(pid, SIGUSR1);
|
|
fprintf(stderr, "Bootstrap daemon SIGUSR1 to pid-%ld %sing.\n",
|
|
(long)pid, flag == 1 ? "restart" : "stop");
|
|
|
|
len = read(pipe_fd[0], buf, 7);
|
|
fprintf(stderr, "Bootstrap server served %*s.\n", (int)len, buf);
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "child exit. status = %d, waitpid ret = %d\n",
|
|
WEXITSTATUS(status), ret);
|
|
flag = 2;
|
|
}
|
|
|
|
close(pipe_fd[0]);
|
|
}
|
|
}
|
|
|
|
close(listen_fd);
|
|
return 0;
|
|
}
|
|
|