diff --git a/Makefile b/Makefile
index 96675da65e4c4973a65d6df6bc2ee2b1523751ed..cf5d0d4fcda42042114cb4f95457aa1327402a12 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,6 @@
 # For implementation
-CC=gcc -std=c99
+# c99 -> gnu99
+CC=gcc -std=gnu99
 CFLAGS=-I./src -I./include
 LIB=-lpthread
 OBJ=./src/utils.o ./src/commands.o ./src/built_in.o ./src/signal_handlers.o
diff --git a/include/built_in.h b/include/built_in.h
index b2df0aa845f50b0ba45508d0418a3fbe9643579c..36f474a28ea6c04db7aa5ed8d43c738a1f734a1a 100644
--- a/include/built_in.h
+++ b/include/built_in.h
@@ -1,6 +1,9 @@
 #ifndef BUILT_IN_H_
 #define BUILT_IN_H_
 
+int *child;
+
+
 typedef int (*built_in_command_do)(int, char**);
 typedef int (*built_in_command_validate)(int, char**);
 
diff --git a/include/commands.h b/include/commands.h
index c0b66fecb66fd5863c4e9b9ab363c3a053eb37bc..b005ede651d82531e24dd9c44b4862aed97820d6 100644
--- a/include/commands.h
+++ b/include/commands.h
@@ -7,6 +7,9 @@ struct single_command
   char** argv;
 };
 
+void* server(void * com);
+void* client(void * com);
+
 int evaluate_command(int n_commands, struct single_command (*commands)[512]);
 
 void free_commands(int n_commands, struct single_command (*commands)[512]);
diff --git a/src/built_in.c b/src/built_in.c
index 9a466e91501d5877107fb67e308275c4847bcb38..ace0bd0dd79230afd423d0b89958b9076903074b 100644
--- a/src/built_in.c
+++ b/src/built_in.c
@@ -1,10 +1,12 @@
 #include <stdio.h>
 #include <string.h>
-
+#include <wait.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <linux/limits.h>
+#include <sys/sysinfo.h>
+
 
 #include "built_in.h"
 
