Bonjour à tous,
Je dois re-développer la fonction C system
: pour ce faire, j'utilise l'appel-système fork
qui permet de créer un processus enfant et c'est ce dernier qui doit exécuter la commande passée en paramètre à system
, en appelant exec
.
Ce que j'ai fait semble bien marcher (pas d'erreur de compilation ni d'exécution).
Le seul souci se situe au niveau du retour de ma méthode system
(appelée mySystem
dans mon code). Par exemple, dans mon processus enfant, quand je donne un shell inexistant à exec
et donc que cette dernière retourne -1, mon processus enfant s'arrête avec un exit code de -1 car c'est ce que je lui dis de faire. Le souci c'est que mon processus parent, qui récupère cet exit code grâce à un wait(&status)
, retourne… 255 et non -1.
Je ne comprends pas du tout pourquoi. J'ai bien fait attention à utiliser la macro WEXISTSTATUS dans le retour de mon mySystem
.
Donc voilà, est-ce que quelqu'un aurait une idée de ce qui ne va pas s'il vous plaît ?
Merci d'avance !
Source
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #include <stdio.h> #include <unistd.h> #include <sys/wait.h> #include <stdlib.h> pid_t pid; int mySystem(char*); int main(int argc, char* argv[]) { int result = mySystem("ls"); fprintf(stdout, "%i", result); return 0; } int mySystem(char* command) { pid = fork(); if(pid == -1) { perror("Fork"); return -1; // An error occurred => return -1 } else if (pid == 0) { // The child process will do the following execl("BLABLABLABLA MAUVAIS SHELL BLABLABLAA", "sh", "-c", command, NULL); // If this call doesn't fail, the following lines are not read perror("Exec"); // If (and only if) execl couldn't be called (bad shell's path, etc.)... exit(-1); // ..., we stop the child process and this one has an exit code equaled to -1 } /* * NOW, the child process ended because... : * 1. Either because of our "exit(-1)" after the "perror" (our source-code) * 2. OR because of an "exit(-1") of the command passed into the execl (source-code of the execl's command) * 3. OR because of the "exit(0)" of the command passed into the execl (source-code of the execl's command) */ // The parent process will execute the following lines (child process ended) int status = -1; if(wait(&status) == -1) { // We store into the var 'status' the exit code of the child process : -1 or 0 perror("Wait"); // Note that because we have only one process child, we don't need to do : while(wait(&status) > 0) {;;} return -1; } return WEXITSTATUS(status); // Our function mySystem returns this exit code } |
Edit : Topic résolu
Voici le code final (cas où command
vaut NULL
non-traité) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #include <stdio.h> #include <unistd.h> #include <sys/wait.h> #include <stdlib.h> pid_t pid; int mySystem(const char*); int main(int argc, char* argv[]) { int result = mySystem("ls"); fprintf(stdout, "%i", result); return 0; } int mySystem(const char* command) { pid = fork(); if(pid == -1) { perror("Fork"); return -1; // An error occurred => return -1 } else if (pid == 0) { // The child process will do the following execl("/bin/sh", "sh", "-c", command, NULL); // If this call doesn't fail, the following lines are not read perror("Exec"); // If (and only if) execl couldn't be called (bad shell's path, etc.)... exit(127); // ..., we stop the child process and this one has an exit code equaled to -1 } /* * NOW, the child process ended because... : * 1. Either because of our "exit(-1)" after the "perror" (our source-code) * 2. OR because of an "exit(-1") of the command passed into the execl (source-code of the execl's command) * 3. OR because of the "exit(0)" of the command passed into the execl (source-code of the execl's command) */ // The parent process will execute the following lines (child process ended) int status = -1; if(wait(&status) == -1) { // We store into the var 'status' the exit code of the child process : -1 or 0 perror("Wait"); // Note that because we have only one process child, we don't need to do : while(wait(&status) > 0) {;;} return -1; } if(WIFEXITED(status)) { return (signed char) WEXITSTATUS(status); // Our function mySystem returns this exit code } else { return -1; } } |