what i am trying to do is that when my program receives SIGSTOP, it should send SIGCONT to itself. if i do it on terminal, it works but i want to do it in my program. I tried something like this, but it doesn't work..
can you help me?
int main()
{
pid_t pid;
pid = fork();
if(pid > 0)
{
int i = 0;
while(1)
{
if(i == 5)
{
kill(getpid(), SIGSTOP);
}
printf("i = %d\n" ,i);
i++;
sleep(1);
}
}
if(pid == 0)
{
while(1)
{
kill(getpid(), SIGCONT);
}
}
return 0 ;
}
You're mixing up which PID is which. The child is sending itself SIGCONT, which does nothing since it's already running. Make it send the parent SIGCONT instead.
Related
How can i send signal from parent process to the child?
After i write to the pipe i want to send signal to the child process.
pid_t pid;
int filds[2];
pipe(filds);
char *args[150] = {"./draw.out", NULL};
char buff = '\0';
if ((pid = fork()) < 0) { // fork a child process/
printf("*** ERROR: forking child process failed\n");
exit(1);
} else if (pid == 0) {
execvp(args[0], args); // execute the command
} else { // for the parent
char btnPressed = getch();
while (btnPressed != 'q'){
btnPressed = getch();
write(filds[1],buff, BUFF_SIZE);
//signal
}
// signal finish game.
}
kill(PID, SIGwhatever);
however this is probably a poor choice; the better solution is
close(filds[1]);
and handle close of input in the child. I think you're missing a
dup2(files[0],0);
in the child path as well.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
GOAL: Make parent process counters correct, counter1 = 5, counter2 =8.
Program is supposed to create 2 subprocesses. Each one of them will send set number of respectively SIGUSR1 and SIGUSR2 to parent. 5 and 8 times respectively.
To simplify, after many crashes causing my system to log out, closing all programs and forcing me to log in, i'm printing information about parent process instead. The goal is to replace those prints by
kill(getppid(),SIGUSR1) // and SIGUSR2 for second child process.
Current child work function:
void childWork(int loopCounter, int sigNum)
{
for(; loopCounter>0; loopCounter--)
{
if(SIGUSR1==sigNum) //kill(getppid(),SIGUSR1);
printf("[%d] sending SIGUSR1 to %d\n", getpid(),getppid());
else if(SIGUSR2 == sigNum) //kill(getppid(), SIGUSR2);
printf("[%d] sending SIGUSR2 to %d\n", getpid(),getppid());
}
}
Here is the zombie handling function for cleanup:
void handleZombie(int sig) {
while (1) {
pid_t pid = waitpid(0, NULL, WNOHANG);
if (pid < 0) {
if (errno == ECHILD)
return;
printf("Error, cleaning\n");
}
if (pid == 0)
return;
}
And finally main:
int main(int argc, char** argv)
{
printf("[%d] PARENT started! My parent: %d\n", getpid(), getppid());
childrenLeft=2;
setHandler(handleZombie,SIGCHLD);
setHandler(sigHandler1, SIGUSR1);
setHandler(sigHandler2, SIGUSR2);
int i;
for(i=1;i<=childrenLeft;i++)
{
pid_t pid = fork();
if(pid < 0)
printf("Error - fork\n");
if(pid==0)
if(i==1)
{
printf("[%d] child created!\n", getpid());
childWork(5,SIGUSR1);
}
if(i==2)
{
childWork(8, SIGUSR2);
printf("[%d] child created!\n", getpid());
}
exit(EXIT_SUCCESS);
}
printf("Work finished, final numbers:\nSIGUSR1 received: %d\nSIGUSR2 received: %d\n",sig1Count,sig2Count);
while (wait(NULL) > 0)
continue;
printf("[PARENT=%d] terminates\n", getpid());
return EXIT_SUCCESS;
}
Current issue is actually handling the parent process. For reason i do not understand, my second child isn't created. What more, the parent being printed is out of the blue.
[6025] PARENT started! My parent: 1300
[6026] child created!
[6026] sending SIGUSR1 to 6025
[6026] sending SIGUSR1 to 6025
[6026] sending SIGUSR1 to 6025
[6026] sending SIGUSR1 to 30404
[6026] sending SIGUSR1 to 30404
This is the complete output. Please help me understand what is going on here...
Note that you don't report that child 2 is created until after childWork() returns.
However, your fundamental problem is the lack of statement grouping braces after if (pid == 0) which means that the exit(EXIT_SUCCESS): after the two tests if (i == 1) and if (i == 2); causes the parent to exit immediately after launching the first child.
int main(int argc, char** argv)
{
printf("[%d] PARENT started! My parent: %d\n", getpid(), getppid());
childrenLeft=2;
setHandler(handleZombie,SIGCHLD);
setHandler(sigHandler1, SIGUSR1);
setHandler(sigHandler2, SIGUSR2);
int i;
for(i=1;i<=childrenLeft;i++)
{
pid_t pid = fork();
if(pid < 0)
printf("Error - fork\n");
if(pid==0)
{ // Primary bug: braces missing
if(i==1)
{
printf("[%d] child created!\n", getpid());
childWork(5,SIGUSR1);
}
if(i==2)
{
printf("[%d] child created!\n", getpid()); // Moved before childWork()
childWork(8, SIGUSR2);
}
exit(EXIT_SUCCESS); // Only executed by children
} // Primary bug: missing braces
}
printf("Work finished, final numbers:\nSIGUSR1 received: %d\nSIGUSR2 received: %d\n",sig1Count,sig2Count);
while (wait(NULL) > 0)
continue;
printf("[PARENT=%d] terminates\n", getpid());
return EXIT_SUCCESS;
}
This is the bare minimum fixing needed; there are many other changes that could and perhaps should be made.
I'm writing a Unix program where the parent process has to send signals to children and a grandson. How could I know if all processes have been already created before sending signals? Because sometimes they don't exist yet. Thanks a lot!
void t(int sig)
{
kill(SIGKILL, pidc1);
kill(SIGKILL, pidc2);
kill(SIGKILL, pidg2);
kill(SIGKILL, pidc3);
}
void handler()
{
write(1, "Signal SIGUSR1\n", 15);
}
pid_t pidc1, pidc2, pidc3, pidg2;
int main(int argc, char **argv)
{
struct sigaction action;
int status;
action.sa_flags = 0;
action.sa_handler = handler;
sigaction(SIGUSR1, &action, NULL);
pidc1 = fork();
if(pidc1 == 0)
{
printf("Child 1\n");
}
pidc2 = fork();
if(pidc2 == 0)
{
printf("Child 2\n");
pidg2 = fork();
if(pidg2 == 0)
{
printf("Grandson 2\n");
}
wait(&status);
}
pidc3 = fork();
if(pidc3 == 0)
{
printf("Child 3\n");
}
kill(pidg2, SIGUSR1);
kill(pidc3, SIGUSR1);
signal(SIGALRM, t);
alarm(10);
wait(&status);
}
Preliminary note: The child code parts in your example program fall through to their parent's code, which is certainly not intended; I'll assume something like return sleep(5); at the end of each block. Also note that the printf()s may malfunction with fork()s and buffered output.
Barmar wrote:
If you need to wait for the grandchild processes to be created, you need some kind of communication from the child to the parent, so it can send the grandchild's PID. Shared memory and a mutex would be a way to do this.
That's absolutely correct. (The direct children are no problem, since the parent knows their PIDs.) Another way to communicate the grandchild's PID is a pipe; your example main() could become:
int main(int argc, char **argv)
{
int status;
sigaction(SIGUSR1, &(struct sigaction){.sa_handler = handler}, NULL);
setbuf(stdout, NULL); // printf() may malfunction without this
pidc1 = fork();
if (pidc1 == 0)
{
printf("Child 1\n"); return sleep(5);
}
int pipefd[2];
pipe(pipefd); // for communicating the grandson's PID
pidc2 = fork();
if (pidc2 == 0)
{
printf("Child 2\n");
pidg2 = fork();
if (pidg2 == 0)
{
printf("Grandson 2\n"); return sleep(5);
}
write(pipefd[1], &pidg2, sizeof pidg2); // write pidg2 to write end
wait(&status); return sleep(5);
}
pidc3 = fork();
if(pidc3 == 0)
{
printf("Child 3\n"); return sleep(5);
}
read(pipefd[0], &pidg2, sizeof pidg2); // read pidg2 from pipe's read end
kill(pidg2, SIGUSR1);
kill(pidc3, SIGUSR1);
}
Hello i have such problem
pid_t pid1;
pid_t pid2;
void switch_files(int sig_type)
{
printf("%d %d\n", pid1, pid2);
}
int main(int argc, char **argv)
{
pid_t lpid1,lpid2;
if ((lpid1 = fork()) == 0)
{
signal(SIGUSR1, switch_files);
//Some work
} else {
pid1 = lpid1;
}
if ((lpid2 = fork()) == 0)
{
signal(SIGUSR2, switch_files);
//Some work
} else {
pid2 = lpid2;
}
while(scanf("%s", input) > 0)
{
write(pipe1[1], input, strlen(input) + 1);
kill(pid1, SIGUSR1);
}
waitpid(pid1, 0, 0);
waitpid(pid2, 0, 0);
}
So i need to have value of pid1 and pid2 in my callback for signals, and at printf i have 0 0 but in main i have normal value of pids. How i can fix this, thank you for any help.
If you want the child to have the pid, simply ask for it:
if ((lpid1 = fork()) == 0)
{
pid1 = getpid();
pid2 = -1; // other child doesn't even exist yet
signal(SIGUSR1, switch_files);
//Some work
exit(0); // you don't want the child to go executing parent code, do you?
}
And
if ((lpid2 = fork()) == 0)
{
//pid1 already set with pid of 1st child
pid2 = getpid();
signal(SIGUSR2, switch_files);
//Some work
exit(0); // you don't want the child to go executing parent code, do you?
}
If you need to the 1st child to have the pid of the 2nd child, then you need to use some form of IPC, so you can communicate to the the 1st child after also 2nd child has been started and its pid is known.
If you want the children to have information, you have to communicate that information to them somehow. You can use a file, a pipe, shared memory, or any mechanism you want. But you have to pass the information somehow.
I have a little problem with signal function.
My program in a brief:
void sigfunc(int sn)
{
if(sn == SIGINT)
printf("SIG TEXT!");
}
int main(void)
{
...
// spawn 10 children and execl my another programs
for (i = 0; i < 10; i++) {
pid = fork();
if (pid != 0) {
signal(SIGINT, sigfunc);
continue;
} else if (pid == 0) {
execl(pathtoprog[i], progname[i], NULL);
}
// wait for sig (only parent waits because programs from execl have their own while(1))
if(pid > 0)
while(1) {}
}
Problem is simple: when I press Ctrl+C I'll see SIG TEXT! but programs started by execl will crash/hang(I'm not sure, because they stop working but still exists in process monitor). How to write this sigfunc to react only for parent process and leave all children with execl alone?