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
|
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/dir.h>
#include <sys/types.h>
#define MAX_PROCESS 4
void
my_perror (FILE *fp, const char *msg)
{
fprintf (fp, "%s: %s\n", msg, strerror (errno));
}
void
wait_for_a_task (int *nb_tasks)
{
int pid;
int status;
printf ("%10d> Il y a actuellement %d processus qui tournent simultanément\n", getpid (), *nb_tasks - 1);
printf ("%10d> J'attends la terminaison d'un fils...\n", getpid ());
pid = waitpid (-1, &status, WUNTRACED);
if (WIFEXITED (status))
printf ("%10d> \t\tchild (%d) terminated with return code (%d)\n", getpid (), pid, WEXITSTATUS (status));
else
if (WIFSIGNALED (status))
printf ("%10d> \t\tchild (%d) killed by signal (%d)\n", getpid (), pid, WTERMSIG (status));
else
printf ("%10d> \t\tchild (%d) terminated\n", getpid (), pid);
/* un process de moins */
(*nb_tasks)--;
}
int
chomp (char *s)
{
int chomped = 0;
char *p = strchr (s, '\n');
if (p != NULL)
{
*p = '\0';
chomped = 1;
}
return chomped;
}
int
process_file (const char *pathname, const char *filename)
{
char in_filepath [PATH_MAX]; /* input file path */
char out_filepath [PATH_MAX]; /* output file path */
FILE *in_fp = NULL; /* input file pointer */
FILE *out_fp = NULL; /* output file pointer */
char buffer [BUFSIZ];
int i = 0;
int value;
printf ("%10d> Passage dans process_file()\n", getpid ());
/* Construction des noms de fichier avec leur chemin */
sprintf (in_filepath, "%s/%s", pathname, filename);
sprintf (out_filepath, "%s/%s.out", pathname, filename);
/* Ouverture du fichier en sortie */
out_fp = fopen (out_filepath, "w");
if (out_fp == NULL)
{
my_perror (out_fp, out_filepath);
return -1;
}
/* On y écrit quelques traces */
fprintf (out_fp, "%10d> Passage dans process_file()\n", getpid ());
fprintf (out_fp, "%10d> Processing file '%s' ...\n", getpid (), in_filepath);
fprintf (out_fp, "%10d> Creating file '%s' ...\n", getpid (), out_filepath);
fprintf (out_fp, "%10d> ouverture en lecture du fichier '%s'...\n", getpid (), in_filepath);
/* Ouverture du fichier en entrée */
in_fp = fopen (in_filepath, "r");
if (in_fp == NULL)
{
my_perror (out_fp, in_filepath);
fclose (out_fp);
return -1;
}
fprintf (out_fp, "%10d> ...fichier '%s' ouvert en lecture\n", getpid (), in_filepath);
/* Traitement du fichier */
while (fgets (buffer, BUFSIZ, in_fp))
{
chomp (buffer);
fprintf (out_fp, "%10d> '%s' read from file\n", getpid (), buffer);
value = atoi (buffer);
fprintf (out_fp, "%10d> Waiting for %d seconds ...\n", getpid (), value);
sleep (value);
i++;
}
/* Fin de traitement */
fprintf (out_fp, "%10d> Fin.\n", getpid ());
/* Fermeture des fichiers */
fclose (in_fp);
fclose (out_fp);
return 0;
}
/* Fonction volontairement simplissime de matching: */
/* => Si "filepath" contient "substr", c'est gagné! */
int
file_matches (const char *filepath, const char *substr)
{
char *p = NULL;
p = strstr (filepath, substr);
if (p == NULL)
return 0;
p = strstr (filepath, ".txt");
if (p == NULL)
return 0;
return 1;
}
long
process_dir (const char *src_dir, const char *substr)
{
DIR *pd;
struct dirent *cur;
long file_index;
int pidfils;
int nb_tasks;
int rc;
printf ("%10d> Passage dans process_dir()\n", getpid ());
/* Ouvrir le répertoire de données */
pd = opendir (src_dir);
if (pd == NULL)
{
perror (src_dir);
return -1;
}
/* Parcourir le répertoire de données */
file_index = 0;
nb_tasks = 0;
while ((cur = readdir (pd)) != NULL)
{
if (cur-> d_name[0] != '.')
{
/* file matching */
rc = file_matches (cur-> d_name, substr);
if (rc == 1)
{
printf ("%10d> --- Substring '%s' matches file '%s'.\n", getpid (), substr, cur-> d_name);
/* file matching */
pidfils = fork ();
switch (pidfils)
{
case -1:
perror ("fork");
closedir (pd);
exit (EXIT_FAILURE);
case 0:
closedir (pd);
process_file (src_dir, cur-> d_name);
exit (EXIT_SUCCESS);
}
file_index++;
nb_tasks++;
/* Si nombre MAX_PROCESS de processus atteint */
if (nb_tasks > MAX_PROCESS)
{
wait_for_a_task (&nb_tasks);
}
}
else
{
printf ("%10d> --- Sorry. Substring '%s' does not match file '%s'.\n", getpid (), substr, cur-> d_name);
}
}
}
/* Fermer le répertoire de données */
closedir (pd);
/* On attend que se terminent les MAX_PROCESS processus résiduels */
while (nb_tasks != 0)
{
wait_for_a_task (&nb_tasks);
}
/* Programme principal exécuté par le père */
printf ("%10d> Fin du processus père\n", getpid ());
return file_index;
}
int
main (void)
{
int rc = process_dir (".", "data_");
printf ("%10d> process_dir() has returned %d\n", getpid (), rc);
exit (EXIT_SUCCESS);
} |
Partager