Esempio n. 1
0
File: run.c Progetto: JonMuehlst/msh
int run(char* cmd, int input, int first, int last, int* n, int delimitFlag) {

    int output = STANDARD_OUTPUT;

    getRedir(cmd); //redir_num and fileName get assigned here.

    if(redir_num == OUTPUT_REDIRECTION_NUM || redir_num == APPEND_OUTPUT_REDIRECTION_NUM) {
        openFile();
        output = fd;
    } else if(redir_num == INPUT_REDIRECTION_NUM) {
        openFile();
        input = fd;
    }

    split(cmd, args);

    if (args[0] != NULL) {
        /*
        	if (strcmp(args[0], EXIT) == 0)
        		exit(0); */
        (*n) += 1;
        if(delimitFlag == AMPERSAND_NUM) {
            return bgCommand(input, first, output);
        } else if(delimitFlag == PIPE_NUM) {
            return pipeCommand(input, first, last);
        } else if(delimitFlag == NO_BLOCK_ENDING) {
            return command(input, first, output);
        }
    }
    return 0;
}
Esempio n. 2
0
int main(void) {
	char inputBuffer[MAX_LINE]; /** buffer to hold the command entered **/
	int background;             /** equals 1 if a command is followed by '&' **/
	int respawnable;			/** igual a 1 si al comando le sigue '#' **/
	char *args[MAX_LINE / 2];   /** command line (of 256) has max of 128 arguments **/

	// probably useful variables:
	int pid_fork, pid_wait; 		/** pid for created and waited process **/
	int status;             		/** status returned by wait **/
	enum status status_res; 		/** status processed by analyze_status() **/
	int info;						/** info processed by analyze_status() **/
	ignore_terminal_signals();	    /** Ignora las señales del terminal **/

	/** Asociamos el manejador a la señal SIGCHLD y creamos la lista de trabajos **/
	signal(SIGCHLD, manejador);
	lista_trabajos = new_list("Lista trabajos");

	/** Program terminates normally inside get_command() after ^D is typed **/
	while(1) {

		printf("\nCOMMAND->");
		fflush(stdout);
		/** get next command **/
		get_command(inputBuffer, MAX_LINE, args, &background, &respawnable);

		// if empty command
		if(args[0] == NULL) {
			continue;
		}

		/** Comando interno CD **/
		if(strcmp(args[0], "cd") == 0 && args[1] != NULL) {
			chdir(args[1]);
			continue;
		}

		/** Comando interno historial **/
		if(strcmp(args[0], "historial") == 0) {
			continue;
		}

		/** Comando interno JOBS (HECHO) **/
		if(strcmp(args[0], "jobs") == 0) {
			if(empty_list(lista_trabajos)) {
				printf("La lista de tareas está vacía\n");
			} else {
				print_job_list(lista_trabajos);
			}
			continue;
		}

		/** Comando interno BG (HECHO) **/
		if(strcmp(args[0], "bg") == 0) {
			if(args[1] == NULL) {
				printf("No le has pasado ningún argumento al comando \n");
			} else {
				int index = atoi(args[1]);   // Convertimos el indice pasado a un entero
				bgCommand(index);   // Invocamos al comando FG
			}
			continue;
		}

		/** Comando interno FG (HECHO) **/
		if(strcmp(args[0], "fg") == 0) {
			int index = 1;			// Por defecto a la primera tarea de la lista
			if(args[1] != NULL) {
				index = atoi(args[1]);	// Si no es nulo, lo aplicaremos al correspondiente
			}
			fgCommand(index);						// Invocamos al comando FG
			continue;
		}

		// the steps are:
		// (1) fork a child process using fork()
		pid_fork = fork();

		if(pid_fork < 0) {	// Caso de error
			printf("Error. The system wasn able to spawn a new process. Exiting...\n");
			exit(-1);

		} else if(pid_fork == 0) {	// Proceso hijo

			/** Nuevo identificador de grupo de procesos para el hijo, asociacion del terminal y señales a default **/
			pid_t mypid = getpid();
			new_process_group(mypid);	// Metemos al hijo en un nuevo grupo

			if(!background && !respawnable) {
				// Le asignamos el terminal
				set_terminal(mypid);
			}

			// Restauramos las señales que reciben del terminal
			restore_terminal_signals();

			// (2) the child process will invoke execvp()
			execvp(args[0], args);

			// Solo llegará aquí si no se ha producido el cambio de imagen
			printf("Error. Command not found: %s\n", args[0]);
			exit(-1);

		// Padre
		} else {

			/** Nuevo identificador de grupo de procesos para el hijo **/
			new_process_group(pid_fork);	// El padre se va a un nuevo grupo de trabajo

			/** Si el programa está en background o es respawnable **/
			if(background || respawnable) {

				/** BLoqueamos la señal SIGCHLD, añadimos el trabajo a la lista(background) y desbloqueamos la señal **/
				block_SIGCHLD();

				job *aux;

				// Creamos un nuevo nodo para agregarlo a la lista
				if(background) {
					aux = new_job(pid_fork, args[0], args, BACKGROUND);
				} else if(respawnable) {
					aux = new_job(pid_fork, args[0], args, RESPAWNABLE);
				}

				// Añadimos ese nodo a la lista creada anteriormente
				add_job(lista_trabajos, aux);
				unblock_SIGCHLD();

				printf("Background job running... pid: %d, command: %s. \n", pid_fork, args[0]);

			/** Si no, es por que está en foreground **/
			} else {
				/**
				 * Wait con detección de suspension y recuperación del terminal
				 * Con el WUNTRACED se comprueba también si el hijo se suspende
				 **/
				set_terminal(pid_fork);	// Redundante
				pid_t wait_pid = waitpid(pid_fork, &status, WUNTRACED);
				set_terminal(getpid());

				/**
				 * pid_fork = waitpid(pid_fork, &status, 0);
				 * esta instruccion ya no es necesaria porque hacemos el wait_pid
				 **/
				int info;
				// Le pasamos la variable "status" que nos acaba de pasar el wait
				enum status st = analyze_status(status, &info);

				/**
				 * Si sale del bloqueo debido a la suspensión del estado
				 * lo metemos en la lista de tareas para poder llevar un
				 * seguimiento de los procesos suspendidos
				 **/
				if(st == SUSPENDED) {
					/** BLoqueamos la señal SIGCHLD, añadimos el trabajo a la lista (suspendido) y desbloqueamos la señal **/
					block_SIGCHLD();
					// Creamos un nuevo nodo para agregarlo a la lista
					job *aux = new_job(pid_fork, args[0], args, STOPPED);
					// Añadimos ese nodo a la lista creada anteriormente
					add_job(lista_trabajos, aux);
					unblock_SIGCHLD();
				}

				// (4) Shell shows a status message for processed command
				printf("Foreground pid: %d, command: %s, status: %s, info: %d. \n", wait_pid, args[0], status_strings[st], info);

			}
		}

		// (5) loop returns to get_commnad() function

	} // end while
}