Hello there!
I tried to make this exercise:
Code:
/*
* The father process receives from the command line the name of a file and a (non empty) list of directories where
* it has to search the file.
* It then creates a clone process for every directory whose task is to search (in the directory and all of its subdirectories) for files
* whose name matches with the string received as a parameter.
* All the filenames found are returned to the father (NULL is passed in the case no match occourred).
* The father waits for all the processes to terminate and then displays the result of the search.
* example of usage: program STRING /home/username
* example of output: /home/username/aSTRINGx.htm
* /home/username/foo/anotherSTRING.txt
*/
and my program is pretty long.. Actually i'd like to focus your attention on just one aspect which (i cannot understand why) is wrong.
I defined this struct:
Code:
struct arguments{
char directory[256];
char *key;
int numMatches;
char *matches[];
};
typedef struct arguments Arguments;
so directory is an array of char instead of being a char *..
in the main i take the name of the string to be found (key) and several directories (one or more) from the char *argv[].. the code looks like this (i omit some redundant code which consists mainly of controls):
Code:
int main (int argc,char *argv[])
{
...
int nclones=argc-2;
char *key=argv[1];
int i;
Arguments *args;
args=(Arguments *) malloc (nclones*sizeof(Arguments) );
...
for (i=0;i<nclones;i++)
{
strcpy(args[i].directory,argv[i+2]); //***************************************
args[i].key=key;
args[i].matches[0]=NULL;
args[i].numMatches=0;
}
pid_t *pid_clones;
pid_clones = (pid_t *) malloc (sizeof (pid_t)*nclones);
....
int *stacks;
stacks=(int *)malloc(1024*sizeof(int)*nclones);
.....
//Now it's time to create the clones
for (i=0;i<nclones;i++)
{
pid_clones[i]=clone(search,&stacks[(i+1)*1024],CLONE_VM,&args[i]); //************
....
}
now the problem is that in the second clone (in the case i want to search 2 directories) the struct's directory is corrupted.. the search function starts like this:
Code:
int search (void *args)
{
Arguments *a = (Arguments *)args;
pid_t pid=getpid();
printf("I'm clone %d and have to search all the files whose name contains '%s' into the directory '%s'\n",(int)pid,
a->key,a->directory);
....
and the beginning of the output, in the case of this command line:
Code:
programname time /usr/include/sys /usr/include/
looks like this:
Code:
I'm clone 17093 and have to search all the files whose name contains 'time' into the directory '/usr/include/sys'
I'm clone 17094 and have to search all the files whose name contains 'time' into the directory 'Xx���'
what did i wrong?
thanks x your help!
PS: just in case, the whole program is this (i have still to solve the recursion on the subdirectories):
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sched.h>
#include <dirent.h>
#include <sys/time.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <wait.h>
struct arguments{
char directory[256];
char *key;
int numMatches;
char *matches[];
};
typedef struct arguments Arguments;
int search (void *args)
{
Arguments *a = (Arguments *)args;
pid_t pid=getpid();
printf("I'm clone %d and have to search all the files whose name contains '%s' into the directory '%s'\n",(int)pid,
a->key,a->directory);
struct stat statbuff;
struct dirent *entry;
DIR *dirPtr;
int countMatches=0;
size_t lenMatch;
dirPtr=opendir(a->directory);
chdir(a->directory);
if (dirPtr==NULL)
{
printf("Directory %s doesn't exist!\n",a->directory);
return 1;
}
while ((entry=readdir(dirPtr))!=NULL)
{
if (lstat(entry->d_name,&statbuff)==-1)
{
printf("BAD LSTAT\n");
return 0;
}
if ( S_ISDIR(statbuff.st_mode) &&
(strcmp(entry->d_name,".")!=0 && strcmp(entry->d_name,"..")!=0))
{
//TODO Visit a subdirectory
}
else if (S_ISREG(statbuff.st_mode))
{
if (strstr(entry->d_name,a->key)!=NULL)
{
lenMatch=strlen(entry->d_name);
lenMatch+=strlen(a->directory);
lenMatch++;
a->matches[countMatches]=(char *)malloc(lenMatch*sizeof(char));
strcpy(a->matches[countMatches],a->directory);
strcat(a->matches[countMatches++],entry->d_name);
}
}
}
chdir("..");
closedir(dirPtr);
a->numMatches+=countMatches;
return 0;
}
int main (int argc,char *argv[])
{
if (argc<3)
{
printf("Usage: searchClone filename directory1 directory2 ...\n");
return 1;
}
int nclones=argc-2;
char *key=argv[1];
int i;
Arguments *args;
args=(Arguments *) malloc (nclones*sizeof(Arguments) );
if (args==NULL)
{
printf ("out of memory\n");
return 1;
}
for (i=0;i<nclones;i++)
{
strcpy(args[i].directory,argv[i+2]);
args[i].key=key;
args[i].matches[0]=NULL;
args[i].numMatches=0;
}
pid_t *pid_clones;
pid_clones = (pid_t *) malloc (sizeof (pid_t)*nclones);
if (pid_clones==NULL)
{
printf ("out of memory\n");
return 1;
}
int *stacks;
stacks=(int *)malloc(1024*sizeof(int)*nclones);
if (stacks==NULL)
{
printf ("out of memory\n");
return 1;
}
//Now it's time to create the clones
for (i=0;i<nclones;i++)
{
pid_clones[i]=clone(search,&stacks[(i+1)*1024],CLONE_VM,&args[i]);
if (pid_clones[i]==-1)
{
printf("BAD CLONE\n");
return 1;
}
}
int clones_ended=0;
while (1)
{
waitpid(-1,NULL,__WCLONE);
clones_ended++;
if (clones_ended==nclones)
break;
}
int j;
for (i=0;i<nclones;i++)
{
printf("Clone %d found %d matches:\n",i+1,args[i].numMatches);
for (j=0;j<args[i].numMatches;j++)
{
printf("%s\n",args[i].matches[j]);
}
printf("\n");
}
return 0;
}