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);
}
Exemple #2
0
/*
 * 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;
}