Existe uma maneira, com C no linux, de fechar outro aplicativo? [duplicado]

Nov 30 2020

Gostaria de fazer um programa que possa bloquear a abertura de alguns programas ou interrompê-los depois de iniciados. Só posso codificar em C e também gostaria de adicionar uma GUI, portanto, não posso usar bash e kill. Existe uma maneira de fechar outro programa de C?

Eu quero basicamente criar um "atraso de tempo" para que não possa iniciar o minecraft durante o dia escolar.

Gostaria de manter o código o mais eficiente possível e não consegui encontrar nenhuma ferramenta como um serviço que fechasse aplicativos de maneira eficiente ou impedisse que eles fossem iniciados.

Respostas

Joshua Dec 01 2020 at 03:56

Então, o que queremos fazer é localizar o processo e kill()ele. Não é tão difícil. É muito longo porque o executável não é minecraft, é java, então procuramos o .jararquivo.

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

void kill_minecraft()
{
    char buf[8192];
    DIR *dir = opendir("/proc");
    struct dirent *dirent;
    while ((dirent = readdir(dir)))
    {
        pid_t pid = atol(dirent->d_name);
        if (pid > 0)
        {
            sprintf(buf, "/proc/%s/cmdline", dirent->d_name);
            FILE *in = fopen(buf, "r");
            if (in)
            {
                size_t nmem = fread(buf, 1, 8192, in);
                fclose(in);
                buf[8192] = 0;
                // Recognize minecraft's jar in the command line
                if (nmem > 0 && (char *ptr = (char*)memmem(buf, "minecraft/versions/", nmem)))
                {
                     char *p1 = (char*)strstr(ptr, ":");
                     char *p2 = (char*)strstr(ptr, ".jar");
                     if (p2 && (!p1 || p1 > p2))
                     {
                         // Match! Goodbye!
                         kill(pid, 9);
                     }
                }
                fclose(in);
            }
        }
    }
    closedir(dir);
}

Uau. Vamos decompô-lo. Esta função itera sobre todos os processos em execução e lê em sua linha de comando. Depois de fazer isso, ele verifica a linha de comando para o padrão do minecraft; que é ter um argumento de linha de comando de minecraft / versions / something / something.jar. Em java, os argumentos jar são agrupados separados por :caracteres, para que ele cuide disso. Ao obter um fósforo, ele chama kill.

O agendamento desta função é deixado como um exercício para o leitor. Veja time()e sleep()funções. Quanto a executá-lo, a maneira mais preguiçosa é ligar para ele /etc/rc.local.

Você pode fazer isso com pkill -fum loop, mas essa regex é difícil de escrever e não quero descobrir.