/**
 * forks a process and launches a program as child
 */
void launchJob(char *command[], char *file, int newDescriptor,
               int executionMode)
{
        pid_t pid;
        pid = fork();
        switch (pid) {
        case -1:
                perror("R-shell(fork)");
                exit(EXIT_FAILURE);
                break;
        case 0:
                /**
                 *  we set the handling for job control signals back to the default.
                 */
                signal(SIGINT, SIG_DFL);
                signal(SIGQUIT, SIG_DFL);
                signal(SIGTSTP, SIG_DFL);
                signal(SIGCHLD, &signalHandler_child);
                signal(SIGTTIN, SIG_DFL);
                usleep(20000);                                                             // fixes a synchronization bug. Needed for short commands like ls
                setpgrp();                                                                                     // make the child as new process group leader
                if (executionMode == FOREGROUND)
                        tcsetpgrp(RSH_TERMINAL, getpid());                                           // if we want the process to be in foreground
                if (executionMode == BACKGROUND)
                        printf("[%d] %d\n", ++numActiveJobs, (int) getpid());              // inform the user about the new job in bg

                executeCommand(command, file, newDescriptor, executionMode);

                exit(EXIT_SUCCESS);
                break;
        default:
                setpgid(pid, pid);                                                                        // we also make the child a new process group leader from here
                // to avoid race conditions
                jobsList = insertJob(pid, pid, *(command), file, (int) executionMode); // insert the job in the list

                t_job* job = getJob(pid, BY_PROCESS_ID);                             // and get it as job object

                if (executionMode == FOREGROUND) {
                        putJobForeground(job, FALSE);                                              // put the job in foreground (if desired)
                }
                if (executionMode == BACKGROUND)
                        putJobBackground(job, FALSE);                                             // put the job in background (if desired)
                break;
        }
}
Example #2
0
void launchJob(char *command[], char *file, int newDescriptor,
               int executionMode)
{
        pid_t pid;
        pid = fork();
        switch (pid) {
        case -1:
                perror("MyShell");
                exit(EXIT_FAILURE);
                break;
        case 0:
                signal(SIGINT, SIG_DFL);
                signal(SIGQUIT, SIG_DFL);
                signal(SIGTSTP, SIG_DFL);
                signal(SIGCHLD, &signalHandler_child);
                signal(SIGTTIN, SIG_DFL);
                usleep(20000);
                setpgrp();
                if (executionMode == FOREGROUND)
                        tcsetpgrp(MSH_TERMINAL, getpid());
                if (executionMode == BACKGROUND)
                        printf("[%d] %d\n", ++numActiveJobs, (int) getpid());

                executeCommand(command, file, newDescriptor, executionMode);

                exit(EXIT_SUCCESS);
                break;
        default:
                setpgid(pid, pid);

                jobsList = insertJob(pid, pid, *(command), file, (int) executionMode);

                t_job* job = getJob(pid, BY_PROCESS_ID);

                if (executionMode == FOREGROUND) {
                        putJobForeground(job, FALSE);
                }
                if (executionMode == BACKGROUND)
                        putJobBackground(job, FALSE);
                break;
        }
}
Example #3
0
int checkBuiltInCommands()
{
        if (strcmp("exit", commandArgv[0]) == 0) {
                puts("\nExiting. Thanks for using myShell!\n");
		exit(EXIT_SUCCESS);
        }
        if (strcmp("cd", commandArgv[0]) == 0) {
		//add_command_to_history(commandArgv[0]);
                changeDirectory();
                return 1;
        }
       /* if (strcmp("in", commandArgv[0]) == 0) {
                launchJob(commandArgv + 2, *(commandArgv + 1), STDIN, FOREGROUND);
                return 1;
        }
        if (strcmp("out", commandArgv[0]) == 0) {
                launchJob(commandArgv + 2, *(commandArgv + 1), STDOUT, FOREGROUND);
                return 1;
        }*/
        if (strcmp("bg", commandArgv[0]) == 0) {
                //add_command_to_history(commandArgv[0]);

		if (commandArgv[1] == NULL)
                        return 0;
                /*if (strcmp("in", commandArgv[1]) == 0)
                        launchJob(commandArgv + 3, *(commandArgv + 2), STDIN, BACKGROUND);
                else if (strcmp("out", commandArgv[1]) == 0)
                        launchJob(commandArgv + 3, *(commandArgv + 2), STDOUT, BACKGROUND);
                else
                        launchJob(commandArgv + 1, "STANDARD", 0, BACKGROUND);*/
		int jobId = (int) atoi(commandArgv[1]);
		t_job* job = getJob(jobId, BY_JOB_ID);
		if(job == NULL)
			return 0;
		if(job->status == SUSPENDED){
			fprintf(stdout, "converting program from suspended to background wait status: ");
			puts(job->name);
			putJobBackground(job, TRUE);
			//launchJob(job->name, "STANDARD", 0, BACKGROUND);
		}
		else{
			putJobBackground(job, FALSE);
			fprintf(stdout, "program already in a wait status.");
		}
		return 1;
        }
	if (strcmp("&", commandArgv[commandArgc-1]) == 0){ // commandArgv[1] for bg after file

		//printf("%s", commandArgv[0]);
		if (strcmp("&", commandArgv[0]) == 0) // commandArgv[0] for bg after file
			return 0;
		else{
			//puts(commandArgv);
			//printf("commandArgv:  %p\n", commandArgv);
			launchJob(commandArgv, "STANDARD", 0, BACKGROUND); // ommandArgv for bg after file
		}
		return 1;
	}
	else{
		//printf("%s", commandArgv[0]);
	}
       if (strcmp("fg", commandArgv[0]) == 0) {
                //add_command_to_history(commandArgv[0]);

		if (commandArgv[1] == NULL)
                        return 0;
                int jobId = (int) atoi(commandArgv[1]);
                t_job* job = getJob(jobId, BY_JOB_ID);
                if (job == NULL)
                        return 0;
                if (job->status == SUSPENDED || job->status == WAITING_INPUT){
                        fprintf(stdout, "bringing program from background to run: ");
			puts(job->name);
			putJobForeground(job, TRUE);
		}
                else                               // status = BACKGROUND
                        putJobForeground(job, FALSE);
                return 1;
        }
        if (strcmp("jobs", commandArgv[0]) == 0) {
                //add_command_to_history(commandArgv[0]);

		printJobs();
                return 1;
        }
        if (strcmp("kill", commandArgv[0]) == 0)
        {
                //add_command_to_history(commandArgv[0]);

				if (commandArgv[1] == NULL)
                        return 0;

				char *nextCharPtr;
				char testString[10];

				strcpy(testString, commandArgv[1]);
				char *test = testString;
				if(strncmp("%", test, 1) == 0)
				{
					nextCharPtr = strtok(testString, "%");
					killJob((atoi(nextCharPtr)));
					return 1;
				}
				else{
					killJobCredit((atoi(commandArgv[1])));
					return 1;
				}
        }
	/*if(strcmp("!1", commandArgv[0]) == 0){
		char *cP;
		int number;
		cP = strtok(commandArgv[0], "!");
		number = atoi(cP)-1;
		char historyPoint[60];
		char *hisString;
		char *newCommand[10];

		int i;
		for(i = 0; i < 60; i++){
			historyPoint[i] = (char)history[number][i];
		}

		hisString = strtok(historyPoint, "");
		printf("%s\n", hisString);

		//historyPoint = history[number];
		//printf("%s\n", historyPoint);
		newCommand[0] = hisString;
		//printf("commandArgv: %s\n", commandArgv[0]);
		commandArgv[0] = newCommand[0];
		//printf("new commandArgv: %s\n", commandArgv[0]);
		//printf("%s\n", newCommand[0]);
		//launchJob(newCommand[0], "STANDARD", 0, FOREGROUND);
		//executeCommand(commandArgv[0], "STANDARD", 0, FOREGROUND);
		return 1;
	}*/
	if(strcmp("history", commandArgv[0]) == 0)
	{
		int index;
		int column;
		int count = 1;
		printf("Command History List\n");
		printf("%d:  ", count);
		for(index = 0; index < 10; index++){
			for(column = 0; column < 55; column++){
				fprintf(stdout, "%c", history[index][column]);
			}
			count++;
			//printf("%d:  ", count);
			if(count <= 10){
				printf("\n");
				printf("%d:  ", count);
			}
			if(count == 11)
				printf("\n");
			//count++;
		}
		return 1;

	}
	if(strcmp("help", commandArgv[0]) == 0)
	{

		printf("Help Menu\n");
		printf("The functionality of this shell is as follows:\n\n");
		printf("The execution of simple normal shell operations such as cat, more, echo, any user-defined program, etc. will\n");
		printf("operate exactly as they would in the bash shell.\n");
		printf("The built-in commands ls, cd, ps and pwd will operate just as they would in the bash shell as well.\n");
		printf("To start a program in the background simply append the & symbol such as, ./program &\n");
		printf("The command jobs can be used to list the processes that are currently running in the background of your shell.\n");
		printf("If a program has been suspended, such as the user entering CTRL-Z, you can background the job to wait status using\n");
		printf("the command bg <job number> e.g. bg 1\n");
		printf("If a job is in the background, either in wait-status or suspended, it can be brought to the foreground by using the\n");
		printf("command fg <job number> e.g. fg 1\n");
		printf("A job can be killed using the command kill %<job number> such as kill %1 or using the pid number, kill <pid number>\n");
		printf("You can obtain the pid number of a job from the jobs list or the ps command.\n");
		printf("Simple input/output redirection is accomplished as follows:\n");
		printf("./a.out < input  --  would run program a.out with input from file input and would write all output to stdout\n");
		printf("./a.out > output  --  would run program a.out with output of program sent to the created file output\n");
		printf("./a.out < input > output  --  would run program a.out with input from file input and would write output to the created file output.\n");
		printf("./a.out >> output  --  would run program a.out with output of program appended to the end of the previously created file output.\n");
		printf("./a.out < input >> output  --  would run program a.out with input from file input and append output to the end of the previously\n");
		printf("created file output.\n");
		printf("Simple pipe functionality has also been implemented in this shell.  An example is as follows:\n");
		printf("who | wc  --  would run command who and pipe output to the word count process\n");
		printf("To see a list of previously entered commands type history at the shell prompt, only ten commands are held in history per shell execution.\n");
		printf("To execute a previous command listed in history type !<command number> e.g. !1 at the shell prompt.");
		printf("To exit the shell program type exit at the shell prompt.\n\n");
		printf("End of Help Menu\n");
		return 1;

	}
        //int i;
        ////for( i=0;i<=commandArgc;i++)
        //{
        //char *str;
        //strcpy(str,commandArgv);
        if( commandArgc == 3 )
        {
		if(strcmp("|", commandArgv[1]) == 0  )
            	{
            		pipelining(2);
            		return 1;
           	}
		else if(strcmp("<", commandArgv[commandArgc-2]) == 0){
			int in;
			int i = 0;
			i = fork();
			if(i == 0){
				in = open(commandArgv[2], O_RDONLY);
				dup2(in, 0);
				close(in);
				executeCommand(commandArgv, "STANDARD", 0, FOREGROUND);
				//puts("test statement 1");
				dup2(0, 0);
				//printf("test statement 2");
			}else{
				waitpid(getpid(), NULL, 0);
				close(in);
			}
			return 1;
		}
		else if(strcmp(">", commandArgv[commandArgc-2]) == 0){
			int out;
			int i = 0;
			i = fork();
			if(i == 0){
				out = open(commandArgv[2], O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IRGRP | S_IWGRP | S_IWUSR);
				dup2(out, 1);
				close(out);
				executeCommand(commandArgv, "STANDARD", 0, FOREGROUND);
				//printf("test statement 3");
				dup2(1, 1);
				//printf("test statement 4");
			}else{
				waitpid(getpid(), NULL, 0);
				close(out);
			}
			return 1;
		}
		else if(strcmp(">>", commandArgv[commandArgc-2]) == 0){
			int out;
			int i = 0;
			int offset;

			i = fork();
			if(i == 0){
				out = open(commandArgv[2], O_WRONLY | O_APPEND);

				offset = lseek(out, 1, SEEK_END);

				dup2(out, 1);
				close(out);

				executeCommandAppend(commandArgv, "STANDARD", 0, FOREGROUND);

				dup2(1, 1);

			}else{
				waitpid(getpid(), NULL, 0);
				close(out);
			}
			return 1;

		}

        }
	if( commandArgc > 3 )
	{
		if(strcmp(">", commandArgv[commandArgc-2]) == 0){
			int in;
			int out;
			int i = 0;
			i = fork();
			if(i == 0){
				in = open(commandArgv[2], O_RDONLY);
				out = open(commandArgv[4], O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IRGRP | S_IWGRP | S_IWUSR);

				dup2(in, 0);
				dup2(out, 1);

				close(in);
				close(out);

				executeCommand(commandArgv, "STANDARD", 0, FOREGROUND);
				dup2(0, 0);
				dup2(1, 1);
			}else{
				waitpid(getpid(), NULL, 0);
				close(in);
				close(out);
			}

			return 1;

		}
		else if(strcmp("|", commandArgv[commandArgc-2]) == 0 )
		{
			//puts("works");
			//printf("%d",commandArgc);
			pipelining(commandArgc-1);
			return 1;
		}
		else if(strcmp(">>", commandArgv[commandArgc-2]) == 0){
			int in;
			int out;
			int offset;
			int i = 0;

			i = fork();
			if(i == 0){
				in = open(commandArgv[2], O_RDONLY);
				out = open(commandArgv[4], O_WRONLY |  O_APPEND);

				offset = lseek(out, 1, SEEK_END);


				dup2(in, 0);
				dup2(out, 1);

				close(in);
				close(out);

				executeCommandAppend(commandArgv, "STANDARD", 0, FOREGROUND);
				dup2(0, 0);
				dup2(1, 1);
			}else{
				waitpid(getpid(), NULL, 0);
				close(in);
				close(out);
			}

			return 1;

		}
	}
        //break;
        //}



        return 0;
}