Exemplo n.º 1
0
void generate_parsingtree(target_t *node, pid_t *child_pid)
{
	if(node == NULL)
		return;
	int ndep = 0;
	pid_t cpid[node->nDependencyCount];
	int status[node->nDependencyCount];
	memset(status, 0, node->nDependencyCount);

	while(ndep < node->nDependencyCount)  {
		generate_parsingtree(find_target(node->szDependencies[ndep]), cpid+ndep);
		ndep++;
	}
	// Wait for all the children to execute
	ndep=0;
	while(ndep < node->nDependencyCount)  {
		cpid[ndep] = waitpid( cpid[ndep], status+ndep, 0);
		ndep++;
	}

	// Execute the code if the dependencies are modified;
	ndep=0; int virginity = 1;
	while(ndep < node->nDependencyCount)  {
		int temp = compare_modification_time(node->szTarget, node->szDependencies[ndep]);
		if(temp!=1)
			virginity = -1;
		ndep++;
	}
	if(virginity ==-1)  { /* virginity is lost.  */
		*child_pid = fork();
		if(*child_pid==0)  {
			system(node->szCommand);
			printf("\n%s\t%d", node->szCommand, getpid());
			exit(0);
		}	
	}
	else  { /* virginity is maintained.  */
		printf("\n no need of %s", node->szCommand);
	}
}
Exemplo n.º 2
0
Arquivo: main.c Projeto: parkx676/C
int main(int argc, char **argv) 
{
	// Declarations for getopt
	extern int optind;
	extern char * optarg;
	int ch;
	char * format = "f:hnBm:";
	
	// Default makefile name will be Makefile
	char szMakefile[64] = "Makefile";
	char szTarget[64];
	char szLog[64];

	// boolean flags for each option.
	int b = 0;
	int n = 0;
	int m = 0;
	int f = 0;

	int file;

	// keep track of stdout so we can return to default output
	int stdOutClone = dup(1);

	while((ch = getopt(argc, argv, format)) != -1) 
	{
		switch(ch) 
		{
			case 'f':
				strcpy(szMakefile, strdup(optarg));
				f = 1;
				break;
			case 'n':
				n = 1;
				break;
			case 'B':
				b = 1;
				break;
			case 'm':
				m = 1;
				strcpy(szLog, strdup(optarg));
				fprintf(stderr,"log name: %s\n",szLog);
				file = open(szLog, O_APPEND|O_RDWR|O_CREAT, 0777);
				dup2(file, 1);
				break;
			case 'h':
				show_error_message(argv[0]);
				exit(1);
			default:
				show_error_message(argv[0]);
				exit(1);
		}
	}

	argc -= optind;
	argv += optind;


	// at this point, what is left in argv is the targets that were 
	// specified on the command line. argc has the number of them.
	// If getopt is still really confusing,
	// try printing out what's in argv right here, then just running 
	// with various command-line arguments.

	if(argc > 1) {
		show_error_message(argv[0]);
		return EXIT_FAILURE;
	}

	// build a target_t array of all targets found in the specified Makefile.
	int parseResult = parse(szMakefile);
	
	// Parse graph file or die
	if(parseResult == -1) 
	{
		return EXIT_FAILURE;
	}

	// target provided.
	if(argc == 1)
	{
		strcpy(szTarget,argv[0]);
	}

	// If no target provided, use the first one found in the Makefile.
	else
	{
		strcpy(szTarget,targets[0].szTarget);
		//fprintf(stderr, "szTarget: %s\n", szTarget);
	}


	int i;
	int j;

	// how many children to wait for.
	int waits = 0;	
	for(i = 0; i < 10; i++) {

		// look for target in the targets array.
		if(strcmp(szTarget,targets[i].szTarget) == 0) {

			targets[i].nStatus = 0;
			targets[i].pid = 1;
			
			for(j = 0; j < targets[i].nDependencyCount; j++) {

				// if the dependency's associated file exists and needs to be updated (or b flag is set) make a child with it as the target.
				if(is_file_exist(targets[i].szDependencies[j]) != -1){
					if(b || compare_modification_time(targets[i].szTarget,targets[i].szDependencies[j]) == 2) { 
						if(targets[i].szDependencies[j][strlen(targets[i].szDependencies[j])-1] == 'c'){
							break;
						}
						else {
							targets[i].pid = fork();
							if(targets[i].pid == 0) {
								break;
							} else { 
							// increment waits for each child created for a given adult.
								waits++; 
							}
						}		
					}
				// if the dependency's associated file does not exist, make a child with it as the target.
				} else {

					targets[i].pid = fork();
					if(targets[i].pid == 0) {
						break;

					// increment waits for each child created for a given adult.
					} else { 
						waits++; 
					}
				}

			}


			if(targets[i].pid > 0){

				int k;

				// wait for ALL children to finish.
				for(k = 0; k < waits; k++) {
					wait(NULL);
				}

				// echo commands if n
				if(n) {
					char* echoCommand = (char*) calloc(100, 1);
					strcat(echoCommand, "echo '");
					char* command = &targets[i].szCommand[0];
					strcat(echoCommand,command);
					strcat(echoCommand,"'");
					system(echoCommand);
				} 
				// else execute them
				else {
					system(targets[i].szCommand);
				}

				// debugging code
				/*
				echoCommand = (char*) calloc(100, 1);
				strcat(echoCommand, "echo 'command: ");
				command = &targets[i].szCommand[0];
				strcat(echoCommand,command);
				strcat(echoCommand," is complete.'");
				system(echoCommand);
				*/
			}
			else if (targets[i].pid == 0){
				/* this is clunky, but we were up against the clock
				 * so after making a *char[] and having it not work
				 * we just copied that array into a char**
				 */
				char* nextArgs[7];
				int k;
				for(k = 0; k < 7; k++){
					nextArgs[k] = (char*) calloc(64, 1);
				}
				int ind = 1;
				
				strcpy(nextArgs[0],"./make4061");
				if(f){
					strcpy(nextArgs[ind], "-f");
					ind++;
					char* makeFile = (char *) calloc(64, 1);
					strcpy(makeFile, &szMakefile[0]);
					strcpy(nextArgs[ind], makeFile);
					ind++;
				}
				if(n) {
					strcpy(nextArgs[ind], "-n");
					ind++;
				} if(b) {
					strcpy(nextArgs[ind], "-B");
					ind++;
				} if(m) {
					strcpy(nextArgs[ind], "-m");
					ind++;
					char* logFile = (char *) calloc(64, 1);
					strcpy(logFile, &szLog[0]);
					strcpy(nextArgs[ind], logFile);
					ind++;
				}
				strcpy(nextArgs[ind], &targets[i].szDependencies[j][0]);

				
				k = 0;
				while(nextArgs[k][0] != 0) {
					k++;
				}

				char** realNextArgs = (char**) calloc(i,sizeof(char*));
				int j;
				for(j= 0; j < k; j++){
					realNextArgs[j] = (char*) calloc(64, 1);
					strcpy(realNextArgs[j], nextArgs[j]);
				}

				// it doesn't work without this line, but for some reason 
				// this corrupts the third spot in the copy array (it's writing to the 6th).
				realNextArgs[j] = NULL;


				//debug
				/*m = 0;
				while(m != k){
					fprintf(stderr,"Arg %d: %s\n", m, realNextArgs[m]);
					m++;
				}*/
				

				execvp(realNextArgs[0], realNextArgs);

				// child failed if execvp returns.
				fprintf(stderr, "Not execvp\n");
				exit(-1);
			}
			else {
				perror("bad forking");
				exit(-1);
			}
			break;
		}
	}

	// close the file if writing to log, and reset stdout.
	if (m == 1) {
		close(file);
		dup2(stdOutClone,1);
	}
	return EXIT_SUCCESS;
}
Exemplo n.º 3
0
//Handles all forking and exec'ing of commands. Execs the commands (if there are
//any) for the processes with zero dependencies that have not been built.
//Decriments the number of dependencies for parents.  Also handles timestamps.  
int forkExec(Node **toBeExeced, int numElements){
	int i;
	int k = 0;
	int comp;
	
	if(strcmp(targ, "clean")==0)
		commands[1] = 1;
	
	for(i=0;i<numElements;i++){
		char **execargv;
		pid_t childpid;
		int execargc;
		int status;
		int recompile = 1;
		//if recompile is 1, then build
		
		//-n flag set
		if(commands[1] == 0){

			recompile = 1;
			for(k = 0;k<toBeExeced[i]->sizeDepends;k++){
				comp = compare_modification_time(toBeExeced[i]->dependencies[k],toBeExeced[i]->target);
				int child_timestamp = get_file_modification_time(toBeExeced[i]->dependencies[k]);
				int parent_timestamp = get_file_modification_time(toBeExeced[i]->target);

				//if the timestamp for one doesn't exist, or the timestamp of the child is greater (newer) than the parent
				if(comp < 2 || (parent_timestamp == -1)){
					recompile = 1;
				}
			}
		}
		//if child is older than the parent, don't rebuild
		if(recompile == 0 && commands[0] != 1){
			continue;
		}
		
		if (strcmp (toBeExeced[i]->command, " ") != 0){	
			if(commands[0] == 1){
				printf("%s\n", toBeExeced[i]->command);
				if (toBeExeced[i]->toParent != NULL){
					toBeExeced[i]->toParent->numTargetDep--;
				}
				continue;
			}
			execargc = makeargv (toBeExeced[i]->command," ",&execargv);
			toBeExeced[i]->pid = childpid = fork();
		}else
		{
			continue;
		}
		if (childpid == -1){
			perror("Failed to Fork\n");
			return -1;
		}
		if(childpid ==0){
			execvp(execargv[0],&execargv[0]);
			perror("Child failed to Exec \n");
			return -1;
		}
		if(childpid > 0){
			wait(&status);
			if(toBeExeced[i]->toParent != NULL){
				toBeExeced[i]->toParent->numTargetDep--;
			}
		}
		freemakeargv(execargv);
	}
	return 1;
}