diff --git a/src/built_in.c b/src/built_in.c index 9a466e91501d5877107fb67e308275c4847bcb38..7076ceb204da5e2c967755f87bf1d3733a0b6689 100644 --- a/src/built_in.c +++ b/src/built_in.c @@ -65,4 +65,4 @@ int validate_fg_argv(int argc, char** argv) { if (strcmp(argv[0], "fg") != 0) return 0; return 1; -} +} \ No newline at end of file diff --git a/src/commands.c b/src/commands.c index 13e9c330aedcb9d3c1c0979a5b22fd7844516ada..e73afcfe03fbfabbaddec79df8a3d6936183334f 100644 --- a/src/commands.c +++ b/src/commands.c @@ -2,9 +2,19 @@ #include <stdlib.h> #include <string.h> #include <assert.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <errno.h> +#include <unistd.h> +#include <stdbool.h> +#include <pthread.h> #include "commands.h" #include "built_in.h" +#define SOCK_PATH "tpf_unix_sock.server" static struct built_in_command built_in_commands[] = { { "cd", do_cd, validate_cd_argv }, @@ -25,16 +35,79 @@ static int is_built_in_command(const char* command_name) return -1; // Not found } +void *socket_server(void *server_input) { + + int server_sock, client_sock, len, rc, pid; + int status; + struct sockaddr_un server_sockaddr; + struct sockaddr_un client_sockaddr; + int backlog = 10; + memset(&server_sockaddr, 0, sizeof(server_sockaddr)); + + server_sock = socket(AF_UNIX, SOCK_STREAM, 0); + + server_sockaddr.sun_family = AF_UNIX; + strcpy(server_sockaddr.sun_path, SOCK_PATH); + len = sizeof(server_sockaddr); + + unlink(SOCK_PATH); + rc = bind(server_sock, (struct sockaddr*)&server_sockaddr,sizeof(server_sockaddr)); + + if( rc == -1 ) { + printf("BIND ERROR\n"); + close(server_sock); + exit(1); + } + + while(1){ + if(listen(server_sock,backlog) == -1){ + printf("LISTEN ERROR\n"); + exit(1); + } + + client_sock = accept(server_sock, (struct sockaddr *) &client_sockaddr, &len); + + if(client_sock == -1){ + printf("ACCEPT ERROR\n"); + close(server_sock); + close(client_sock); + exit(1); + } + + pid = fork(); + + if(pid == 0){ + dup2(client_sock, 1); + evaluate_command(1, server_input); + exit(0); + } + if(pid > 0){ + wait(&status); + } + + close(client_sock); + pthread_exit(0); + } +} + /* * Description: Currently this function only handles single built_in commands. You should modify this structure to launch process and offer pipeline functionality. */ int evaluate_command(int n_commands, struct single_command (*commands)[512]) { if (n_commands > 0) { + struct single_command* com = (*commands); + struct stat buf; + int status; + + char buffer[1024]; + assert(com->argc != 0); + stat(com->argv[0], &buf); + int built_in_pos = is_built_in_command(com->argv[0]); if (built_in_pos != -1) { if (built_in_commands[built_in_pos].command_validate(com->argc, com->argv)) { @@ -45,11 +118,78 @@ int evaluate_command(int n_commands, struct single_command (*commands)[512]) fprintf(stderr, "%s: Invalid arguments\n", com->argv[0]); return -1; } - } else if (strcmp(com->argv[0], "") == 0) { + } + else if (strcmp(com->argv[0], "") == 0) { return 0; - } else if (strcmp(com->argv[0], "exit") == 0) { + } + else if (strcmp(com->argv[0], "exit") == 0) { return 1; - } else { + } + + else if (n_commands > 1){ + + int client_sock, pid, rc, len; + struct sockaddr_un server_sockaddr; + pthread_t p_thread; + + pthread_create(&p_thread, NULL, socket_server, (void*)com); + + pid = fork(); + + if(pid == 0){ + memset(&server_sockaddr, 0, sizeof(struct sockaddr_un)); + + client_sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (client_sock == -1) { + printf("SOCKET ERROR \n"); + exit(1); + } + + len = sizeof(server_sockaddr); + + server_sockaddr.sun_family = AF_UNIX; + strcpy(server_sockaddr.sun_path, SOCK_PATH); + + rc = connect(client_sock, (struct sockaddr *) &server_sockaddr, len); + if(rc == -1){ + printf("CONNECTION ERROR\n"); + exit(1); + } + + dup2(client_sock, 0); + execv(com[1].argv[0], com[1].argv); + close(client_sock); + exit(0); + } + else{ + wait(&status); + } + } + + else if(S_ISREG(buf.st_mode)){ + + int pid; + bool background = false; + + if(strcmp(com->argv[(com->argc)-1], "&") == 0){ + background = true; + com->argv[(com->argc)-1] = NULL; + } + + pid = fork(); + + if(pid == 0){ + execv(com->argv[0], com->argv); + } + else if(pid > 0){ + wait(&status); + }else{ + perror("Fork error"); + return -1; + } + } + + else { fprintf(stderr, "%s: command not found\n", com->argv[0]); return -1; } @@ -74,3 +214,5 @@ void free_commands(int n_commands, struct single_command (*commands)[512]) memset((*commands), 0, sizeof(struct single_command) * n_commands); } + + diff --git a/src/main.c b/src/main.c index 77c78049273e013e278ad9021fa088531b636a97..9d1eb8e5a53661bbe64abf25b2eb1d80148dfb88 100644 --- a/src/main.c +++ b/src/main.c @@ -1,16 +1,22 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <signal.h> #include "commands.h" #include "built_in.h" #include "utils.h" +#include "signal_handlers.h" int main() { char buf[8096]; + while (1) { + signal(SIGINT, (void *)catch_sigint); + signal(SIGTSTP, (void *)catch_sigtstp); + fgets(buf, 8096, stdin); struct single_command commands[512]; @@ -21,6 +27,8 @@ int main() free_commands(n_commands, &commands); n_commands = 0; + + memset(buf,0,8096); if (ret == 1) { break; @@ -28,4 +36,4 @@ int main() } return 0; -} +} \ No newline at end of file diff --git a/src/signal_handlers.c b/src/signal_handlers.c index 4b6fe2e073f327917964b5327b6649f74bcbda1e..f55a86066e61bca54a6b3f344982f446c8110024 100644 --- a/src/signal_handlers.c +++ b/src/signal_handlers.c @@ -1,11 +1,16 @@ #include "signal_handlers.h" +#include <signal.h> +#include <stdio.h> void catch_sigint(int signalNo) { - // TODO: File this! + printf("\nYour input Ctrl+C, Shell doesn't close.\n"); + signal(SIGINT, SIG_IGN); } + void catch_sigtstp(int signalNo) { - // TODO: File this! -} + printf("\nYour input Ctrl+Z, but it doesn't move.\n"); + signal(SIGTSTP, SIG_IGN); +} \ No newline at end of file