void process_source_directory(char *dir,char *cwd,char*copy_put,char**args_txl,char**source,Config *user_config) { DIR *dp; struct dirent *entry; struct stat statbuf; if((dp = opendir(dir)) == NULL) { fprintf(stderr,"cannot open directory: %s\n", dir); return; } chdir(dir); while((entry = readdir(dp)) != NULL) { lstat(entry->d_name,&statbuf); if(S_ISDIR(statbuf.st_mode)) { /* Found a directory, but ignore . and .. */ if(strcmp(".",entry->d_name) == 0 || strcmp("..",entry->d_name) == 0){ continue; } /* New dir path */ char *newDir = malloc(snprintf(NULL, 0, "%s/%s",dir,entry->d_name ) + 1); sprintf(newDir, "%s/%s",dir,entry->d_name); /* Recurse at a new indent level */ process_source_directory(newDir,cwd,copy_put,args_txl,source,user_config); } else{ char *dot = strrchr(entry->d_name, '.'); if (dot && !strcmp(dot, ".c")){ char *file = malloc(snprintf(NULL, 0, "%s/%s", dir,entry->d_name ) + 1); sprintf(file, "%s/%s",dir,entry->d_name); args_txl[4+TXL_OPTS]=file; process_source_file(file,cwd,copy_put,args_txl,source,user_config); free(file); } } } chdir(".."); closedir(dp); }
/* * Get a list of all files in the data directory. */ void libpqProcessFileList(void) { PGresult *res; const char *sql; int i; /* * Create a recursive directory listing of the whole data directory. * * The WITH RECURSIVE part does most of the work. The second part gets the * targets of the symlinks in pg_tblspc directory. * * XXX: There is no backend function to get a symbolic link's target in * general, so if the admin has put any custom symbolic links in the data * directory, they won't be copied correctly. */ sql = "WITH RECURSIVE files (path, filename, size, isdir) AS (\n" " SELECT '' AS path, filename, size, isdir FROM\n" " (SELECT pg_ls_dir('.', true, false) AS filename) AS fn,\n" " pg_stat_file(fn.filename, true) AS this\n" " UNION ALL\n" " SELECT parent.path || parent.filename || '/' AS path,\n" " fn, this.size, this.isdir\n" " FROM files AS parent,\n" " pg_ls_dir(parent.path || parent.filename, true, false) AS fn,\n" " pg_stat_file(parent.path || parent.filename || '/' || fn, true) AS this\n" " WHERE parent.isdir = 't'\n" ")\n" "SELECT path || filename, size, isdir,\n" " pg_tablespace_location(pg_tablespace.oid) AS link_target\n" "FROM files\n" "LEFT OUTER JOIN pg_tablespace ON files.path = 'pg_tblspc/'\n" " AND oid::text = files.filename\n"; res = PQexec(conn, sql); if (PQresultStatus(res) != PGRES_TUPLES_OK) pg_fatal("could not fetch file list: %s", PQresultErrorMessage(res)); /* sanity check the result set */ if (PQnfields(res) != 4) pg_fatal("unexpected result set while fetching file list\n"); /* Read result to local variables */ for (i = 0; i < PQntuples(res); i++) { char *path = PQgetvalue(res, i, 0); int64 filesize = atol(PQgetvalue(res, i, 1)); bool isdir = (strcmp(PQgetvalue(res, i, 2), "t") == 0); char *link_target = PQgetvalue(res, i, 3); file_type_t type; if (PQgetisnull(res, 0, 1)) { /* * The file was removed from the server while the query was * running. Ignore it. */ continue; } if (link_target[0]) type = FILE_TYPE_SYMLINK; else if (isdir) type = FILE_TYPE_DIRECTORY; else type = FILE_TYPE_REGULAR; process_source_file(path, type, filesize, link_target); } PQclear(res); }
int main(int argc, char**argv) { Config *user_config; char * cwd = getcwd(NULL, 0); int args_index=1; //Set "gstats.xml" location GSTATS_PATH=malloc(snprintf(NULL, 0, "%s/gstats.xml", cwd) + 1); sprintf(GSTATS_PATH, "%s/gstats.xml", cwd); if(argc==2){ open_GStats(GSTATS_PATH); if(strcmp(argv[args_index],"--gstats-clear")==0){ if(clear_GStats(GSTATS_PATH)==0){ printf("gstat-status: File %s deleted.\n", GSTATS_PATH); exit(EXIT_SUCCESS); }else{ fprintf(stderr, "gstat-status: Error deleting the file %s.\n", GSTATS_PATH); exit(EXIT_FAILURE); } }else if(strcmp(argv[args_index],"--gstats-collect")==0){ //Show stats char*args_cat[]={"cat",GSTATS_PATH,NULL}; startprogram(args_cat,NULL,0); exit(EXIT_SUCCESS); } close_GStats(GSTATS_PATH); } if(strcmp(argv[args_index],"--gstreamer")==0){ args_index++; preset_project=1; } if(strcmp(argv[args_index],"-v")==0){ user_config = processConfigFile(argv[2]); verbose_mode=1; args_index++; } user_config = processConfigFile(argv[args_index]); if(user_config==NULL){ fprintf(stderr,"error: incorrect arguments\n"); exit(EXIT_FAILURE); } if (cwd== NULL){ perror("getcwd() error"); exit(EXIT_FAILURE); } if (user_config) { char**source=user_config->source; //Duplicate the project in order to revert back to after mutations char *chptr = strrchr(user_config->sourceRootDir, '/'); long dif = chptr - user_config->sourceRootDir; char *copy_put =strndup(chptr+1, strlen(user_config->sourceRootDir)-dif); //Remove the copy of the program under test if it exists due to an execution terminated by the user cleanUp(copy_put); cleanUp("mutation_out"); //Create mutation_out mkdir("mutation_out",S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); //Create gcov_out mkdir("mutation_out/PUT",S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); //copy PUT char *args_cp[5]; args_cp[0]="cp"; args_cp[1]="-r"; args_cp[2]=user_config->sourceRootDir; args_cp[3]=copy_put; args_cp[4]=NULL; startprogram(args_cp,NULL,0); //Generate initial stats for PUT setenv("IS_MUTATE","false",1); runMake(copy_put,NULL,user_config->makeTestTarget); // CFG data for the PUT extractCFGBranches(copy_put,"mutation_out/PUT",NULL); // Valgrind data for the PUT ValgrindResult* valgrindResultPUT = genValgrindResult(cwd,"PUT","PUT",copy_put,user_config); if(valgrindResultPUT!=NULL){ PUTValgrindErrors = valgrindResultPUT->valgrind_error_count; } setenv("IS_MUTATE","true",1); if(user_config->testingFramework==1){ //Replace the CuTest library in the project with our modified library char * cutest_source = malloc(snprintf(NULL, 0, "%s/%s", copy_put,user_config->CuTestLibSource) + 1); sprintf(cutest_source, "%s/%s",copy_put , user_config->CuTestLibSource); if(user_config->CuTestVersion==1){ copy_file("CuTest/CuTest.forked.c",cutest_source); } else{ copy_file("CuTest/CuTest.forked2.c",cutest_source); } free(cutest_source); }else if(user_config->testingFramework==2 && user_config->CheckTestLibSource!=NULL){ //Replace the Check library in the project with our modified library char * check_source = malloc(snprintf(NULL, 0, "%s/%s", copy_put,user_config->CheckTestLibSource) + 1); sprintf(check_source, "%s/%s",copy_put , user_config->CheckTestLibSource); //Check if a preset project is being run if(preset_project==1){ copy_file("libcheck-presets/check.c.gstreamer",check_source); }else{ copy_file("libcheck/src/check.c",check_source); } free(check_source); } //Initialize txl arguments in order to perform mutations on each source file char**args_txl = malloc((9+TXL_OPTS) * sizeof(char*));; args_txl[0]="txl"; args_txl[1]="mutator.Txl"; args_txl[2]="-size"; args_txl[3]="2048"; args_txl[2+TXL_OPTS]="-o"; args_txl[5+TXL_OPTS]="-"; args_txl[6+TXL_OPTS]="-mut_out"; args_txl[8+TXL_OPTS]=NULL; //mutator.txl path args_txl[1]=malloc(snprintf(NULL, 0, "%s/mutator.Txl",cwd) + 1); sprintf(args_txl[1],"%s/mutator.Txl",cwd); //Store mutation_results_path mutation_results_path = malloc(snprintf(NULL, 0, "%s/%s/%s",cwd, copy_put,"mutation_results.log") + 1); sprintf(mutation_results_path, "%s/%s/%s",cwd, copy_put, "mutation_results.log"); //Create a temporary log file in order to keep track of mutation results temp_results_path = malloc(snprintf(NULL, 0, "%s/%s/%s",cwd, copy_put,"temp_results.log") + 1); sprintf(temp_results_path, "%s/%s/%s",cwd, copy_put,"temp_results.log"); //Create temparary environment variables to store temp_results_path and mutation_results_path to be accessed by child processes setenv("MUTATION_RESULTS_PATH",mutation_results_path,1); setenv("TEMP_RESULTS_PATH",temp_results_path,1); //Because we run the test suite again from Valgrind, in order to prevent duplicate output, we uniquely identify this program setenv("IS_MUTATE","true",1); int sc; struct stat s; for(sc=0;sc < user_config->numberOfSource;sc++){ //get local path char *path = malloc(sizeof(char)*(snprintf(NULL, 0, "%s/%s/%s",cwd, copy_put, *source) + 1)); sprintf(path, "%s/%s/%s",cwd, copy_put, *source); //Check if the path is a directory or a file if( stat(path,&s) == 0 ) { if( s.st_mode & S_IFDIR ) { //it's a directory process_source_directory(path,cwd,copy_put,args_txl,source,user_config); } else if( s.st_mode & S_IFREG ) { //it's a file args_txl[4+TXL_OPTS]=path; process_source_file(path,cwd,copy_put,args_txl,source,user_config); } } source++; } //Remove the copy of the program under test we made earlier cleanUp(copy_put); printf("\n"); } return 0; }