L'écriture de mon propre coquille... coincé sur des tuyaux?
Depuis quelques jours, j'ai été de tenter d'écrire mon propre coquille de mise en œuvre, mais il me semble avoir été coincé sur l'obtention des tuyaux pour fonctionner correctement. Je suis capable d'analyser une ligne de fourche et désactiver les commandes entre les tuyaux (ex: ls | sort) individuellement mais ne semble pas possible de les obtenir à de la pipe d'entrée de l'un en l'autre.
Je pense que je ne comprends pas comment les utiliser dup2() et les tuyaux correctement.
J'ai maintenant compris mon code qui ne répond toujours pas... 🙁 Donc coincé...
void forkAndExecute( char* arrayOfWords[] , vector<pid_t> *vectorOfPIDs , bool hasNextCmd , bool hasPrevCmd) {
int fd[ 2 ];
pid_t pid;
if( hasNextCmd ){
pipe(fd);
}
pid = fork();
//error if PID < 0
if( pid < 0 ) {
cerr << ">>> fork failed >>>" << endl;
exit(-1);
}
//child process if PID == 0
else if( pid == 0 ) {
if ( hasPrevCmd ){
dup2(fd[0] , 0);
close(fd[0]);
close(fd[1]);
}
if ( hasNextCmd ){
dup2(fd[1],1);
close(fd[0]);
close(fd[1]);
}
execvp( arrayOfWords[0] , arrayOfWords );
cout << ">>> command not found >>>" << endl;
//if logic reaches here, exec failed
exit(0);
}
//parent process
else{
close(fd[0]);
close(fd[1]);
//if( ! isLastCmd ){
//}
vectorOfPIDs->push_back(pid);
}
}
OriginalL'auteur 101010110101 | 2009-09-22
Vous devez vous connecter pour publier un commentaire.
Première suggestion: constantes Symboliques sont mieux que des numéros de magie.
Deuxième suggestion: Prendre du recul et de réfléchir à ce que vous essayez d'accomplir.
Vous voulez lancer deux processus, avec le premier processus de la sortie standard (stdout) connecté à la deuxième processus de stdin. Droit?
Donc, en C, cela signifie que vous avez besoin de prendre l'appel
pipe
, passerfd[PIPE_WRITE]
pour le premier enfant, qui vadup2
à 1, et de passerfd[PIPE_READ]
pour le deuxième enfant, qui vadup2
à 0.Simplement en regardant
forkAndExecute'
s prototype montre qu'il ne peut pas le faire:Il ne gère qu'une seule commande, et de l'examen que de la liste d'arguments, à moins qu'il recourt à mal les variables globales, il n'y a aucun moyen pour elle de recevoir un descripteur de fichier à partir de son PrevCmd ou de recevoir un descripteur de fichier à partir de son NextCmd.
Réfléchir à la façon de gérer les descripteurs de fichier que vous avez besoin, et la refonte
forkAndExecute
pour être en mesure d'utiliser ces.OriginalL'auteur
Le processus général permettrait d'ajouter la gestion d'erreur à ce processus de base (pseudo-code):
Créer le conduit. Puis fourche de l'enfant, les processus afin qu'ils héritent. Remapper les descripteurs de fichiers à 0 (stdin) et 1 (stdout) de sorte que le processus de lecture et d'écriture des endroits appropriés. Fermez tout en restant descripteur de fichier que vous ne voulez pas que les processus enfants de voir ou de bloquer sur quand le travail est fini. Exec le réel les processus enfants. Attendre qu'ils aient fini, et vous avez terminé!
==0
et utilisant l'une des variantes deexec
etwait
, elle a établi comme valide C et fait le travail sur son deuxième essai. Deuxwait
les appels sont nécessaires.tout d'abord, merci pour essayer d'aider. D'autre part, je suis toujours bloqué hehe. Je suis vraiment pas pourquoi sa ne fonctionne pas.
"Coincé" comment? Avez-vous essayé l'exemple de code que j'ai posté? Il fonctionne vraiment (converti en C, voir mon premier commentaire), je l'ai vérifié après la publication. Avez-vous manqué l'application du concept à votre base de code?
le problème est que je N nombre de tuyaux. Donc, chaque fois que je vais dans le forkAndExecute méthode, je ne la fourche une fois. Je vais avoir du mal à comprendre comment enregistrer et utiliser l'ancien descripteurs de fichiers.
JB pouvez-vous donner des précisions sur les "Deux d'attente des appels sont nécessaires" s'il vous plaît?
OriginalL'auteur
ok C'est de travailler pour moi. Espérons que cela vous aide:
OriginalL'auteur
Voici un tutoriel sur les pipes UNIX, en particulier sur la façon de construire des piplines dans une coquille d'architecture:
http://www.cse.ohio-state.edu/~mamrak/CIS762/pipes_lab_notes.html
Pas beaucoup entièrement écrit de code, mais il décrit les concepts assez bien.
Vous pouvez également télécharger le code source pour pratiquement n'importe quel environnement, tels que bash, tcsh, zsh, etc.
OriginalL'auteur
Essayez de lire le le code source de Bash de voir comment ils ont fait.
OriginalL'auteur
Quand j'avais besoin de faire un similaires shell il y a quelques années, j'ai utilisé le livre Pratique De La Programmation Unix.
Il est vraiment utile pour des exemples sur de nombreux CIB sujets. J'ai encore une copie sur mon bureau que je référence de temps à autre. Pour 2 $ - $9 utilisé, c'est une très bonne valeur pour ce que vous obtenez.
Pour ce que ça vaut, juste pensé que je le mentionne.
OriginalL'auteur
Ici sont les notes sur un tuyau de la Programmation des Systèmes de classe, j'ai pris le dernier semestre.
OriginalL'auteur
Vous vous connectez chaque programme, à sa propre production. Vous avez probablement voulu relier chacun des programmes de sortie de la prochaine entrée de la place.
Au lieu d'aller pour le cas général de la n processus dans un pipeline, vous devriez commencer avec un base de deux et d'élargir à partir de là. Vous aurez une meilleure compréhension de la façon dont les descripteurs de fichiers sont branchés les uns des autres si vous passez par l'extension de code de travail, au lieu de tirer directement de la structure complexe.
Il n'est pas évident pour moi comment vous pouvez mettre en œuvre ce de manière récursive, mais pourquoi pas. Ce qui le rend un peu difficile est que nous ne pouvons pas nous pondent un processus de
pr|pr
schéma jusqu'à ce que le tuyau lui-même est créé. Dans plusieurs tuyaux de l'installation, cela s'étend à: on ne peut pas spawn tout le processus jusqu'à ce que deux de ses entrée et de sortie des tuyaux sont créés.OriginalL'auteur
bien, je n'ai pas de réponse, mais je suis en train de travailler sur le même problème atm. Je vais partager ce que j'ai. Il fonctionne pour les deux commandes, mais une fois qu'elle est en cours d'exécution, i/o sont cassés. d'une manière étrange, je n'ai pas été en mesure de comprendre encore. appelez le plombier!
J'ai le sentiment que ça a à voir avec ce qui suis ou ne suis pas le faire après le wait()
wait
; autrement, le processus de lecture peut bloquer, en attendant que des données à partir de l'ouverture d'un autre côté.OriginalL'auteur