WTF? Defenetly smth else happens! I inserted true thread-safe code in child process
Code:
while(1)
{
for(i=0;i<arrsize(buf_i);i++)
buf_i[i]=i;
}
And child hangs inside this loop (i see that under debugger that i've attached to child)
After that i try to continue parent and nothing good happens. Interrupted system call inside strtoll() somewhere in other place of world.
Full code is:
Code:
#include "ice_system.h"
#include <stdio.h>
#include <unistd.h>
#ifdef ice_system_call_light_weight_shell_task_imlemented
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
static FILE *exec_file=NULL;
static const char *FileName="./ice_system_shell_task.sh";
static pid_t child_pid_or_zero_for_parent, parent_id;
static int EndChildProcess, ProcessContinued;
static char buf[256];
static int SendSignalToProcess(pid_t p_id, int sig_id)
{
if (kill(p_id, sig_id)==-1)
{
perror("SendSignalToProcess");
fprintf(stderr, "There was troubles trying to send signal %d to process %d\n", sig_id, p_id);
return 1;
}
return 0;
}
static inline void DoProceedChildProcess()
{
#ifdef debug
fprintf(stderr, "Task from file %s is about to proceed\n", FileName);
#endif
if (system(FileName)==-1)
perror("DoProceedChildProcess");
#ifdef debug
fprintf(stderr, "Task from file %s done\n", FileName);
#endif
}
static inline void ChildProcessSigHandler(int sg)
{
if (sg==SIGUSR1)
DoProceedChildProcess();
else //SIGTERM
EndChildProcess=1;
}
static inline void ParentProcessSigHandler(int sg)
{
ProcessContinued=1;
}
static inline int InitChildProcess()
{
//1) register signals
static sigset_t sset;
int v_signals[]={SIGTERM, SIGUSR1};
//
if (iceu_signals_set_signals(&sset, v_signals, arrsize(v_signals)))
return 1;
iceu_signals_init_signal_handler(&sset, &ChildProcessSigHandler);
return 0;
}
static inline void RunChildProcess()
{
int buf_i[1024], i;
//
while(!EndChildProcess)
{
while(1)
{
for(i=0;i<arrsize(buf_i);i++)
buf_i[i]=i;
}
pause();
SendSignalToProcess(parent_id, SIGUSR1); // child just waits until will not ended
}
snprintf(buf, sizeof(buf), "rm -f %s", FileName);
if (system(buf)==-1)
perror("ice_system_call_light_weight_shell_task_free. system:");
exit(0);
}
static inline int InitParentHandler()
{
static sigset_t sset;
int v_signals[]={SIGUSR1};
//
if (iceu_signals_set_signals(&sset, v_signals, arrsize(v_signals)))
return 1;
iceu_signals_init_signal_handler(&sset, &ParentProcessSigHandler);
return 0;
}
int ice_system_call_light_weight_shell_task_init()
{
// 1)
if ((exec_file=iceu_system_safely_open_file(FileName, "w"))==NULL)
return 1;
fclose(exec_file);
sprintf(buf, "chmod u+x %s", FileName);
if (system(buf)==-1)
return 1;
if (InitParentHandler())
return 1;
ProcessContinued=0; // actually for parent
switch (child_pid_or_zero_for_parent=fork())
{
case -1: // with errors will be in main window
{
perror("fork");
return 1;
}
case 0: // child process
{
if (InitChildProcess())
exit(0);
parent_id=getppid();
EndChildProcess=0;
SendSignalToProcess(parent_id, SIGUSR1); // child just waits until will not ended
RunChildProcess();
}
default: // parent process
{
while(!ProcessContinued)
sleep(2); // wait for initialization of child
#ifdef debug
fprintf(stderr, "Parent id is %d\n", getpid());
fprintf(stderr, "Child id is %d\n", child_pid_or_zero_for_parent);
#endif
}
}
return 0;
}
void ice_system_call_light_weight_shell_task_free()
{
pid_t pid;
int status;
//
if (child_pid_or_zero_for_parent!=-1)
{
SendSignalToProcess(child_pid_or_zero_for_parent, SIGTERM);
// now wait until it really exited:
while(((pid=waitpid(child_pid_or_zero_for_parent, &status, 0))!=child_pid_or_zero_for_parent)||
(!WIFEXITED(status)))
{
if(pid<=0)
{
fprintf(stderr, "Error occured trying to end child\n");
break;
}
}
}
}
#endif //ice_system_call_light_weight_shell_task_imlemented
// dislike to system() call this one is lightweighted provided there is no fork call so there is no memory consumption
int ice_system_call_light_weight_shell_task(const char *task)
{
#ifndef ice_system_call_light_weight_shell_task_imlemented
if (system(task)==-1)
{
perror("ice_system_call_light_weight_shell_task");
return 1;
}
#else
if ((exec_file=iceu_system_safely_open_file(FileName, "w"))==NULL)
return 1;
fprintf(exec_file, "#!/bin/bash\n%s\nexit 0", task);
fclose(exec_file);
ProcessContinued=0;
#ifdef debug
fprintf(stderr, "Task \"%s\" is about to proceed\n", task);
#endif
if (SendSignalToProcess(child_pid_or_zero_for_parent, SIGUSR1))
return 1;
while(!ProcessContinued)
sleep(1);
/*
if (SendSignalToProcess(parent_id, SIGSTOP))
return 1;
*/
#endif
return 0;
}
I don't get it! WTF? Maybe after fork child and parent had smth common that shouldn't be common anymore?