Pourquoi sysctl produit E_INVAL sur Mac OS X?
-
24-09-2019 - |
Question
Voici une épuré (contrôle d'erreur / null omis) extrait de code C / Obj-C qui utilise sysctl pour obtenir le argv d'un processus particulier avec 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);
...
Le premier appel à sysctl (pour déterminer la taille du tableau de chaînes argv) réussit. La longueur retournée est ~ 1600, plus grand que je me attends, mais je suppose que pas déraisonnable. Malloc réussit. Le deuxième appel à Sysctl renvoie -1, la mise en errno à 22, E_INVAL.
Je l'ai regardé tout autre code, y compris celui de cette question, mais ne peut pas voir le problème avec le mien. Qu'est-ce que je manque?
La solution
J'ai essayé envelopper votre code en un programme, et il fonctionne très bien et imprime argv de l'autre processus, etc. lorsque vous demandez sur l'un de mes propres processus , soit un avec le même uid que le procédé invoquant sysctl()
.
Le « plus grand que j'attendre » aspect est parce que les variables d'environnement du processus sont renvoyés ainsi que les arguments de ligne de commande. (Il est pas évident que le format de ces informations est.)
Pour toute demande au sujet d'un différent processus de l'utilisateur, je reçois le même EINVAL de la deuxième sysctl
que vous avez été voir. Je suppose que cela est considéré comme une curiosité déraisonnable sur les processus d'autres personnes, mais on croirait que le premier sysctl
échouerait aussi.
(Lorsque demandant au sujet d'un pid inexistant, la première sysctl
échoue avec EINVAL).
Tout cela semble être massivement underdocumented: Leopard, KERN_PROCARGS
ne figure même pas dans la page man sysctl