Passage d'un tableau à execvp() à partir de l'entrée de l'utilisateur
Je suis en train de passer des arguments entrés par l'utilisateur pour execvp()
.
Jusqu'à présent, j'ai divisé la chaîne. Si l'utilisateur tape ls -a
, temp
est enregistré en tant que "ls" et " -", suivi par un caractère NUL. Je ne suis pas tout à fait sûr de savoir comment le signaler correctement dans execvp
. Dans les exemples que j'ai vu à l'aide de execvp(temp[position], temp)
. Je sais que la façon dont je suis en train de le faire pour le moment est mal, mais je ne suis pas sûr de savoir comment le faire correctement! Au moment où j'obtiens une erreur de segmentation.
int main(int argc, char *argv[])
{
char line[124];
int size = 124;
char *temp = NULL;
while(fgets(line, size, stdin) != NULL ) {
if (strcmp(line, "exit\n") == 0) {
exit(EXIT_SUCCESS);
}
temp = strtok(line, " ");
while (temp != NULL) {
printf("%s\n", temp);
temp = strtok(NULL, " ");
}
execvp(temp, &temp);
}
return EXIT_SUCCESS;
}
Puisque vous n'êtes pas en utilisant soit
Je vais utiliser par la suite. Tout simplement pas à ce point dans le temps.
Juste assez mais pour un SSCCE (Bref, Autonome, Exemple Correcte), vous cherchez à éliminer tout ce qui est indifférent à la réduction de l'exemple. C'est un problème mineur — mineur. La plupart des programmes offrent beaucoup plus de possibilités pour sniper que la vôtre.
argc
ou argv
, vous pouvez utiliser int main(void)
. Avec les options de compilation-je utiliser de façon habituelle, qui empêche un couple de mises en garde.Je vais utiliser par la suite. Tout simplement pas à ce point dans le temps.
Juste assez mais pour un SSCCE (Bref, Autonome, Exemple Correcte), vous cherchez à éliminer tout ce qui est indifférent à la réduction de l'exemple. C'est un problème mineur — mineur. La plupart des programmes offrent beaucoup plus de possibilités pour sniper que la vôtre.
OriginalL'auteur caerulean | 2013-03-21
Vous devez vous connecter pour publier un commentaire.
Votre problème, c'est que
temp
est un seul pointeur, et vous avez besoin pour passer un tableau de pointeurs sur desexecvp()
.Quelque chose comme:
Noter que la liste d'argument a été donné un pointeur null comme un terminator, tout comme
argv[argc] == NULL
dansmain()
. Clairement, j'ai lésiné sur la vérification d'erreur (si vous passez plus de 63 arguments, vous allez débordementargs
tableau). Mais il contient l'idée de base.Je ne suis pas sûr de ce que peut être le problème — l'ensemble de ces travaux pour moi:
ls
ls -l
ls -l madump.c
(oùmadump.c
arrive à être un fichier dans le répertoire que je suis en essais)Le code que j'ai utilisé était:
Noter que j'ai ajouté
\n
à lastrtok()
liste des jetons, après la création d'un répertoire avec un saut de ligne à la fin de son nom. Bon pour les amis ennuyeux et incompréhensible semi-éduqués ennemis, mais une nuisance de la plupart des autres points de vue. Notez comment j'ai imprimer les données qui va être transmis àexecvp()
juste avant de le faire. Souvent, je ne l'utiliseraisprintf("<<%s>>\n", *next);
au lieu de simplementputs()
pour obtenir une claire indication de l'endroit où les arguments de début et de fin.La sortie de l'exécution de la commande (
doit
) était:Qu'avez vous obtenez à partir de votre version?
Que (l'ajout de ce qui est dans
temp
àargs
) se fait via l'next
. D'abord,*next
points àargs[0]
; la valeurtemp
est copié àargs[0]
etnext
est incrémenté à point àargs[1]
; rincer et répéter. Par ailleurs, il n'auriez normalement être unfork()
dans le code, trop, sinon, votre programme va s'arrêter quand il premier avec succès exécute une commande.J'ai gardé mon tableau args à la taille de 16 ans pour l'instant. Après je reçois ce travail, je vais être la mise en œuvre de fork() pour que je puisse gérer plusieurs processus.
C'est tout beau; les choses simples de travail (vérifier avec
valgrind
) et ensuite de passer sur les parties les plus difficiles.Lorsque
execvp()
retourne -1, appelerperror
et de sortie. De cette façon, vous saurez pourquoiexecvp()
quitté.OriginalL'auteur Jonathan Leffler
Que votre code ressemble actuellement, après votre
while(temp != NULL)
finitions,temp
va être NUL!execvp
attend le première argument le chemin d'accès du fichier qui sera la nouvelle image de processus. Le deuxième argument devrait être un tableau de valeur NULL chaînes où le dernier membre de ce tableau est un pointeur NULL, et le premier membre est le nom de fichier du fichier spécifié dans le premier argument.À mettre en œuvre dans votre code, considérez les points suivants
while
boucle à la place:Le code que j'ai fourni ci-dessus ne font pas certains de vérification des erreurs (comme lorsque
realloc
oumalloc
échoue), mais, fondamentalement, garder ces points à l'esprit:Veuillez jeter un oeil à la documentation pour une meilleure clarté et un exemple très simple.
temp
points pour les parties de la matriceline
. Si vous décidez de copier les chaînes, alors je vous recommande d'utiliserstrdup()
. Lesnprintf()
est intéressant. L'explicite\0
est vraiment inutile; il y est déjà aller à une valeur null à la fin de toute façon. La dernièresprintf()
ne fait pas ce que vous pensez que cela fonctionne. Soit il se bloque ou écrit une chaîne de caractères comme(null)
dans la variable à laquelle vous n'avez alloué suffisamment d'espace pour un'\0'
.Oh wow, je n'avais aucune idée de
strdup()
. Semble beaucoup plus propre d'utiliser à la place. Oh ouisnprintf()
ne copiez le '\0', mon mauvais. Je ne comprends pas votre dernier point. En fait, je viens de réaliser questrlen((char *)0)
= crash.(char *)0
=(null)
donc je suis un peu paumé comment allouer de la mémoire pour cela. Toutes les suggestions?Utilisation:
argList[numArgs - 1] = NULL;
(ou0
en place deNULL
) au lieu de la final de la bouclesprintf()
. La dernière valeur du tableau doit être un pointeur null. Théoriquement, vous devriez vérifier que les allocations de mémoire réussir, trop. Aussi, même si elle rend le code un peu plus difficile, c'est une bonne idée pour allouer de la mémoire pourargList
dans les blocs (de dire 64 pointeurs à la fois), afin d'éviter quadratique comportement comme la croissance de la bloquer une entrée à la fois. Cependant, c'est un raffinement pour plus tard.Haha je savais que j'compliqué les choses quelque part. Merci
Je viens de remarquer une chose: si
execvp()
retourne, il a échoué. Si elle a réussi, il n'a pas de retour de l'autre programme est en cours d'exécution à la place.OriginalL'auteur Anish Ramaswamy
J'imagine que l'erreur est parce que vous êtes de passage à un pointeur NULL pour execvp. La boucle immédiatement au-dessus de l'appel garantit.
De faire ce que vous voulez faire, vous aurez besoin de créer un tableau de pointeurs de chaîne pour ce que vous avez actuellement appelé
temp
. Cela devient leargv
tableau pour le programme que vous appelez. C'est pourquoi la commande est généralement utilisée commeexecvp (temp[0], temp)
-argv[0]
est généralement le nom du programme.Donc, essayez de créer un tableau de pointeurs de chaîne, et ont chacun un point à un sous word à partir de
line
. Vous devrez peut-être utiliser malloc, mais si vous voulez faire le malin, vous pourriez être en mesure de pointer directement dansline
. Si vous faites cela, vous aurez besoin de définir le caractère immédiatement après chaque " mot " à\0
.OriginalL'auteur lxop