Fixed exit on Ctrl+C (SIGINT).

This commit is contained in:
ha7ilm 2015-12-02 23:33:35 +01:00
parent c9406d38c9
commit 4800710443
3 changed files with 54 additions and 17 deletions

16
csdr.c
View file

@ -169,6 +169,22 @@ int init_fifo(int argc, char *argv[])
fcntl(fd, F_SETFL, flags | O_NONBLOCK); fcntl(fd, F_SETFL, flags | O_NONBLOCK);
return fd; return fd;
} }
else if(!strcmp(argv[2],"--fd"))
{
//to use this:
//1. Create a pipe(pipedesc) in your process.
//2. fork() and execl() your process to run csdr, and give pipedesc[0] as parameter after --fd
// Note: when forking, the child process will get a copy of the file descriptor table! That's why this
// works at all, as file descriptor indexes are normally not transferable between processes, except for a *NIX socket way which is quite complicated...
//3. From your parent process, write into pipedesc[1].
//This is implemented in ddcd, check there to see how to do it!
int fd;
if(sscanf(argv[3], "%d",&fd)<=0) return 0;
fprintf(stderr,"csdr: fd control mode on, fd=%d\n", fd);
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
return fd;
}
} }
return 0; return 0;
} }

View file

@ -45,9 +45,12 @@ int in_client = 0;
char ddc_method_str[100] = "td"; char ddc_method_str[100] = "td";
ddc_method_t ddc_method; ddc_method_t ddc_method;
pid_t main_dsp_proc; pid_t main_dsp_proc;
pid_t pgrp;
int input_fd = STDIN_FILENO; //can be stdin, or the stdout of main_subprocess int input_fd = STDIN_FILENO; //can be stdin, or the stdout of main_subprocess
pid_t main_subprocess_pid = 0; pid_t main_subprocess_pid = 0;
pid_t main_subprocess_pgrp = 0;
pid_t client_subprocess_pid = 0;
pid_t client_subprocess_pgrp = 0;
char* buf; char* buf;
@ -69,14 +72,21 @@ int proc_exists(pid_t pid)
void sig_handler(int signo) void sig_handler(int signo)
{ {
int tmpstat; int tmpstat;
if(signo==SIGPIPE)
{
fprintf(stderr,MSG_START "SIGPIPE received.\n");
return;
}
if(signo==SIGCHLD) if(signo==SIGCHLD)
if( main_subprocess_pid && signo==SIGCHLD && (waitpid(main_subprocess_pid, &tmpstat, WNOHANG), 1) && !proc_exists(main_subprocess_pid) ) if( main_subprocess_pid && signo==SIGCHLD && (waitpid(main_subprocess_pid, &tmpstat, WNOHANG), 1) && !proc_exists(main_subprocess_pid) )
{ {
fprintf(stderr,MSG_START "main_subprocess_pid exited! Exiting...\n"); fprintf(stderr,MSG_START "main_subprocess_pid exited! Exiting...\n");
} }
else return; else return;
if(pgrp!=1 && pgrp!=0) //I just want to make sure that we cannot kill init or sched //if(pgrp!=1 && pgrp!=0) //I just want to make sure that we cannot kill init or sched
killpg(pgrp, signo); // killpg(pgrp, signo);
if( !in_client && main_subprocess_pid ) killpg2(main_subprocess_pgrp);
if( in_client && client_subprocess_pid ) killpg2(client_subprocess_pgrp);
fprintf(stderr, MSG_START "signal %d caught in %s, exiting ddcd...\n", signo, (in_client)?"client":"main"); fprintf(stderr, MSG_START "signal %d caught in %s, exiting ddcd...\n", signo, (in_client)?"client":"main");
fflush(stderr); fflush(stderr);
exit(0); exit(0);
@ -161,7 +171,7 @@ int main(int argc, char* argv[])
sigaction(SIGINT, &sa, NULL); sigaction(SIGINT, &sa, NULL);
sigaction(SIGHUP, &sa, NULL); sigaction(SIGHUP, &sa, NULL);
sigaction(SIGCHLD, &sa, NULL); sigaction(SIGCHLD, &sa, NULL);
//sigaction(SIGPIPE, &sa, NULL); sigaction(SIGPIPE, &sa, NULL);
prctl(PR_SET_PDEATHSIG, SIGHUP); //get a signal when parent exits prctl(PR_SET_PDEATHSIG, SIGHUP); //get a signal when parent exits
struct sockaddr_in addr_host; struct sockaddr_in addr_host;
@ -214,8 +224,9 @@ int main(int argc, char* argv[])
} }
//We'll see if it is a good idea: //We'll see if it is a good idea:
setpgrp(); //setpgrp();
pgrp = getpgrp(); //pgrp = getpgrp();
//It is not, because we can't catch Ctrl+C (SIGINT), as it is sent to a process group...
//Start DSP subprocess from the main process if required //Start DSP subprocess from the main process if required
char main_subprocess_cmd_buf[500]; char main_subprocess_cmd_buf[500];
@ -236,7 +247,7 @@ int main(int argc, char* argv[])
case M_FASTDDC: case M_FASTDDC:
sprintf(main_subprocess_cmd_buf, subprocess_args_fastddc_1, decimation, transition_bw); sprintf(main_subprocess_cmd_buf, subprocess_args_fastddc_1, decimation, transition_bw);
fprintf(stderr, MSG_START "starting main_subprocess_cmd: %s\n", main_subprocess_cmd_buf); fprintf(stderr, MSG_START "starting main_subprocess_cmd: %s\n", main_subprocess_cmd_buf);
if(!(main_subprocess_pid = run_subprocess( main_subprocess_cmd_buf, 0, pipe_s2m ))) if(!(main_subprocess_pid = run_subprocess( main_subprocess_cmd_buf, 0, pipe_s2m, &main_subprocess_pgrp )))
print_exit(MSG_START "couldn't start main_subprocess_cmd!\n"); print_exit(MSG_START "couldn't start main_subprocess_cmd!\n");
close(STDIN_FILENO); // redirect stdin to the stdin of the subprocess close(STDIN_FILENO); // redirect stdin to the stdin of the subprocess
break; break;
@ -322,7 +333,7 @@ int main(int argc, char* argv[])
close(clients[i]->socket); close(clients[i]->socket);
delete clients[i]; delete clients[i];
clients.erase(clients.begin()+i); clients.erase(clients.begin()+i);
print_client(clients[i], "done closing client from main process."); fprintf(stderr, MSG_START "done closing client from main process.");
} }
} }
else { if(clients[i]->error) print_client(clients[i], "pipe okay again."); clients[i]->error=0; } else { if(clients[i]->error) print_client(clients[i], "pipe okay again."); clients[i]->error=0; }
@ -334,9 +345,14 @@ int main(int argc, char* argv[])
return 0; return 0;
} }
pid_t run_subprocess(char* cmd, int* pipe_in, int* pipe_out) pid_t run_subprocess(char* cmd, int* pipe_in, int* pipe_out, pid_t* pgrp)
{ {
pid_t pid = fork(); pid_t pid = fork();
if(*pgrp>=0)
{
setpgrp();
*pgrp = getpgrp();
}
//fprintf(stderr, "run_subprocess :: fork-ed %d\n", pid); //fprintf(stderr, "run_subprocess :: fork-ed %d\n", pid);
if(pid < 0) return 0; //fork failed if(pid < 0) return 0; //fork failed
if(pid == 0) if(pid == 0)
@ -376,7 +392,6 @@ void client()
print_client(this_client, "client process forked."); print_client(this_client, "client process forked.");
char client_subprocess_cmd_buf[500]; char client_subprocess_cmd_buf[500];
pid_t client_subprocess_pid = 0;
int input_fd = this_client->pipefd[0]; int input_fd = this_client->pipefd[0];
prctl(PR_SET_PDEATHSIG, SIGHUP); //get a signal when parent exits prctl(PR_SET_PDEATHSIG, SIGHUP); //get a signal when parent exits
@ -395,13 +410,13 @@ void client()
sprintf(client_subprocess_cmd_buf, subprocess_args_fastddc_2, decimation, pipe_ctl[0], transition_bw); sprintf(client_subprocess_cmd_buf, subprocess_args_fastddc_2, decimation, pipe_ctl[0], transition_bw);
break; break;
} }
if(!(client_subprocess_pid = run_subprocess( client_subprocess_cmd_buf, this_client->pipefd, pipe_stdout )))
if(!(client_subprocess_pid = run_subprocess( client_subprocess_cmd_buf, this_client->pipefd, pipe_stdout, &client_subprocess_pgrp)))
print_exit(MSG_START "couldn't start client_subprocess_cmd!\n"); print_exit(MSG_START "couldn't start client_subprocess_cmd!\n");
fprintf(stderr, MSG_START "starting client_subprocess_cmd: %s\n", client_subprocess_cmd_buf); fprintf(stderr, MSG_START "starting client_subprocess_cmd: %s\n", client_subprocess_cmd_buf);
input_fd = pipe_stdout[0]; //we don't have to set it nonblocking input_fd = pipe_stdout[0]; //we don't have to set it nonblocking
fprintf(stderr, MSG_START "pipe_stdout[0] = %d\n", pipe_stdout[0]); fprintf(stderr, MSG_START "pipe_stdout[0] = %d\n", pipe_stdout[0]);
setpgrp(); write(pipe_ctl[1], "0.0\n", 4);
pgrp = getpgrp();
} }
for(;;) for(;;)
{ {
@ -409,12 +424,17 @@ void client()
if(send(this_client->socket,buf,bufsizeall,0)==-1) if(send(this_client->socket,buf,bufsizeall,0)==-1)
{ {
print_client(this_client, "client process is exiting."); print_client(this_client, "client process is exiting.");
if(client_subprocess_pid && pgrp!=1 && pgrp!=0) killpg(pgrp, SIGTERM); if(client_subprocess_pid) killpg2(client_subprocess_pgrp);
exit(0); exit(0);
} }
} }
} }
void killpg2(pid_t pgrp)
{
if(pgrp!=1 && pgrp!=0) killpg(pgrp, SIGTERM);
}
void error_exit(const char* why) void error_exit(const char* why)
{ {
perror(why); perror(why);

7
ddcd.h
View file

@ -33,9 +33,10 @@ void error_exit(const char* why);
void print_exit(const char* why); void print_exit(const char* why);
void print_client(client_t* client, const char* what); void print_client(client_t* client, const char* what);
int proc_exists(pid_t pid); int proc_exists(pid_t pid);
pid_t run_subprocess(char* cmd, int* pipe_in, int* pipe_out); pid_t run_subprocess(char* cmd, int* pipe_in, int* pipe_out, pid_t* pgrp);
void maxfd(int* maxfd, int fd); void maxfd(int* maxfd, int fd);
void sig_handler(int signo); void sig_handler(int signo);
void killpg2(pid_t pgrp);
typedef enum ddc_method_e typedef enum ddc_method_e
{ {
@ -49,9 +50,9 @@ const char subprocess_cmd_td[] = "csdr "
#else #else
"shift_unroll_cc" "shift_unroll_cc"
#endif #endif
" --pipe %d | csdr fir_decimate_cc %d %g"; " --fd %d | csdr fir_decimate_cc %d %g";
const char subprocess_args_fastddc_1[] = "csdr through %d %g";
//const char subprocess_args_fastddc_1[] = "csdr fastddc_fwd_cc %d %g"; //const char subprocess_args_fastddc_1[] = "csdr fastddc_fwd_cc %d %g";
const char subprocess_args_fastddc_1[] = "csdr through %d %g";
//const char subprocess_args_fastddc_2[] = "csdr fastddc_inv_cc %d --pipe %d %g"; //const char subprocess_args_fastddc_2[] = "csdr fastddc_inv_cc %d --pipe %d %g";
const char subprocess_args_fastddc_2[] = "csdr convert_u8_f %d %d %g"; const char subprocess_args_fastddc_2[] = "csdr convert_u8_f %d %d %g";