Exemplo n.º 1
0
/*BEGIN externalCall function--passes user input to external shell. Used only if user inputs a command not implemented in this shell*/
int externalCall(char **args){
	
	/*check for the background execution argument '&'*/
	BGCheck(args);

	 /*fork/exec statement--case 0 is the child process, default is the parent, -1 is an error*/
	switch(childPID = fork()){
		case -1:
			debug("Fork error");
			break;
		case 0:
			debug("Externalcall fork case 0");
			
			/*allocate memory for, build, and push PARENT environment variable (used a previously made char* to save space*/
			shell = (char*)malloc(sizeof(char) *(strlen(initCall) + 8));
			strcat(shell, "PARENT=");
			strcat(shell, initCall);
			putenv(shell);

			/*check for I/O Redirect, both in and out(all other calls currently used only check for output redirection)*/
			IORedirect(args, 2);
			execvp(args[0], args);
			exit(-1);	//exit with error code, shouldn't ever reach this line
		default:
			if(!noWait){
				debug("Externalcall wait");
				waitpid(childPID, &status, WUNTRACED);
			}
	}
	return childPID;
}
Exemplo n.º 2
0
//#iii. dir <directory> - list the contents of <directory>
int dir(char **args){
	int i = 2;
	numArgs = 0;
	debug("Dir called");
	
	/*count the arguments*/
	while(args[++numArgs] != NULL);

	/*allocate space for, and build the new set of arguments*/
	out = (char**)malloc(sizeof(char*) * (numArgs + 1));
	out[0] = (char *)malloc(sizeof(char) * 3);
	strcpy(out[0], "ls");
	out[1] = (char *)malloc(sizeof(char) * 4);
	strcpy(out[1], "-al");
	out[2] = NULL;	//in case of no additional arguments
	
	debug("Setting Args. List to follow:");
	debug(out[0]);
	debug(out[1]);
	/*set the new list of arguments, terminated with a NULL pointer*/
	while(i < numArgs+1){
		out[i] = (char *)malloc(sizeof(char) * ((strlen(args[i-1]))+1));
		strcpy(out[i], args[i-1]);
		debug(out[i]);
		++i;
		out[i] = NULL;
	}

	 /*fork/exec statement--case 0 is the child process, default is the parent, -1 is an error*/
	switch(childPID = fork()){
		case -1:
			debug("Fork error");
			break;
		case 0:
			debug("Dir fork case 0");
			debug("Checking for I/O Redirection");
			IORedirect(out, 1);
			debug("I/O Redirection check complete. Executing call.");
			execvp("ls", out);
			exit(-1);
		default:
			if(!noWait){
				debug("Dir wait");
				waitpid(childPID, &status, WUNTRACED);
			}
	}
	free(out);
	return childPID;
}
Exemplo n.º 3
0
/* 
 * eval - Evaluate the command line that the user has just typed in
 * 
 * If the user has requested a built-in command (quit, jobs, bg or fg)
 * then execute it immediately. Otherwise, fork a child process and
 * run the job in the context of the child. If the job is running in
 * the foreground, wait for it to terminate and then return.  Note:
 * each child process must have a unique process group ID so that our
 * background children don't receive SIGINT (SIGTSTP) from the kernel
 * when we type ctrl-c (ctrl-z) at the keyboard.  
 */
void eval(char *cmdline) 
{
    int bg;              /* should the job run in bg or fg? */
    struct cmdline_tokens tok;
	struct job_t *jobinfo;
	pid_t pid;
	sigset_t wait;
    /* Parse command line */
    bg = parseline(cmdline, &tok); 

    if (bg == -1) /* parsing error */
        return;
    if (tok.argv[0] == NULL) /* ignore empty lines */
        return;
	if(!buildinCmd(&tok)){
		blockAllSignal();
		if((pid = fork()) == 0){
			//child
			if(setpgid(0, 0) < 0){
				unix_error("process set prcess group error\n");
			}
			IORedirect(&tok);	
			unblockAllSignal();
			if(execve(tok.argv[0], tok.argv, environ) == -1){
				printf("%s, command not found\n", tok.argv[0]);
				exit(0);
			}
		}else{
			//parent 
			if(!bg){
				addjob(job_list, pid, FG, cmdline);
				sigemptyset(&wait);
				sigsuspend(&wait);
                unblockAllSignal();	
				while(fgpid(job_list) != 0)
                    {  
                        sigsuspend(&wait);
                    }
			}else{
				addjob(job_list, pid, BG, cmdline);
                jobinfo = getjobpid(job_list, pid);
				printf("[%d] (%d) %s\n", jobinfo->jid, jobinfo->pid, jobinfo->cmdline);
                unblockAllSignal();	
			}
		}
	}	
    return;
}
Exemplo n.º 4
0
//#vi. help - display the user manual using the more filter
int help(char **args){
	debug("Help called");

	 /*fork/exec statement--case 0 is the child process, default is the parent, -1 is an error*/
	switch(childPID = fork()){
		case -1:
			debug("Fork error");
			break;
		case 0:
			IORedirect(args, 1);
			/*Display the readme file using the more filter*/
			execlp("more", "more", readme, NULL);
			exit(-1);
		default:
			if(!noWait)
				waitpid(childPID, &status, WUNTRACED);
	}
	return childPID;
}
Exemplo n.º 5
0
//#iv. environ - list all the environment strings
int envrn(char **args){
	debug("Environ called");
	env = environ;

	 /*fork/exec statement--case 0 is the child process, default is the parent, -1 is an error*/
	switch(childPID = fork()){
		case -1:
			debug("Fork Error");
			break;
		case 0:
			IORedirect(args, 1);
			while(*env)
				puts(*env++);
			exit(0);
		default:
			if(!noWait)
				waitpid(childPID, &status, WUNTRACED);
	}
	return childPID;
}
Exemplo n.º 6
0
//#v. echo <comment> - display <comment> on the display followed by
//#a new line (multiple spaces/tabs may be reduced to a single space)
int echo(char **args){
	int i = 1;
	debug("Echo called");

	 /*fork/exec statement--case 0 is the child process, default is the parent, -1 is an error*/
	switch(childPID = fork()){
		case -1:
			debug("Fork error");
			break;
		case 0:
			IORedirect(args, 1);
			/*print all arguments on a single line, each followed by a single space.*/
			while(args[i] != NULL){
				printf("%s ", args[i]);
				++i;
			}
			printf("\n");	//end the line with a newline character
			exit(0);
		default:
			if(!noWait)
				waitpid(childPID, &status, WUNTRACED);
	}
	return childPID;
}