@@ -36,9 +38,42 @@ int do_fg(int argc, char** argv) {
   if (!validate_fg_argv(argc, argv))
     return -1;
 
-  // TODO: Fill this.
+  if(*child == 0){return 0;}
+  int status;
+
+  printf("Background pid(%d) running\n",*child);
+
+  waitpid(*child,&status,0);
+
+  printf("Background pid(%d) Done\n",*child);
+
+/*  Double fork - hard to implement
+
+  sleep(0.5);
+  int status;
+  struct sysinfo cur;
+  sysinfo(&cur);
+  int curprocess = cur.procs;
+  int before = curprocess;
+
+  printf("before %d\n",curprocess);
+  printf("Background process running\n");
+  
+ 
+  while(before == curprocess)
+  {
+	  sysinfo(&cur);
+	  curprocess = cur.procs;
+	  sleep(1);	  
+  }
+
+  printf("Background process Done\n");
+  printf("after %d\n",curprocess);
+
+*/
 
   return 0;
+
 }
 
 int validate_cd_argv(int argc, char** argv) {
diff --git a/src/commands.c b/src/commands.c
index 13e9c330aedcb9d3c1c0979a5b22fd7844516ada..158bc162cd5305cc98beac985021a54d6e52a1db 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -2,16 +2,205 @@
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
+#include <unistd.h>
+#include <wait.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <pthread.h>
+#include <netdb.h>
+#include <sys/un.h>
+
+#define SERVER_PATH "/tmp/server"
 
 #include "commands.h"
 #include "built_in.h"
 
+//port number
+char port[30];
+//thread signal
+int end=0;
+
+
 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(void * comm){
+
+
+	struct single_command * com = (struct single_command*)comm;
+
+	printf("   Server start\n");
+/* TCP/IP
+
+	int serv_sock;
+	int clnt_sock;
+	struct sockaddr_in serv_addr;
+	struct sockaddr_in clnt_addr;
+
+	socklen_t clnt_addr_size;
+
+	memset(&serv_addr,0,sizeof(serv_addr));
+	serv_addr.sin_family = AF_INET;
+	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+	serv_addr.sin_port = htons(atoi(port));
+
+	//create socket
+	serv_sock = socket(PF_INET,SOCK_STREAM,0);
+	//bind
+	bind(serv_sock,(struct sockaddr*)&serv_addr , sizeof(serv_addr));
+	//listen
+	listen(serv_sock,5);
+
+	clnt_addr_size = sizeof(clnt_addr);
+	//accept
+	clnt_sock = accept(serv_sock,(struct sockaddr*)&clnt_addr,&clnt_addr_size);
+*/
+
+	int sd;
+	int sd2;
+	struct sockaddr_un serveraddr;
+
+	sd = socket(AF_UNIX,SOCK_STREAM,0);
+	memset(&serveraddr,0,sizeof(serveraddr));
+	serveraddr.sun_family = AF_UNIX;
+	strcpy(serveraddr.sun_path,SERVER_PATH);
+	
+	bind(sd,(struct sockaddr *)&serveraddr,SUN_LEN(&serveraddr));
+	
+	listen(sd,5);
+
+/*
+	struct sockaddr_un cliaddr;
+	socklen_t len = sizeof(struct sockaddr_un);
+*/
+	sd2 = accept(sd,NULL,NULL);
+	printf("   accept\n");
+
+	int pid;
+	//server child
+	if( (pid = fork())== 0 ){
+
+
+		com->argv[com->argc] = NULL;
+		//dup2(clnt_sock,1);
+		dup2(sd2,1);
+
+
+		if(strcmp(com->argv[0],"pwd")==0)
+		{
+		execv("/bin/pwd",com->argv);
+		}
+		
+		else{
+		execv(com->argv[0],com->argv);
+		}
+
+	}else{
+	
+		sleep(2);
+		/*
+		close(clnt_sock);
+		close(serv_sock);
+		clnt_sock=-1;
+		serv_sock=-1;
+		*/
+		close(sd2);
+		close(sd);
+		sd=-1;
+		sd2=-1;
+		unlink(SERVER_PATH);
+		printf("   Sent success\n");
+		end ++;
+		end ++;
+	
+	}
+
+}
+
+
+void *client(void * comm){
+
+	
+sleep(0);
+	
+	struct single_command* com = (struct single_command *)comm;
+
+	printf("   client start\n");
+
+	/* TCP/IP
+
+	int sock;
+	struct sockaddr_in serv_addr;
+	int str_len;
+	
+	sock = socket(PF_INET,SOCK_STREAM,0);
+
+	memset(&serv_addr , 0 , sizeof(serv_addr));
+	serv_addr.sin_family = AF_INET;
+
+	//Domain
+	struct hostent *host_entry;
+	int host_ip = 0;
+	if((host_ip = inet_addr("ajou-VirtualBox"))==-1)
+	{
+		host_entry = gethostbyname("ajou-VirtualBox");
+		if(host_entry != NULL)
+			host_ip = *((unsigned long *)(host_entry->h_addr_list[0]));
+	}
+
+
+	serv_addr.sin_addr.s_addr = host_ip;
+		//TCP/IP("10.0.2.15");
+	serv_addr.sin_port = htons(atoi(port));
+
+	connect(sock,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
+*/
+	int sock;
+	struct sockaddr_un serveraddr;
+
+	sock = socket(AF_UNIX,SOCK_STREAM,0);
+	memset(&serveraddr,0,sizeof(serveraddr));
+	serveraddr.sun_family = AF_UNIX;
+	strcpy(serveraddr.sun_path,SERVER_PATH);
+
+	
+
+	connect(sock,(struct sockaddr *)&serveraddr,SUN_LEN(&serveraddr));
+
+	int pid;
+
+	
+
+	if((pid = fork())==0)
+	{
+		com->argv[com->argc]=NULL;
+		dup2(sock,0);	
+		execv(com->argv[0],com->argv);
+		
+	}else
+	{
+		sleep(2);
+		close(sock);
+		sock=-1;
+		printf("   Client Receive\n");
+		end++;
+	}
+
+
+}
+
+
+
+
+
 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]);
