execl() arguments dans Ubuntu
Je suis à l'apprentissage de linux programmation et suis tombé sur la fonction exec ce qui est très utile. Mais le problème est exec arguments de la fonction sont très confus et je n'arrive pas à saisir quel argument est dans quel but.. Dans le code suivant execl()
fonction est appelée à partir d'un enfant a créé par fork()
, Quel est le but de la dernière argument (NULL
) dans execl()
?
execl("/bin/ls","ls","-l",NULL);
Si quelqu'un peut expliquer ce qu'est le but de NULL
argument et d'autres arguments et le but des arguments de exec()
fonction de la famille, Il serait d'une grande aide pour moi!
OriginalL'auteur user1698102 | 2012-10-01
Vous devez vous connecter pour publier un commentaire.
Pour créer un comportement indéfini. Qui n'est pas un appel à
execl
. Unappel correct pourrait être:
Le dernier argument doit être
(char*)0
, ou vous avez un comportement indéfini.Le premier argument est le chemin de l'exécutable. La suite
les arguments apparaissent dans
argv
du programme exécuté. La liste de cesles arguments se termine par un
(char*)0
; c'est la façon dont la fonction appeléesait que le dernier argument a été atteint. Dans l'exemple ci-dessus,
par exemple, le fichier exécutable à
"/bin/ls"
remplacera votre code;son
main
, il auraargc
égal à 2, avecargv[0]
l'égalité des"ls"
,et
argv[1]
l'égalité des"-l"
.Immédiatement après cette fonction, vous devez avoir l'erreur de manipulation
code. (
execl
renvoie toujours -1, quand il revient, de sorte que vous n'avez pas besoin dele tester. Et il retourne uniquement si il y avait une sorte d'erreur.)
NULL
au lieu de(char*)0
crée un comportement indéterminé?Parce que la norme Posix dit. Plus généralement, la norme dit que c'est un comportement indéfini si un varargs fonction tente d'en extraire un type autre que le type qui a été adoptée.
execl
est documenté pour exiger unchar*
. Il ne pouvait guère en essayer un autre type jusqu'à ce qu'il avait extrait de l'argument.NULL
a un type intégral, généralementint
. Donc, en passantNULL
est un comportement indéfini, et a été depuis des pointeurs cessé d'être ints.Proférer des conneries. POSIX états qui
NULL
, comme un pointeur null, est égal à zéro converti en pointeur [POSIX définitions, 3.244], généralement(void *)0
.(void *)0
, ou une expression équivalente. En C89 et C99,void *
n'a pas besoin d'être converti en un autre type de pointeur. Donc -- et cela englobe TOUS C89/C99/C de GNU implémentations je n'ai jamais utilisé, de microcontrôleurs, clusters --NULL
est correcte à utiliser pour ce, et toutes les autres semblables variadic fonctions.n'est pas un pointeur null, c'est un pointeur null constante. Et d'un pointeur null constante est requise par la norme C++ pour avoir un type intégral. Je n'ai vu que deux définitions de
NULL
sous Unix:0
et g++'s__null
compilateur de la magie. C'est toujours une erreur de passerNULL
à un variadic fonction où les pointeurs sont attendus. La norme Posix indique à l'aide de(char*)0
, et les pages de manuel Linux explicitement queNULL
doit être passé comme(char*)NULL
.Juste pour être parfaitement clair, quand
NULL
(ou0
) est utilisé dans un contexte qui exige un type de pointeur, il est implicitement converti en un pointeur null. Passage d'un argument à un...
n' pas besoin d'un pointeur de type, cependant, et pas de conversion se produit; vous passez0
. G++ compilateur utilise la magie pourNULL
, de sorte que vous aurez probablement vous en sortir avec avec g++, mais j'ai utilisé plus que quelques compilateurs où ça ne marcherait pas; oùchar*
était plus gros qu'unint
(etNULL
a été définie comme0
).OriginalL'auteur James Kanze
La
exec
fonctions sont variadic: ils prennent un nombre variable de paramètres, de sorte que vous pouvez passer un nombre variable d'arguments à la commande. Les fonctions doivent utiliserNULL
comme un marqueur pour marquer la fin de la liste d'arguments.Dans les variadic fonctions est une boucle qui va se répéter sur le nombre d'arguments variable. Ces boucles besoin d'une condition d'arrêt. Dans certains cas, par exemple,
printf
, le nombre réel d'arguments peut être déduite à partir d'un autre argument. Dans d'autres fonctions,NULL
est utilisé pour marquer la fin de la liste.Une autre option serait d'ajouter un paramètre de fonction pour nombre d'arguments, mais qui rend le code un peu plus fragile, nécessitant le programmeur à gérer un paramètre supplémentaire, plutôt que de simplement en utilisant toujours un
NULL
que l'argument final.Vous verrez également
(char *) 0
utilisé comme marqueur:execl
, la fonction appelée attend une liste dechar*
, terminé par un pointeur null de typechar*
. DepuisNULL
a typeint
(ou au moins un type intégral), en passant ici, c'est un comportement indéfini.OriginalL'auteur pb2q
Dans
/usr/include/libio.h
, depuis gcc 2.8 (il y a longtemps)NULL
est défini pour être null ( est réservé pour les builtins), avant queNULL
était(void *)0
qui est indiscernable de(char *)0
dans unvarargs
situation étant donné que le type n'est pas adopté, l'exception étant si__cplusplus
est défini auquel casNULL
est définie comme 0.La chose prudente à faire, surtout si vous avez une architecture 64-bit est à utiliser de manière explicite
(void *)0
qui est définie de façon à être compatible avec n'importe quel pointeur et ne pas compter sur toute douteux#defines
qui pourrait arriver à être dans la bibliothèque standard.OriginalL'auteur jrrk
La but de la fin argument
(char *) 0
est de mettre fin aux paramètres. Un comportement indéfini peut entraîner si ce manque.La page de man définit la execl signature :
chemin: L'emplacement du programme à appeler, le programme d'invoquer.
arg, ...*: peut être considéré comme arg0, arg1, ..., argn.
Dans votre cas
execl( "/bin/ls", "ls", "-l", (char*)0 );
est le bon appel de fonction."bin/ls" le programme d'invoquer
"ls" le nom du programme
"-l" est le paramètre pour le programme appelé
OriginalL'auteur Carlos Davila