diff --git a/src/built_in.c b/src/built_in.c index 9a466e91501d5877107fb67e308275c4847bcb38..b30c77def4af520db597df3d87aae039be3e13d3 100644 --- a/src/built_in.c +++ b/src/built_in.c @@ -35,8 +35,13 @@ int do_pwd(int argc, char** argv) { int do_fg(int argc, char** argv) { if (!validate_fg_argv(argc, argv)) return -1; + + int pid = waitpid(0, 0, 0); - // TODO: Fill this. + if(pid == -1) + printf("no such jobs.\n"); + else + printf("%d done\n", pid); return 0; } diff --git a/src/commands.c b/src/commands.c index 13e9c330aedcb9d3c1c0979a5b22fd7844516ada..b1eb262fc9843a58eb6493f3ba30dd54dc8c0926 100644 --- a/src/commands.c +++ b/src/commands.c @@ -2,16 +2,44 @@ #include <stdlib.h> #include <string.h> #include <assert.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> +#include <pthread.h> #include "commands.h" #include "built_in.h" +#define SOCK_PATH "tpf_unix_sock.server" +#define CLIENT_PATH "tpf_unix_sock.client" +#define UNIX_PATH_MAX 108 + +pid_t pID; +/* +struct sockaddr_un{ + unsigned short int sun_family; //AF_UNIX + char sun_path[UNIX_PATH_MAX]; //pathname +};*/ + +static char PATH[5][1028] = { + {"/usr/local/bin/"}, + {"/usr/bin/"}, + {"/bin/"}, + {"/usr/sbin/"}, + {"/sbin/"} +}; + static struct built_in_command built_in_commands[] = { { "cd", do_cd, validate_cd_argv }, { "pwd", do_pwd, validate_pwd_argv }, { "fg", do_fg, validate_fg_argv } }; +void server_thread(); +void client_thread(void* command); + static int is_built_in_command(const char* command_name) { static const int n_built_in_commands = sizeof(built_in_commands) / sizeof(built_in_commands[0]); @@ -30,11 +58,23 @@ static int is_built_in_command(const char* command_name) */ int evaluate_command(int n_commands, struct single_command (*commands)[512]) { - if (n_commands > 0) { - struct single_command* com = (*commands); + struct single_command* com = (*commands); + if (n_commands == 1) { + //struct single_command* com = (*commands); assert(com->argc != 0); + //background processing + int background = 0; + + if(strcmp(com->argv[com->argc-1], "&") == 0){ + background = 1; + + com->argv[com->argc-1] = NULL; + com->argc = com->argc-1; + } + + //do built_in_command 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)) { @@ -50,12 +90,222 @@ int evaluate_command(int n_commands, struct single_command (*commands)[512]) } else if (strcmp(com->argv[0], "exit") == 0) { return 1; } else { - fprintf(stderr, "%s: command not found\n", com->argv[0]); - return -1; + //process creation + pID = fork(); + + //fork error + if(pID == -1){ + fprintf(stderr, "fork fail\n"); + + } + //child process + else if(pID == 0){ + path_exec(com); + + fprintf(stderr, "%s: command not found\n", com->argv[0]); + exit(0); + } + //parent process + else{ + if(background == 1) + printf("background pid : %d\n", pID); + else + waitpid(pID, 0, 0); + } + return 0; } } + //IPC + else if(n_commands >= 2){ + void* status; + pthread_t threads[2]; + + int pid = fork(); + if(pid == 0){ + for(int l = 0; l < n_commands; l++){ + pthread_create(&threads[1], NULL, &client_thread, (void *) com); + pthread_join(threads[1], &status); + com++; + } + exit(0); + } else{ + pthread_create(&threads[0], NULL, &server_thread, (void *)&n_commands); + waitpid(pid, NULL, 0); + pthread_join(threads[0], NULL); + } + + return 0; + } + + + return 0; +} +void path_exec(struct single_command* com){ + if(execv(com->argv[0], com->argv) == -1){ + //need path resoultion + char *tmp = com->argv[0]; + + for(int k = 0; k < 5; k++){ + com->argv[0] = strcat(PATH[k], tmp); + if(execv(com->argv[0], com->argv) == -1) + com->argv[0] = tmp; + else + break; + } + } +} + +void server_thread(){ + int server_sock, client_sock, len; + struct sockaddr_un server_sockaddr; + struct sockaddr_un client_sockaddr; + char buf[256]; + memset(&server_sockaddr, 0, sizeof(struct sockaddr_un)); + memset(&client_sockaddr, 0, sizeof(struct sockaddr_un)); + memset(buf, 0, 256); + + //create domain stream socket + server_sock = socket(AF_UNIX, SOCK_STREAM, 0); + if(server_sock == -1){ + printf("SOCKET ERROR\n"); + exit(1); + } + + //bind + server_sockaddr.sun_family = AF_UNIX; + strcpy(server_sockaddr.sun_path, SOCK_PATH); + len = sizeof(server_sockaddr); + + unlink(SOCK_PATH); + if(bind(server_sock, (struct sockaddr *) &server_sockaddr, len) == -1){ + printf("BIND ERROR\n"); + close(server_sock); + exit(1); + } + + //listen + if(listen(server_sock, 10) == -1){ + printf("LISTEN ERROR\n"); + close(server_sock); + exit(1); + } + + //accept + 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); + } + + dup2(client_sock, STDIN_FILENO); + + int h = 2; + while(h--){ + //send data + memset(buf, 0, 256); + if(send(client_sock, buf, strlen(buf), 0) == -1){ + printf("SEND ERROR\n"); + close(server_sock); + close(client_sock); + exit(1); + } + + //read and print + if(recv(client_sock, buf, sizeof(buf), 0) == -1){ + printf("REC ERROR\n"); + close(server_sock); + close(client_sock); + exit(1); + } + else + printf("DATA RECEIVED = %s\n", buf); + + } + //close + close(server_sock); + close(client_sock); + return 0; + +} + +void client_thread(void* command){ + int client_sock, len; + struct sockaddr_un server_sockaddr; + struct sockaddr_un client_sockaddr; + char buf[256]; + memset(&server_sockaddr, 0, sizeof(struct sockaddr_un)); + memset(&client_sockaddr, 0, sizeof(struct sockaddr_un)); + + //create + client_sock = socket(AF_UNIX, SOCK_STREAM, 0); + if(client_sock == -1){ + printf("SOCKET ERROR\n"); + exit(1); + } + + //bind + client_sockaddr.sun_family = AF_UNIX; + strcpy(client_sockaddr.sun_path, CLIENT_PATH); + len = sizeof(client_sockaddr); + + unlink(CLIENT_PATH); + if(bind(client_sock, (struct sockaddr *) &client_sockaddr, len) == -1){ + printf("BIND ERROR\n"); + close(client_sock); + exit(1); + } + + //set up + server_sockaddr.sun_family = AF_UNIX; + strcpy(server_sockaddr.sun_path, SOCK_PATH); + if(connect(client_sock, (struct sockaddr *) &server_sockaddr, len) == -1){ + printf("CONNECT ERROR\n"); + close(client_sock); + exit(1); + } + + void* status; + int tempfd = dup(STDOUT_FILENO); + + int pid = fork(); + if(pid == 0){ + path_exec(command); + exit(0); + } + else{ + waitpid(-1, &status, 0); + dup2(tempfd, STDOUT_FILENO); + close(tempfd); + } + + int h = 2; + while(h--){ + //send + if(send(client_sock, buf, strlen(buf), 0) == -1){ + printf("SEND ERROR\n"); + close(client_sock); + exit(1); + } + + //Read + memset(buf, 0, sizeof(buf)); + if(recv(client_sock, buf, sizeof(buf), 0) == -1){ + printf("RECV ERROR \n"); + close(client_sock); + exit(1); + } + else + printf("DATA RECEIVED = %s\n", buf); + } + //close + close(client_sock); + + return 0; + } void free_commands(int n_commands, struct single_command (*commands)[512]) @@ -74,3 +324,4 @@ 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..8f8c0cb4901ef6a0ad6f1fb258d8c323d484c632 100644 --- a/src/main.c +++ b/src/main.c @@ -1,16 +1,21 @@ #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]; + catch_sigint(SIGINT); + catch_sigtstp(SIGTSTP); while (1) { + printf("$ "); fgets(buf, 8096, stdin); struct single_command commands[512]; @@ -25,6 +30,7 @@ int main() if (ret == 1) { break; } + memset(buf, 0, sizeof(buf)); } return 0; diff --git a/src/signal_handlers.c b/src/signal_handlers.c index 4b6fe2e073f327917964b5327b6649f74bcbda1e..f98707be0f894047305a274040e40654d3075d16 100644 --- a/src/signal_handlers.c +++ b/src/signal_handlers.c @@ -1,11 +1,12 @@ +#include <signal.h> #include "signal_handlers.h" -void catch_sigint(int signalNo) +void catch_sigint(int signalNo) //process interrupt { - // TODO: File this! + signal(signalNo, SIG_IGN); } -void catch_sigtstp(int signalNo) +void catch_sigtstp(int signalNo) //process stop { - // TODO: File this! + signal(signalNo, SIG_IGN); }