Bonjour, alors voilà, cela fait plusieurs jours que je bloque sur quelque chose et même après avoir lu plein de forum, aucune solution ne marche...
Je me permet donc de créer un nouveau poste et espère être dans la bonne section...

Je dois développer pour un exercice un serveur qui permettra d'exécuter des commandes pour des clients en C. Mon problème est que, malgré une redirection de la sortie standard avant l'execv dans le serveur, les résultat des commandes continue de s'afficher dans le terminal du serveur au lieu de s'afficher dans le terminal du client.

L'idée est qu'il faudrait récupérer le résultat à l'aide d'un tube nommé depuis le client et l'afficher, mais même à l'aide d'une simple redirection dans un fichier, cela ne marche pas... le fichier reste vide et le terminal affiche toujours le résultat.

Voici le code complet: (j'ai mit en gras la zone concernée)

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <pthread.h>
#include <signal.h>

#include "file_synchronisee/file_sync.h"
#include "lanceur_de_commande.h"

typedef struct {
	char *path_fonction;
	char *argv[];
} arg_execv;

/*
 * Lance la commande en fonction de arg, un type elem.
 */
void *lance_commande(void *arg);

/*
 * Prend en argument un espace mémoire partagé de char codée
 * selon notre définition et renvoie une structure arg_execv permettant
 * d'éxecuter la commande.
 */
arg_execv *string_arg_execv(char *tab);

/*
 * Permet d'intercepter le signal SIGQUIT mettant proprement fin au
 * programme.
 */
void gestionnaire(int sig);

/*
 * Met fin au serveur et signal l'erreur.
 */
void fin_serveur_echec();
 
/*
 * Met fin au serveur et signal la réussite.
 */
void fin_serveur_succes(); 


int main(void) {
	// Création de l'espace de mémoire partagée pour la file
	int shm_fd = shm_open(NOM_FILE, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
  if (shm_fd == -1) {
    perror("shm_open");
    exit(EXIT_FAILURE);
  }
  
  // Redéfinition de la taille de cet espace mémoire.
  if (ftruncate(shm_fd, sizeof(file)) == -1) {
    perror("ftruncate");
    fin_serveur_echec();
  }
  
  // Mapage de cet espace mémoire sur le processus.
  file *file_sync = mmap(NULL, sizeof(file), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
  if (file_sync == MAP_FAILED) {
    perror("sem_open");
    fin_serveur_echec();
  }
  
  // On ferme le descripteur désormais inutilisé.
  if (close(shm_fd) == -1) {
		perror("close shm_fd");
		fin_serveur_echec();
	}
  
  // Initialisation de la file.
  *file_sync = file_vide();
  
  // Initialisation de l'action.
  struct sigaction action;
  action.sa_handler = gestionnaire;
  action.sa_flags = 0;
  if (sigfillset(&action.sa_mask) == -1) {
    perror("sigfilltset");
    fin_serveur_echec();
  }
  
  // On change la fonction éxecuté à la réception du signal
  // SIGQUIT afin qu'elle mette fin au serveur proprement.
  if (sigaction(SIGINT, &action, NULL) != 0) {
		perror("Sigaction");
		fin_serveur_echec();
	}
  
  while (1) {
		// On malloc un nouvelle element e à chaque fois pour éviter tous
		// problème si plusieur thread travaille sur le même e.
		elem *e = malloc(sizeof(elem));
		if (e == NULL) {
			perror("Probleme de malloc");
			fin_serveur_echec();
		}
		
		// On tente de défiler un élèment de la file. Cet opération ne sera
		// effectué que lorsque qu'au moin un élèment sera présent dans la
		// file.
		if (file_sync == NULL) {
			fin_serveur_echec();
		}
		*e = defiler(file_sync);
		
		// On averti que l'on a bien recus la demande.
		printf("J'ai recus une commande\n");
		pthread_t th;
		if (pthread_create(&th, NULL, lance_commande, e) != 0) {
			perror("pthread_create");
			fin_serveur_echec();
		}
		
		// Cela garantit que les ressources mémoire consommées par th seront
		// immédiatement libérées lorsque l'exécution de th s'achèvera.
		if (pthread_detach(th) != 0) {
			perror("pthread_detach");
			fin_serveur_echec();
		}
	}
}

void *lance_commande(void *arg) {
	elem *e = (elem *) arg;
	printf("Commande en cours de lancement...\n");
	int sortie;
	switch (fork()) {
		case -1:
			perror("fork");
			fin_serveur_echec();
			break;
		// Traitement des erreurs différents dans le fils.
		// On n'appelera pas fin_serveur_echec(). (processus indépendant)
		case 0:
			// Gestion de la sortie standart du programme prochainement
			// executé
			if ((sortie = open(e->tube_sortie, O_WRONLY) == -1)) {
				perror("open");
				exit(EXIT_FAILURE);
			}
			
			// Redirection de la sortie
			if (dup2(sortie, STDOUT_FILENO) == -1) {
				perror("dup2");
				exit(EXIT_FAILURE);
			}
			if (dup2(sortie, STDERR_FILENO) == -1) {
				perror("dup2");
				exit(EXIT_FAILURE);
			}
			
			fprintf(stdout, "Voila, aucune redirection\n");

			// Fermeture des descripteurs inutilisés
			if (close(sortie) == -1) {
				perror("close(sortie)");
				exit(EXIT_FAILURE);
			}
			
			// Ouverture de l'espace mémoire partager de e contenant la
			// commande à éxecuter.
			int shm_fd = shm_open(e->nom, O_RDWR, S_IRUSR | S_IWUSR);
			if (shm_fd == -1) {
				perror("shm_open");
				exit(EXIT_FAILURE);
			}
			
			// Mapage de cet espace mémoire partager sur le processus.
			char *shm_ptr = mmap(NULL, e->taille, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
			if (shm_ptr == MAP_FAILED) {
				perror("sem_open");
				exit(EXIT_FAILURE);
			}
			
			arg_execv *tampon = string_arg_execv(shm_ptr);
			execv(tampon->path_fonction, tampon->argv);
			free(tampon);
			free(e);
			perror("execv");
			exit(EXIT_FAILURE);
		default:
			break;
	}
	
	free(e);
	printf("Tache terminer.\n");
	pthread_exit(NULL);
}

arg_execv *string_arg_execv(char *tab) {
	arg_execv *resultat = malloc(sizeof(arg_execv));
	if (resultat == NULL) {
		perror("Malloc");
		exit(EXIT_FAILURE);
	}
	
	resultat->path_fonction = tab;
	resultat->argv[0] = tab;
	int condition = 0;
	int i = 1;
	while (!condition) {
		if (*tab == '\0') {
			if (*(tab + 1) == '\0') {
				resultat->argv[i] = NULL;
				condition = 1;
			} else {
				resultat->argv[i] = tab + 1;
				++i;
			}
		}
		tab += 1;
	}
	return resultat;
}

void gestionnaire(int sig) {
	if (sig < 0) {
		fprintf(stderr, "Signal incorrecte");
		fin_serveur_echec();
	}
	printf("\nServeur fermer correctement...\n");
	fin_serveur_succes();
}

void fin_serveur_echec() {
	// On supprime l'espace réservé à la file.
  if (shm_unlink(NOM_FILE) == -1) {
    perror("shm_unlink");
  }
  
  exit(EXIT_FAILURE);
}

void fin_serveur_succes() {
	// On supprime l'espace réservé à la file.
  if (shm_unlink(NOM_FILE) == -1) {
    perror("shm_unlink");
    exit(EXIT_FAILURE);
  }
  
  exit(EXIT_SUCCESS);
}

voici le code du client:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <string.h>

#include "../file_synchronisee/file_sync.h"
#include "../lanceur_de_commande.h"

#define NOM_ESPACE_MEMOIRE "/mon_espace_memoire5645484648784"
#define TUBE_SORTIE "/home/maxime/Bureau/Projet_SE/client/tube_sortie"

int main(void) {
	elem e;
	
  if (mkfifo(TUBE_SORTIE, S_IRUSR | S_IWUSR) == -1) {
    perror("mkFifoOut");
    exit(EXIT_FAILURE);
  }
	
	strcpy(e.tube_sortie, TUBE_SORTIE);
	strcpy(e.nom, NOM_ESPACE_MEMOIRE);
	
	// Création de l'espace mémoire partagée
	int shm_fd = shm_open(NOM_ESPACE_MEMOIRE, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
  if (shm_fd == -1) {
    perror("shm_open1");
    exit(EXIT_SUCCESS);
  }
  
  // Redimension de l'espace mémoire partager selon la commande à
  // éxécuter.
  if (ftruncate(shm_fd, 50) == -1) {
    perror("ftruncate");
    exit(EXIT_FAILURE);
  }
  
  char *shm_ptr = mmap(NULL, 50, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
	if (shm_ptr == MAP_FAILED) {
		perror("sem_open");
		exit(EXIT_FAILURE);
	}
  
  // Ecriture de la commande à éxécuter selon notre codage dans l'espace
  // de mémoire partager.
  strcpy(shm_ptr, "/bin/ls\0\0");
  e.taille = 50;
  shm_fd = shm_open(NOM_FILE, O_RDWR, S_IRUSR | S_IWUSR);
  if (shm_fd == -1) {
    perror("shm_open2");
    exit(EXIT_FAILURE);
  }
  
	file *file_sync = mmap(NULL, sizeof(file), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
	if (file_sync == MAP_FAILED) {
		perror("sem_open");
		exit(EXIT_FAILURE);
	}
  
  enfiler(file_sync, e);
  
  int sortie;
  // Lecture du résultat dans le tube.
	if ((sortie = open(TUBE_SORTIE, O_RDONLY) == -1)) {
		perror("open");
		exit(EXIT_FAILURE);
	}
	printf("%d\n", sortie);
	
	ssize_t n;
	char c;
	while ((n = read(sortie, &c, sizeof(char))) > 0) {
		printf("%c", c);
	}
	if (n == -1) {
		perror("read");
		exit(EXIT_FAILURE);
	}
	
	// Suppression du tube et de l'espace mémoire.
	if (close(sortie) == -1) {
		perror("close");
		exit(EXIT_FAILURE);
	}
	
	if (unlink(TUBE_SORTIE) == -1) {
    perror("unlink");
    exit(EXIT_FAILURE);
  }
  
  if (shm_unlink(NOM_ESPACE_MEMOIRE) == -1) {
    perror("shm_unlink");
    exit(EXIT_FAILURE);
  }
			
  return EXIT_SUCCESS;
}
Merci pour votre aide !