Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible a kill a command launched using system api in C? If not any alternatives?

Tags:

c++

c

I am launching a command using system api (I am ok with using this api with C/C++). The command I pass may hang at times and hence I would like to kill after certain timeout.

Currently I am using it as:

system("COMMAND");

I want to use it something like this:

Run a command using a system independent API (I don't want to use CreateProcess since it is for Windows only) Kill the process if it does not exit after 'X' Minutes.

like image 844
Destructor Avatar asked Nov 01 '22 04:11

Destructor


1 Answers

Since system() is a platform-specific call, there cannot be a platform-independent way of solving your problem. However, system() is a POSIX call, so if it is supported on any given platform, the rest of the POSIX API should be as well. So, one way to solve your problem is to use fork() and kill().

There is a complication in that system() invokes a shell, which will probably spawn other processes, and I presume you want to kill all of them, so one way to do that is to use a process group. The basic idea is use fork() to create another process, place it in its own process group, and kill that group if it doesn't exit after a certain time.

A simple example - the program forks; the child process sets its own process group to be the same as its process ID, and uses system() to spawn an endless loop. The parent process waits 10 seconds then kills the process group, using the negative value of the child process PID. This will kill the forked process and any children of that process (unless they have changed their process group.)

Since the parent process is in a different group, the kill() has no effect on it.

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

int main() {
    pid_t pid;

    pid = fork();
    if(pid == 0) { // child process
        setpgid(getpid(), getpid());
        system("while true ; do echo xx ; sleep 5; done");
    } else {   // parent process
        sleep(10);
        printf("Sleep returned\n");
        kill(-pid, SIGKILL);
        printf("killed process group %d\n", pid);
    }
    exit(0);
}
like image 126
Clyde Avatar answered Nov 15 '22 04:11

Clyde