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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
/* Le programme a au minimum deux arguments :
* - un nom de fichier, existant ou non ;
* - une commande ;
* - tous les arguments suivants sont considérés comme des paramètres de la commande.
* Le programme ouvre en écriture le fichier dont le nom est passé en premier argument sur la ligne de commande
* et redirige sa propre sortie standard (descripteur de fichier = 1) vers ce fichier à l’aide de l’appel système dup2(2).
* Ensuite, le programme exécute la commande passée en deuxième argument en lui passant tous les arguments suivants le cas échéant.
* Si le nom passé en premier argument correspond au nom d’un fichier existant, alors le contenu de ce fichier est écrasé. Sinon, le fichier est créé.
*/
#include <unistd.h> // dup2(2),execvp(3),close(2)
#include <sys/types.h> // open(2)
#include <sys/stat.h> // open(2)
#include <fcntl.h> // open(2)
#include <stdio.h> // perror(3)
#include <string.h>
int main(int argn,char** argv)
{
int desc_fic;
// deux arguments au minimum
if(argn<3)
{
perror("Usage : ./sortie_standard nom_fichier commande [parametres_commande]\n");
return 1;
}
// On ouvre le fichier en écriture seulement si on redirige la sortie standard, et en lecture si on redirige l'entrée standard.
if(strcmp(argv[0],"redir1")==0 || strcmp(argv[0],"redir1")==2) desc_fic=open(argv[1],O_WRONLY);
else if(strcmp(argv[0],"redir0")==0) desc_fic=open(argv[1],O_RDONLY);
// Pour une redirection de la sortie standard ou de l'erreur standard : Si le fichier existe, alors le contenu de ce fichier est écrasé, sinon il est crée en écriture seulement avec des droits en // lecture et en écriture pour l'utilisateur.
// Pour une redirection de l'entrée standard : si le fichier existe, son contenu n'est pas écrasé, et s'il n'existe pas on affiche un message d'erreur.
if(desc_fic==-1)
{
if (strcmp(argv[0],"redir1")==0 || strcmp(argv[0],"redir1")==2)
{
desc_fic=open(argv[1],O_CREAT|O_WRONLY,00600); // 600 = r+w pour l'utilisateur
// Si on ne réussit pas à créer le fichier destination, on affiche l'erreur et on retourne une valeur non nulle.
if(desc_fic==-1)
{
perror("erreur d'ouverture en ecriture du fichier (creation)\n");
return 2;
}
}
else if(strcmp(argv[0],"redir0")==0) perror("Le fichier n'existe pas.\n");
}
else
{
if (strcmp(argv[0],"redir1")==0 || strcmp(argv[0],"redir1")==2)
{
close(desc_fic);
desc_fic=open(argv[1],O_CREAT|O_WRONLY|O_TRUNC,00600);
// Si on ne réussit pas à créer le fichier destination, on affiche l'erreur et on retourne une valeur non nulle.
if(desc_fic==-1)
{
perror("erreur d'ouverture en ecriture du fichier (remise a zero)\n");
return 2;
}
}
}
// On substitue au descripteur de fichier de la sortie standard le descripteur de fichier ouvert dans le programme.
if(strcmp(argv[0],"redir1")==0) dup2(desc_fic,1);
else if(strcmp(argv[0],"redir0")==0) dup2(desc_fic,0);
else if(strcmp(argv[0],"redir2")==0) dup2(desc_fic,2);
// On ferme le fichier.
close(desc_fic);
//Lorsqu'un programme appelle la fonction execvp(3), le processus cesse immédiatement d'exécuter ce programme et commence l'exécution d'un autre depuis le début, en supposant que l'appel à execvp se déroule correctement.
// Le premier argument doit pointer sur le nom du fichier associé au programme à exécuter.
// Le deuxième argument est un tableau de pointeurs qui doit se terminer par un pointeur NULL. Il constitue les arguments disponibles pour le programme à exécuter.
if(execvp(argv[2],argv+2)==-1) // argv+2 est le tableau de chaînes de caractères argv privé de ses deux premières chaînes
{
perror("Erreur : commande incorrecte\n");
return 3;
}
return 0;
} |
Partager