Pergunta

Quero obter o argumento de outro processo como ps.

Estou usando o Mac OS X 10.4.11 rodando em Intel ou PowerPC.

Primeiro, li o código ps e man kvm, depois escrevi um código C.

#include <kvm.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/sysctl.h>
#include <paths.h>

int
main(void) {
    char errbuf[1024];
    kvm_t *kd = kvm_openfiles(_PATH_DEVNULL, NULL, _PATH_DEVNULL, O_RDONLY, errbuf);
    int num_procs;
    if (!kd) { fprintf(stderr, "kvm_openfiles failed : %s\n", errbuf); return 0; }
    struct kinfo_proc *proc_table = kvm_getprocs(kd, KERN_PROC_ALL, 0, &num_procs);

    for (int i = 0; i < num_procs; i++) {
        struct kinfo_proc *pproc = &proc_table[i];
        char **proc_argv = kvm_getargv(kd, pproc, 0);
        printf("%p\n", proc_argv);
    }

    kvm_close(kd);
    return 0;
}

Quando executado em PowerPC, kvm_getargv() sempre retornou NULL.Quando executado na Intel, kvm_openfiles() falhou com erro /dev/mem: No such file or directory.

Claro, eu sei sobre permissão.

Em segundo lugar, tentei o sysctl.

#include <sys/sysctl.h>
#include <stdio.h>
#include <stdlib.h>
#define pid_of(pproc) pproc->kp_proc.p_pid

int
main(void) {

   int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
   int buffer_size;
   sysctl(mib, 4, NULL, &buffer_size, NULL, 0);

   struct kinfo_proc *result = malloc(buffer_size);
   sysctl(mib, 4, result, &buffer_size, NULL, 0);

   int num_procs = buffer_size / sizeof(struct kinfo_proc);
   for (int i = 0; i < num_procs; i++) {
       struct kinfo_proc *pproc = result + i;
       int mib[3] = { CTL_KERN, KERN_PROCARGS, pid_of(pproc) }; // KERN_PROC_ARGS is not defined
       char *proc_argv;
       int argv_len;
       sysctl(mib, 3, NULL, &argv_len, NULL, 0);
       proc_argv = malloc(sizeof(char) * argv_len);
       sysctl(mib, 3, proc_argv, &argv_len, NULL, 0);
       fwrite(proc_argv, sizeof(char), argv_len, stdout);
       printf("\n");
       free(proc_argv);
   }

   return 0;
}

Por FWRITE, eu tenho argv [0], mas argv [1 ..] não são (as variáveis ​​do ambiente são impressas.)

Não há mais como fazer isso?

Foi útil?

Solução

Na versão 10.6, KERN_PROCARGS2 está disponível: https://gist.github.com/770696

Este método é usado em ps, procfs no MacFUSE, etc.

Outras dicas

Na verdade, estou precisando da mesma coisa para uma biblioteca Python que estou escrevendo e, em minha pesquisa, encontrei outra biblioteca Python (PSI) que implementa isso no código C.Faz parte do código do módulo python para listar processos e também inclui listar os argumentos para cada processo.Você pode dar uma olhada no código-fonte para obter um exemplo prático:

darwin_process.c - role para baixo até set_exe() para o código relevante

Observação:o site é realmente lento, então você terá que ser um pouco paciente enquanto carrega.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top