Skip to content
Snippets Groups Projects
Select Git revision
  • 0da38cdb4e257cffb72ee31186cb7bed83c1ca0c
  • master default
2 results

commands.c

Blame
  • Forked from sce213ta / mysh-1
    1 commit ahead of the upstream repository.
    KwonSunyoung's avatar
    KwonSunyoung authored
    0da38cdb
    History
    commands.c 7.65 KiB
    #include <stdio.h>
    #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]);
    
      for (int i = 0; i < n_built_in_commands; ++i) {
        if (strcmp(command_name, built_in_commands[i].command_name) == 0) {
          return i;
        }
      }
    
      return -1; // Not found
    }
    
    /*
     * 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]);
    
    	
    //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 {
            fprintf(stderr, "%s: Invalid arguments\n", com->argv[0]);
            return -1;
          }
        } 
         // another argv[0]
          else if (strcmp(com->argv[0], "") == 0) {
          return 0;
        } else if (strcmp(com->argv[0], "exit") == 0) {
          return 1;
        } else {
    	
    
    
    	//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;
    }
    
    void free_commands(int n_commands, struct single_command (*commands)[512])
    {
      for (int i = 0; i < n_commands; ++i) {
        struct single_command *com = (*commands) + i;
        int argc = com->argc;
        char** argv = com->argv;
    
        for (int j = 0; j < argc; ++j) {
          free(argv[j]);
        }
    
        free(argv);
      }
    
      memset((*commands), 0, sizeof(struct single_command) * n_commands);
    }