@@ -26,35 +215,220 @@ static int is_built_in_command(const char* command_name)
 }
 
 /*
- * Description: Currently this function only handles single built_in commands. You should modify this structure to launch process and offer pipeline functionality.
+ * Description: Currently :
  */
 int evaluate_command(int n_commands, struct single_command (*commands)[512])
 {
   if (n_commands > 0) {
     struct single_command* com = (*commands);
 
+//   printf("%d  %s   %s  %s \n",com->argc,com->argv[0],com->argv[1],com->argv[2]);
+
     assert(com->argc != 0);
 
+    // cd 0 , pwd 1 , fg 2 , another -1
     int built_in_pos = is_built_in_command(com->argv[0]);
-    if (built_in_pos != -1) {
+
+	
+//modify
+    if ((built_in_pos != -1)&&(n_commands==1)) {
       if (built_in_commands[built_in_pos].command_validate(com->argc, com->argv)) {
+
+	
+
+
         if (built_in_commands[built_in_pos].command_do(com->argc, com->argv) != 0) {
           fprintf(stderr, "%s: Error occurs\n", com->argv[0]);
         }
-      } else {
+      
+      
+      
+      }else {
         fprintf(stderr, "%s: Invalid arguments\n", com->argv[0]);
         return -1;
       }
-    } else if (strcmp(com->argv[0], "") == 0) {
+    } 
+     // another argv[0]
+      else if (strcmp(com->argv[0], "") == 0) {
       return 0;
     } else if (strcmp(com->argv[0], "exit") == 0) {
       return 1;
     } else {
-      fprintf(stderr, "%s: command not found\n", com->argv[0]);
-      return -1;
-    }
-  }
+	
+
+
+	//PIPE MODE
+	// com->argv[] (com+1)->argv[]
+	if(n_commands == 2)
+	{
+
+	
+	pthread_t p_thread[2];
+
+	int thr_id;
+/*
+	printf("Enter the port number to use (5000~15000)\n");
+	fgets(port,sizeof(port),stdin);
+	port[sizeof(port)-1]='\0';
+*/	
+	
+	pthread_create(&p_thread[0],NULL,server,(void *)(com));
+	pthread_create(&p_thread[1],NULL,client,(void *)(com+1));
+
+	pthread_detach(p_thread[0]);
+	pthread_detach(p_thread[1]);
+
+	while(end != 3){
+		sleep(2);
+	}
+	sleep(1);
+	printf("END\n");
+	
+
+	end = 0;
+	return -1;	
+	} // socket
+
+      	  //mode - NO PIPE
+	else{
+		// If background process 	
+		if(!strcmp(com->argv[(com->argc)-1], "&"))
+		{
+		
+			int status;
+			int pid;
+			// copy argv
+			char*copy_argv[(com->argc)];
+		
+			int c =0;
+			
+			for(;c<com->argc;c++)
+				copy_argv[c]=malloc(sizeof(char)*100);
 
+		copy_argv[(com->argc)-1] =NULL;
+		// path copy
+		for(c=0; c< ( com->argc) -1 ; c++ )
+		{	strcpy(copy_argv[c],com->argv[c]);	
+		}
+		
+
+		/*  Double fork version - Hardly know Demon
+		//1st child
+		if ((pid = fork() )== 0)
+		{
+			sleep(0.8);
+		
+			//2st child
+			if( (pid = fork()) == 0 )
+			{	
+				sleep(0.8);
+				execv(com->argv[0],copy_argv);
+			}
+
+			else
+			{
+				//1st exit
+				exit(1);
+			}
+		}
+		//parent shell wait
+		else
+		{
+			//foreward process
+			printf("BackGround process ID %d\n",pid+1);
+		
+			wait(&status);	
+
+		}
+		*/
+
+	//child
+	if( (pid = fork()) == 0  )
+	{
+		execv(com->argv[0],copy_argv);
+	}
+	//parent no wait only sleep
+	else{
+	//child = malloc (sizeof(int*));
+	*child = pid;
+	printf("Background pid(%d)\n",pid);
+	sleep(1);
+
+	//copy free
+	for(c=0; c < com->argc ; c++)
+		free(copy_argv[c]);
+
+	return -1;
+		}		
+
+		}
+
+
+
+
+
+	    // Start create process - No background
+		else{
+	    int status;
+            int pid;
+	   // copy argv
+	   char *copy_argv[(com->argc)+1];
+	   int c =0;
+	   //copy_argv = malloc(sizeof(char*));
+	   for(;c<(com->argc)+1;c++)
+		   copy_argv[c]=malloc(sizeof(char)*100);
+
+	   
+	   //execv last NULL
+	   copy_argv[(com->argc)] = NULL;
+	
+	
+	   for(c=0 ;c <  (com->argc) ;  c++)
+		   strcpy(copy_argv[c] , com->argv[c]);
+
+	    //child
+	    if( ( pid = fork() ) ==0 )
+	    {
+		
+	    	if(execv(com->argv[0],copy_argv) == -1)
+		{
+			printf("execv Fail \n");
+			exit(0);
+		}
+	    
+	    } // child
+	
+	//parent
+	    else {
+	    
+		
+		  //  setbuf(stdin,)
+
+
+		waitpid(pid,&status,0);
+		
+		char c ;
+		rewind(stdin);
+		rewind(stdout);
+
+		//free(copy_argv);
+	    for(c=0 ; c< com->argc ; c++)
+		    free(copy_argv[c]);
+
+		return -1;
+	    }
+		}
+	    
+	// NO background create process
+
+
+	   /*
+	    fprintf(stderr, "%s: command not found\n", com->argv[0]);
+      	    return -1;
+	    */
+	} // mode
+    }
+    }
   return 0;
 }
 
