Bonjour,
Etant debutant dans la programmation systeme, j'essaie de resoudre un exercice sur les processus.
Le but de l'exercice est de faire un programme en ligne de commande prenant pour argument une chaine de la forme : " COMMANDE ARGUMENTS &> FICHIER" qui execute COMMANDE ARGUMENT en dirigeant stdin et stderr vers FICHIER.
exemple:
touch dummy
chmod 200 dummy
./programme "cat *.c &> file.out"
qui devrait envoyer dans file.out tous les fichiers avec extension ".c" et un message d'erreur pour le fichier dummy.
Je dois utiliser les fonctions fork, une version d'exec, strtok, et dup/dup2. (2 versions demandées une avec dup une avec dup2)
J'ai codé la version suivante, mais j'ai un souci lorsque j'appelle une commande utilisant un argumant de la forme *.extension comme dans l'exemple ci dessus, pour le reste je pense que ca marche. Le probleme est que je ne vois pas du tout ou est le probleme. Auriez vous une idée ?
Voici ce que j'obtiens avec mon programme:
$ ./programme "cat *.c &> file.out"
$ cat file.out
cat: *.c: Aucun fichier ou dossier de ce type
#include stdlib.h
#include stdio.h
#include unistd.h
#include errno.h
#include sys/wait.h
#include string.h
#include fcntl.h
void usage()
{
fprintf(stderr,"Usage: execute \"command argument &> file\"\n");
exit(1);
}
int main(int argc, char * argv[])
{
char *command,*currStr;
char * fileName;
int fd,i;
char ** arg=NULL;
pid_t exc=0;
if (argc!=2) usage();
command = strtok(argv[1],"&>");
fileName = strtok(NULL,"&> ");
currStr = strtok(command," ");
i=1;
do{
arg=(char**) realloc(arg,i * sizeof(char*));
arg[i-1]=currStr;
i++;
currStr=strtok(NULL," ");
} while(currStr!=NULL);
arg=(char**) realloc(arg,i * sizeof(char*));
arg[i-1]=NULL;
exc=fork();
if (exc==-1)
{
fprintf(stderr,"error in fork()");
exit(1);
}
if (exc==0)
{
fd=open(fileName,O_WRONLY | O_CREAT | O_APPEND,0644);
if (fd < 0)
{
perror("open");
exit(1);
}
close (STDOUT_FILENO);
close (STDERR_FILENO);
if (dup(fd)
perror ("dup");
exit(1);
}
close(fd);
execvp(arg[0],arg);
printf("brr");
}
wait(NULL);
}
# Une petite idée
Posté par ǝpɐןƃu∀ nǝıɥʇʇɐW-ǝɹɹǝıԀ (site web personnel) . Évalué à 2.
Dans un répertoire contenant deux fichiers :
a.c
b.c
si je fais cat *.c, la commande cat reçoit comme arguments, non pas "*.c" mais "a.c b.c".
Il me semble que le problème décrit vient de là. Pour éviter que le shell ne fasse la transcription automatique il faut rajouter des quotes : '
Est-ce que ces considérations résolvent/expliquent partiellement le problème rencontré ?
« IRAFURORBREVISESTANIMUMREGEQUINISIPARETIMPERAT » — Odes — Horace
[^] # Re: Une petite idée
Posté par ✅ ffx . Évalué à 3.
un shell habituel interprète les caractères jokers comme * et les développe en noms de fichiers avant de les envoyer à l'application externe
ici le programme se contente d'envoyer les astérisques au programme cat qui ne sait pas les interpréter (qui a dit que les chats étaient intelligents ?)
[^] # Re: Une petite idée
Posté par ǝpɐןƃu∀ nǝıɥʇʇɐW-ǝɹɹǝıԀ (site web personnel) . Évalué à 2.
« IRAFURORBREVISESTANIMUMREGEQUINISIPARETIMPERAT » — Odes — Horace
[^] # Re: Une petite idée
Posté par lylo01 . Évalué à 1.
# man 3 glob|wordexp
Posté par GeneralZod . Évalué à 3.
Pour obtenir un comportement similaire, tu peux utiliser la fonction C ISO fnmatch pour comparer les motifs (à charge pour toi de récupérer les noms de fichiers du répertoire courant), soit la fonction Posix tout-en-un glob.
Si tu cherches des détails sur le globbing (attention, ce ne sont pas des expressions régulières) ==> man 7 glob
La version 2001 de Posix offre également la fonction wordexp qui offre l'expansion du tilde et pleins d'autre chose (très pratique pour implémenter un mini shell).
Autre chose, pour gérer la redirection des flux standards, utilise plutôt dup2, ton code sera plus court et plus explicite.
dup2(fd,STDOUT_FILENO);
dup2(fd,STDERR_FILENO);
[^] # Re: man 3 glob|wordexp
Posté par lylo01 . Évalué à 1.
Merci beaucoup !
[^] # Re: man 3 glob|wordexp
Posté par lylo01 . Évalué à 0.
Merci beaucoup pour votre précieuse aide !
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.