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.Pourquoi sysctl produit-il E_INVAL sous Mac OS X?
...
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 grande que ce à quoi je m'attendais, mais je suppose qu'elle n'est pas déraisonnable. Malloc réussit. Le deuxième appel à sysctl renvoie -1, définissant errno à 22, E_INVAL.
J'ai regardé un autre code, y compris celui de this question, mais ne peux pas voir le problème avec le mien. Qu'est-ce que je rate?
Voilà ce que c'est; quand j'essaie avec un PID auto-détenu, ça marche. J'ai aussi fait quelques recherches sur http://www.opensource.apple.com/source/xnu/xnu-792.12.6/bsd/kern/kern_sysctl.c (voir sysctl_procargsx), et il vérifie en fait les permissions dans le en fait-obtenir-args cas, mais pas quand vous obtenez juste la longueur. Maintenant je me demande juste comment 'ps' est capable d'obtenir les args pour tous les processus, mais je suppose que c'est pour une question séparée. – DNS
L'approche habituelle pour 'ps' est d'être setuid root et ainsi pouvoir utiliser arbitrairement KERN_PROCARGS ou d'autres superpuissances. Ce code source sysctl_procargsx() est intéressant en ce qu'il retourne juste la base de la pile utilisateur - retourner le cadre de la pile principale (argc, argv, envp) permet de comprendre pourquoi les variables d'environnement sont aussi retournées, et dit ... er ... quelque chose sur le format des données renvoyées. –