diff --git a/src/built_in.c b/src/built_in.c index 9a466e91501d5877107fb67e308275c4847bcb38..213d597b0b391e8a0f8e72919248a6fc65b9bfdd 100644 --- a/src/built_in.c +++ b/src/built_in.c @@ -1,12 +1,18 @@ #include <stdio.h> #include <string.h> - +#include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <linux/limits.h> +#include <sys/wait.h> +#include <linux/limits.h> #include "built_in.h" +//#include "signal_handlers.h" + +int pid_num = 1; +char running_command[512]; int do_cd(int argc, char** argv) { if (!validate_cd_argv(argc, argv)) @@ -37,7 +43,14 @@ int do_fg(int argc, char** argv) { return -1; // TODO: Fill this. - + int status; + if(pid_num!=1){ +// signal_setting(); + //back_num = 0; + printf("%d running %s\n",pid_num,running_command); + waitpid(pid_num,&status,0); + pid_num=1; + } return 0; } diff --git a/src/commands.c b/src/commands.c index 13e9c330aedcb9d3c1c0979a5b22fd7844516ada..103f96792aa1fb1261eeb8dc9b1cdca5fb316a50 100644 --- a/src/commands.c +++ b/src/commands.c @@ -1,17 +1,49 @@ +#define _GNU_SOURCE + +#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> +#include <sys/wait.h> +//#include <socket.h> #include "commands.h" #include "built_in.h" +#include <sys/socket.h> +#include <sys/types.h> +#include <pthread.h> + +#define SOCK_PATH "Socket" + +struct sockaddr_un{ + sa_family_t sun_family; + char sun_path[512]; +}; +int running; 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 } }; +static void exec(struct single_command *com){ + execv(com->argv[0],com->argv); + char PATH[100]; + char* saveptr=NULL; + char* tok; + + sprintf(PATH,"%s",getenv("PATH")); + tok=strtok_r(PATH,":",&saveptr); + while(tok){ + char path[100]; + sprintf(path,"%s/%s",tok,com->argv[0]); + execv(path,com->argv); + tok=strtok_r(NULL,":",&saveptr); + } +} + 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]); @@ -49,15 +81,133 @@ int evaluate_command(int n_commands, struct single_command (*commands)[512]) return 0; } else if (strcmp(com->argv[0], "exit") == 0) { return 1; + } else if(n_commands==1){ + int status = 0; + int pid_num = getpid(); + running = fork(); + if(running==0){ + exec(com); + printf("%s : command not found\n",com->argv[0]); + exit(1); + } else{ + waitpid(running,&status,0); + if(status) return -1; + return 0; + } } else { - fprintf(stderr, "%s: command not found\n", com->argv[0]); - return -1; + void* status; + pthread_t threads[2]; + int pid_num=fork(); + if(pid_num==0){ + for(int a=0;a<n_commands;a++,com++){ + pthread_create(&threads[1],NULL,&threads[1],(void *)com); + pthread_join(threads[1],&status); + } + exit(0); + } else{ + pthread_create(&threads[0],NULL,&threads[0],(void *)&n_commands); + waitpid(pid_num,NULL,0); + pthread_join(threads[0],NULL); + } } } return 0; } +void *server_thread(void *n){ + int serverSocket = 0; + int clientSocket = 0; + int serverAddrSize = 0; + socklen_t clientAddrSize = 0; + + struct sockaddr_un serverAddress; + struct sockaddr_un clientAddress; + + bzero(&serverAddress,sizeof(serverAddress)); + bzero(&clientAddress,sizeof(clientAddress)); + + remove(SOCK_PATH); + serverSocket = socket(PF_LOCAL,SOCK_STREAM,0); + + memset(&serverAddress,0,sizeof(serverAddress)); + serverAddress.sun_family = AF_LOCAL; + strcpy(serverAddress.sun_path, SOCK_PATH); + serverAddrSize = sizeof(serverAddress); + bind(serverSocket,(struct sockaddr *)&serverAddress, serverAddrSize); + + listen(serverSocket,5); + int std=dup(1); + char buf[512]; + memset(buf,0,sizeof(buf)); + memset(&clientAddress,0,sizeof(clientAddress)); + clientAddrSize = sizeof(clientAddress); + + int N=(int *)n; + while(N--){ + clientSocket = accept(serverSocket,(struct sockaddr *)&clientAddress, &clientAddrSize); + send(clientSocket,buf,strlen(buf)+1,0); + + memset(buf,0,sizeof(buf)); + recv(clientSocket,buf,512,0); + + close(clientSocket); + } + dup2(std,1); + printf("%s",buf); + close(serverSocket); + remove(SOCK_PATH); + return 0; +} + +void *client_thread(void* com){ + int socketFd = 0; + struct sockaddr_un address; + int result = 0; + char buf[512]={0}; + int addSize=0; + + socketFd = socket(PF_LOCAL,SOCK_STREAM,0); + + memset(&address,0,sizeof(address)); + address.sun_family = AF_LOCAL; + strcpy(address.sun_path, SOCK_PATH); + addSize=sizeof(address); + result = connect(socketFd,(struct sockaddr*)&address, addSize); + + if(result == -1){ + printf("client : ERROR : Connection Failed\n"); + return (void *)-1; + } + + int fd[2]; + pipe(fd); + int pid_num = fork(); + int status; + if(pid_num==0){ + recv(socketFd,buf,512,0); + FILE *fp = fopen("temp","w"); + fprintf(fp,"%s",buf); + fclose(fp); + freopen("temp","r",stdin); + dup2(fd[1],1); + exec((struct single_command *)com); + printf("%s : command not found\n",((struct single_command*)com)->argv[0]); + exit(1); + } + waitpid(pid_num,&status,0); + if(status!=0) return (void *)-1; + memset(buf,0,sizeof(buf)); + read(fd[0],buf,512); + write(socketFd,buf,strlen(buf)+1); + close(socketFd); + remove("temp"); + return 0; + + + + +} void free_commands(int n_commands, struct single_command (*commands)[512]) { for (int i = 0; i < n_commands; ++i) { diff --git a/src/main.c b/src/main.c index 77c78049273e013e278ad9021fa088531b636a97..de11c939bad60d4a7a41dcbf5d0ccc3020260039 100644 --- a/src/main.c +++ b/src/main.c @@ -1,27 +1,72 @@ +#define _GNU_SOURCE + #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> +#include <signal.h> +#include <sys/wait.h> +#include "signal_handlers.h" #include "commands.h" #include "built_in.h" #include "utils.h" int main() { + putenv("PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"); + signal_setting(); + char buf[8096]; while (1) { + memset(buf,0,sizeof(buf)); fgets(buf, 8096, stdin); struct single_command commands[512]; int n_commands = 0; + int background_num = 0; + int buf_len = strlen(buf); + + for(int i =0 ;i<buf_len;i++){ + if(buf[i]=='&'){ + background_num = 1; + buf[i] = 0; + memset(running_command,0,512); + strcpy(running_command,buf); + break; + } + } + mysh_parse_command(buf, &n_commands, &commands); + if(background_num){ + pid_num = fork(); + if(pid_num){ + //back_num = 1; + printf("%d\n",pid_num); + free_commands(n_commands,&commands); + n_commands = 0; + signal_setting(); + continue; + } + } + int ret = evaluate_command(n_commands, &commands); free_commands(n_commands, &commands); n_commands = 0; + if(pid_num==0){ + if(ret==0) + printf("%d done %s\n",getpid(),running_command); + free_commands(n_commands, &commands); + n_commands = 0; + exit(1); + } + free_commands(n_commands, &commands); + n_commands = 0; + if (ret == 1) { break; } diff --git a/src/signal_handlers.c b/src/signal_handlers.c index 4b6fe2e073f327917964b5327b6649f74bcbda1e..33afb4c380d7ee4f089e33c93766f250e5c8a1a0 100644 --- a/src/signal_handlers.c +++ b/src/signal_handlers.c @@ -1,11 +1,72 @@ #include "signal_handlers.h" +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include "built_in.h" +#include "commands.h" +#define _GNU_SOURCE +struct sigset_t{ + unsigned int __sigbits[4]; +}; +struct sigaction{ + void(*sa_handler)(int); + + struct sigset_t sa_mask; + int sa_flags; +}; +struct sigaction act_INT; +struct sigaction act_TSTP; + +int Mpid_num; void catch_sigint(int signalNo) { // TODO: File this! + int cur_num = getpid(); + if(cur_num!=Mpid_num&&cur_num!=pid_num) + exit(1); + printf("cur_num : %d",cur_num); + printf("\nShell doesn't close!!!\n"); + } void catch_sigtstp(int signalNo) { // TODO: File this! + printf("\nIt doesn't move!!!\n"); +} + +void signal_setting(){ + Mpid_num = getpid(); +// ANUM = Mpid_num; + printf("Mpid_Num : %d \npid_num : %d\n",Mpid_num,pid_num); + +// if(pid_num!=Mpid_num){ + // if(back_num==0){ + act_INT.sa_handler = catch_sigint; + sigemptyset(&act_INT.sa_mask); + sigaction(SIGINT,&act_INT,NULL); + + act_TSTP.sa_handler = catch_sigtstp; + sigemptyset(&act_TSTP.sa_mask); + sigaction(SIGTSTP,&act_TSTP,NULL); +// } +// else if(back_num==1){ +// signal(SIGINT,SIG_IGN); +// signal(SIGTSTP,SIG_IGN); +//} +/* else if(pid_num==1){ + act_INT.sa_handler = catch_sigint; + sigemptyset(&act_INT.sa_mask); + sigaction(SIGINT,&act_INT,NULL); + + act_TSTP.sa_handler = catch_sigtstp; + sigemptyset(&act_TSTP.sa_mask); + sigaction(SIGTSTP,&act_TSTP,NULL); + + }*/// else{ +// signal(SIGINT,SIG_IGN); +// signal(SIGTSTP,SIG_IGN); +// } }