What is the most efficient way to kill an external process from a program written in C?

Asked

Viewed 71 times

1

My version:

//test.c (04/07/2019)

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

void stop_attack(pid_t child){

    int wstatus;

    system("killall xerxes");

    if(kill(child, SIGTERM)!=0){

        kill(child, SIGKILL);
    }

    wait(&wstatus);
}

int main(void){

    const time_t timer=3600;

    pid_t child=fork();

    if(child<0){

        exit(EXIT_FAILURE);

    }else if(child==0){

        for(time_t i=0; i<=timer; i++){

            usleep(1000000);
        }

        __kill(child);

    }else{

        system("./xerxes 127.0.0.1 80");
    }

    return EXIT_SUCCESS;
}

Xerxes. c

In the above case I used a system call (system("killall xerxes")), but I’m not sure if this is an efficient and safe approach, as there may be situations where this may fail.

There is a more efficient and secure way to kill an external process via a program written in C, without the need to use the function system()?

1 answer

2

Assuming you are on a UNIX family operating system, the function kill() of the system library signal.h, can solve your problem.

However, the function kill() is only able to send signals to a process from your PID, that is, you will need discover the identifier (or identifiers) of the process you want to "kill". Remembering that the same executable can have multiple instances (copies) running, each with a PID single.

In systems UNIX, the directory /proc is responsible for storing the list of PIDs with the executables that are running on the system.

Follows a code (tested) able to solve the problem without using the function system(), look at you:

#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>

int main( int argc, char * argv[] )
{
    const char * procdir = "/proc";
    size_t namelen = PATH_MAX;
    char * name = NULL;
    DIR * dir = NULL;
    struct dirent * de = NULL;
    int pid = -1;
    char cmdline_file[PATH_MAX+1] = {0};
    FILE * cmdline = NULL;
    int ret = 0;

    if( argc < 2 )
    {
        fprintf( stderr, "Sintaxe: %s <NOME_DO_PROCESSO>\n", argv[0] );
        return EXIT_FAILURE;
    }

    name = calloc( 1, namelen );

    if(!name)
    {
        fprintf( stderr, "calloc(): memoria insuficiente\n");
        return EXIT_FAILURE;
    }

    dir = opendir("/proc");

    if(!dir)
    {
        perror("opendir()");
        return EXIT_FAILURE;
    }

    while((de = readdir(dir)) != 0)
    {
        if( !strcmp(de->d_name, ".") || !strcmp(de->d_name, "..") )
            continue;

        ret = sscanf(de->d_name, "%d", &pid);

        if( ret == 1 )
        {
            sprintf( cmdline_file, "%s/%d/cmdline", procdir, pid );

            cmdline = fopen(cmdline_file, "r");

            if(!cmdline)
                continue;

            if(getline(&name, &namelen, cmdline))
            {
                if(strstr( name, argv[1] ))
                {
                    fprintf(stderr, "Enviando SIGKILL para processo de PID: %d...", pid );

                    ret = kill( pid, SIGKILL );

                    if( ret < 0 )
                        fprintf(stderr,"Falhou!\n");
                    else
                        fprintf(stderr,"OK\n");
                }
            }

            fclose(cmdline);
        }
    }

    closedir(dir);
    free(name);

    return EXIT_SUCCESS;
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.