Por que o sysctl está produzindo E_INVAL no Mac OS X?
-
24-09-2019 - |
Pergunta
Abaixo está um trecho reduzido (verificações de erros/nulos omitidas) de código C/Obj-C que usa sysctl para obter o argv de um processo específico com PID 50.
...
int getProcessArgs[3] = { CTL_KERN, KERN_PROCARGS, 50 };
sysctl(getProcessArgs, 3, NULL, &length, NULL, 0);
char* processArgs = malloc(length * sizeof(char));
sysctl(getProcessArgs, 3, processArgs, &length, NULL, 0);
...
A primeira chamada para sysctl (para determinar o tamanho da matriz de string argv) é bem-sucedida.O comprimento retornado é de aproximadamente 1600, maior do que eu esperaria, mas suponho que não seja irracional.Malloc consegue.A segunda chamada para sysctl retorna -1, definindo errno como 22, E_INVAL.
Eu olhei para outro código, incluindo aquele de essa questão, mas não consigo ver o problema com o meu.o que estou perdendo?
Solução
Tentei agrupar seu código em um programa e ele funciona bem e imprime o argv do outro processo, etc. ao perguntar sobre um dos meus próprios processos, ou seja, um com o mesmo uid do processo que invoca sysctl()
.
O aspecto "maior do que eu esperaria" ocorre porque as variáveis de ambiente do processo são retornadas, assim como os argumentos da linha de comando.(Não é óbvio qual é o formato de todas essas informações.)
Ao perguntar sobre um diferente processo do usuário, recebo o mesmo EINVAL do segundo sysctl
que você tem visto.Acho que isso é considerado uma curiosidade irracional sobre os processos de outras pessoas, mas você pensaria que o primeiro sysctl
também falharia.
(Ao perguntar sobre um pid inexistente, o primeiro sysctl
falha com EINVAL.)
Tudo isso parece estar extremamente subdocumentado:no Leopardo, KERN_PROCARGS
nem aparece no sysctl
página de manual.