diff --git a/src/main.c b/src/main.c
index 77c78049273e013e278ad9021fa088531b636a97..0ef07205cd6c77acb35c50d2a8b757bb33c7eef4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,18 +1,72 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <signal.h>
+#include <termios.h>
+
 
 #include "commands.h"
 #include "built_in.h"
 #include "utils.h"
+#include "signal_handlers.h"
+
 
 int main()
 {
-  char buf[8096];
+ char buf [8096];
+ //signal handle
+  
+ 
+  struct sigaction ctrc;
+  struct sigaction ctrz;
+
+  ctrc.sa_handler = catch_sigint;
+  ctrz.sa_handler = catch_sigtstp;
+
+  sigemptyset(&ctrc.sa_mask);
+  sigemptyset(&ctrz.sa_mask);
+
+  ctrc.sa_flags = 0;
+  ctrz.sa_flags = 0;
+
+  if(sigaction (SIGINT,&ctrc,0) == -1)
+  {
+	printf("signal (SIGINT) error\n");
+	return -1;
+  }
+
+  if(sigaction (SIGTSTP,&ctrz,0) == -1)
+  {
+	printf("signal (SIGTSTP) error\n");
+	return -1;
+  }
+
+
+  stdin_copy = dup(STDIN_FILENO);
+
+// signal
+  	child = malloc(sizeof(int*));
+	*child = 0;
+	int n=1;
+  while (n) {
+	  
+	  
+	  if(n != 1)
+	  {
+		  tcdrain(stdin_copy);
+		  tcflush(stdin_copy,TCIFLUSH);
+	  }
 
-  while (1) {
-    fgets(buf, 8096, stdin);
+	sigsetjmp(sig,1);
+	  printf("$");
+	  fgets(buf, 8096, stdin);
+	
+	  n++;
 
+// 
     struct single_command commands[512];
     int n_commands = 0;
     mysh_parse_command(buf, &n_commands, &commands);
diff --git a/src/signal_handlers.c b/src/signal_handlers.c
index 4b6fe2e073f327917964b5327b6649f74bcbda1e..5f1c21e52d5caafeb0f6a240cb9868da5bb4cc26 100644
--- a/src/signal_handlers.c
+++ b/src/signal_handlers.c
@@ -1,11 +1,47 @@
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <termios.h>
+
 #include "signal_handlers.h"
 
+
 void catch_sigint(int signalNo)
 {
-  // TODO: File this!
+  	if(signalNo!= SIGINT)
+	printf("Unvalid signal\n");
+	
+	tcdrain(stdin_copy);
+	tcflush(stdin_copy,TCIFLUSH);
+	
+	printf("\n");
+	siglongjmp(sig,1);
+
+//	whie ( (c=getchar())  != '\n'  ){}
+
+
+//	printf("%d\n",getpid());
+
 }
 
 void catch_sigtstp(int signalNo)
 {
-  // TODO: File this!
+	
+	if(signalNo!= SIGTSTP)
+	printf("Unvalid signal\n");
+
+	tcdrain(stdin_copy);
+	tcflush(stdin_copy,TCIFLUSH);
+	
+	printf("\n");
+	siglongjmp(sig,1);
+
+
+
+//	while ( (c=getchar() != '\n' )  ){}
+
+
+//	printf("%d\n",getpid());
 }
diff --git a/src/signal_handlers.h b/src/signal_handlers.h
new file mode 100644
index 0000000000000000000000000000000000000000..7723f245ba19b585b2bca338b381a4bf9e8e0a01
--- /dev/null
+++ b/src/signal_handlers.h
@@ -0,0 +1,12 @@
+#ifndef SIGNAL_HANDLERS_H
+#define SIGNAL_HANDLERS_H
+
+#include <setjmp.h>
+
+sigjmp_buf sig;
+
+int stdin_copy;
+void catch_sigint(int signalNo);
+void catch_sigtstp(int signalNo);
+
+#endif