Perché sysctl producendo E_INVAL su Mac OS X?
-
24-09-2019 - |
Domanda
Ecco un sbucciate-giù (controlli errore / nulli omesse) frammento di codice C / Obj-C che utilizzi sysctl per ottenere l'argv di un particolare processo con 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);
...
La prima chiamata a sysctl (per determinare la dimensione della matrice di stringa argv) riesce. La lunghezza restituita è ~ 1600, più grande di quanto mi aspetterei, ma io non suppongo irragionevole. Malloc riesce. La seconda chiamata a rendimenti sysctl -1, impostando errno a 22, E_INVAL.
Ho guardato altro codice, comprese quelle provenienti da questa domanda , ma non può vedere il problema con la mia. Che cosa mi manca?
Soluzione
Ho cercato avvolgendo il proprio codice in un programma, e funziona benissimo e lo stampa dell'altro processo argv ecc Quando indagando su uno dei miei propri processi , vale a dire, uno con lo stesso UID dello processo chiamante sysctl()
.
Il "grande di quanto mi sarei aspettato" aspetto è perché le variabili di ambiente del processo vengono restituiti così come gli argomenti della riga di comando. (Non è chiaro cosa il formato di tutte queste informazioni è.)
Quando indagando su un diverso processo dell'utente, ottengo lo stesso EINVAL dal secondo sysctl
che hai visto. Credo che questo è considerato la curiosità irragionevole sui processi di altre persone, ma penserei prima sysctl
fallirebbe anche.
(Quando indagando su un pid inesistente, il primo sysctl
fallisce con EINVAL.)
Tutto questo sembra essere in maniera massiccia underdocumented:. Su Leopard, KERN_PROCARGS
non compare nemmeno nella pagina sysctl
man