Riki Dev Riki Dev - 19 days ago 5
Linux Question

Kill child process by parent in Linux

I have problem on this program with c. I want to send a

kill
signal to all child processes from the parent process. Below are the gcc errors.

How can I kill all child processes from parent process?

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>

int cont=0;

void gestore(){
printf("\n Processo %d ha eseguito %d iterazioni \n",getpid(),cont);
}


int main(int argc,char *argv[]){

if(argc<2){
printf("\n Numero argomenti non sufficiente \n");
exit(-1);
}

int nfigli=atoi(argv[1]);
int nsec=atoi(argv[2]);
int conta=0,pid=0;
int status=0;

while(conta<nfigli){

cont=0;

pid=fork();

if(pid==-1){
perror("\n Errore creazione processo figlio \n");
exit(-2);
}

else if(pid==0){
//child
signal(SIGUSR1,gestore);

while(true){
sleep(1);
cont++;
}
}

else{
//parent
sleep(nsec);
kill(0);
wait(&status);
}

cont=0;
conta++;
}

return 0;
}


Compile Errors:

counter.c:45:15: error: use of undeclared identifier 'true'; did you mean 'free'?
while(true){
^~~~
free
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/stdlib.h:143:7: note: 'free' declared here
void free(void *);
^
counter.c:45:15: warning: address of function 'free' will always evaluate to 'true' [-Wpointer-bool-conversion]
while(true){
~~~~~ ^~~~
counter.c:45:15: note: prefix with the address-of operator to silence this warning
while(true){
^
&
counter.c:54:14: error: too few arguments to function call, expected 2, have 1
kill(0);

Answer

What is wrong in your code:

  • 'true' is not a C keyword, use '1' instead
  • kill() has two arguments int kill(pid_t pid, int sig);
  • wait() require inclusion of sys/types.h and sys/wait.h
  • printf() is not async-signal-safe (read subchapter) and must not be used in a signal handler
  • 'argc' comparison must be made with '3' instead '2', because the program name counts as an argument
  • What you have called 'father' is 'parent'
  • I don't know if your group kill done with kill(0, SIGUSR1) is correct. Then I've found another implementation ...

The code below was based on this answer. I've made some modifications to suit your problem.
I hope it will be useful. Enjoy :-)

By the way:

  • In this implementation a list of children's pids was used pid_t *pids
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

/* used by child to determine whether it was killed by parent or by itself*/
int child_killed;

/* SIGUSR1 handler */
void
child_sigusr_handler (int signum) {
    child_killed = 1;
}

int
main (int argc, char **argv) {
    pid_t *pids; /* children pid list */
    int n; /* how many children we should create (aka your 'nfigli') */
    int t; /* sleep time before parent start killing (aka your 'nsec') */
    int i; /* a counter ... */

    if (argc < 3) {
        printf("usage: cmd <N_children> <parent_wait_time>\n");
        exit(1);
    }
    n = atoi(argv[1]);
    t = atoi(argv[2]);

    pids = malloc(n * sizeof(pid_t)); /* allocate memory for pid list */

    /* start children */
    for (i = 0; i < n; ++i) {
        if ((pids[i] = fork()) < 0) {
            perror("fork");
            abort();
        } else if (pids[i] == 0) { /* we're child */
            child_killed = 0; /* signal handler will turn it '1' */
            signal(SIGUSR1, child_sigusr_handler);
            sleep(5); /* child waits for 5 secs to exit by itself */

            printf("[%d] child ", getpid());
            if (child_killed)
                printf("has killed by parent\n");
            else
                printf("has ended by itself\n");

            exit(0);
        }
    }

    sleep(t);

    /* kill children */
    for (i = 0; i < n; ++i) {
        kill(pids[i], SIGUSR1);
    }

    free(pids);
    return 0;
}
Comments