PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Thursday, September 15, 2022

[FIXED] How to terminate child process when another child process finishes?

 September 15, 2022     c, exec, fork, linux     No comments   

Issue

I have a code segment that looks like this:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
  pid_t first, last;

  last = fork();
  if (last == 0) {
    char *args[] = { "./last", NULL };
    char *env[] = { NULL };
    execve("./last", args, env);
    _exit(1);
  } else if (last == -1) {
    fprintf(stderr, "Error: failed to fork last.\n");
    exit(1);
  }

  first = fork();
  if (first == -1) {
    fprintf(stderr, "Error: failed to fork first.\n");
    exit(1);
  } else if (first > 0) {
    int status;
    waitpid(first, &status, 0);
  } else {
    char *args[] = { "./first", NULL };
    char *env[] = { NULL };
    execve("./first", args, env);
    _exit(1);
  }

  return 0;
}

This works fine in a sense that I can see processes being invoked and running. However, my issue is that process last has an infinity loop, and when process first terminates, it still stays running. Is there a way in C to force process last here to terminate also when process first finishes?


Solution

kill() should be of interest. From the man page of kill():

#include <sys/types.h>
#include <signal.h>

int kill(pid_t pid, int sig);

Since fork() returns the child PID in the parent, you can use that to call kill(). Here is the modified code and test run.

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>  // Modification 1

int main(int argc, char *argv[]) {
  pid_t first, last;

  last = fork();
  if (last == 0) {
    char *args[] = { "./last", NULL };
    char *env[] = { NULL };
    execve("./last", args, env);
    _exit(1);
  } else if (last == -1) {
    fprintf(stderr, "Error: failed to fork last.\n");
    exit(1);
  }

  first = fork();
  if (first == -1) {
    fprintf(stderr, "Error: failed to fork first.\n");
    exit(1);
  } else if (first > 0) {
    int status;
    waitpid(first, &status, 0);
    kill(last, SIGINT);   // Modification 2
  } else {
    char *args[] = { "./first", NULL };
    char *env[] = { NULL };
    execve("./first", args, env);
    _exit(1);
  }

  return 0;
}

Terminal Session (before):

$ ls test first last 
first  last  test
$ ./test
$ ps aux | grep last
root      165130  0.0  0.0   2136   752 pts/3    S    16:58   0:00 ./last
root      165135  0.0  0.0   6136   892 pts/3    S+   16:58   0:00 grep last

Terminal Session (after):

$ ls test first last 
first  last  test
$ ./test
$ ps aux | grep last
root      165240  0.0  0.0   6136   836 pts/3    S+   17:01   0:00 grep last

Regarding which signal to be passed: anyone whose default action is termination. You can find more from the signal man page. Since I don't know what is exactly in the last executable, I assume that there is no signal handler registered for SIGINT and hence when last gets SIGINT, the program is terminated by default.



Answered By - m0hithreddy
Answer Checked By - Marie Seifert (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing