Advertisement
Guest User

Untitled

a guest
Jun 28th, 2017
521
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.21 KB | None | 0 0
  1. /*-
  2.  * main.c
  3.  * Copyright (c) 1993-1999, Francisco Rosales <frosal@fi.upm.es>
  4.  *
  5.  * Minishell C source
  6.  * Show how to use "obtain_order" input interface function
  7.  *
  8.  * THIS FILE IS TO BE MODIFIED
  9.  */
  10.  
  11. #include <stddef.h>         /* NULL */
  12. #include <stdio.h>          /* setbuf, printf */
  13. #include <unistd.h>
  14. #include <stdlib.h>
  15. #include <paths.h>
  16. #include <fcntl.h>
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19.  
  20. #define STDIN_FILENO 0
  21. #define STDOUT_FILENO 1
  22. #define STDERR_FILENO 2
  23.  
  24. extern int obtain_order();      /* See parser.y for description */
  25.  
  26. int old_in, old_out, old_err;
  27.  
  28. // This function operates on redirection of STDIN, STDOUT, STDERR
  29. void redirection( char **fileC){
  30.     int fp;
  31.    
  32.     //Check if we have request the STDIN
  33.     if (fileC[0] != NULL) {
  34.        
  35.         //Open the file descriptor and open the file
  36.         fp=open(fileC[0],O_RDONLY,0666);
  37.        
  38.         //Close the STDIN
  39.         close(STDIN_FILENO);
  40.        
  41.         // I do a copy of STDIN on fp
  42.         dup(fp);
  43.     }
  44.     //Check if we have request the STDUOT
  45.     if (fileC[1] != NULL) {
  46.        
  47.         //Open the file descriptor and open and creat the file
  48.         fp=open(fileC[1], O_CREAT | O_TRUNC | O_WRONLY, 0666);
  49.        
  50.         //Close the STDOUT
  51.         close(STDOUT_FILENO);
  52.        
  53.         // I do a copy of STDOUT on fp
  54.         dup(fp);
  55.     }
  56.     //Check if we have request the STDERR
  57.     if (fileC[2] != NULL) {
  58.        
  59.         //Open the file descriptor and open and creat the file
  60.         fp=open(fileC[2], O_CREAT | O_TRUNC | O_WRONLY, 0666);
  61.        
  62.         //Close the STDERR
  63.         close(STDERR_FILENO);
  64.        
  65.         // I do a copy of STDERR on fp
  66.         dup(fp);
  67.        
  68.     }
  69. }
  70.  
  71. //With this function I copy the first position of standard INPUT, OUTPUT, ERROR
  72. void copyFileDescriptor()
  73. {
  74.     old_in = dup(STDIN_FILENO);
  75.     old_out = dup(STDOUT_FILENO);
  76.     old_err = dup(STDERR_FILENO);
  77.    
  78. }
  79.  
  80. //Reposition the three standard in old position
  81. void setupFiledescriptor()
  82. {
  83.     close(STDIN_FILENO);
  84.     dup(old_in);
  85.     close(STDOUT_FILENO);
  86.     dup(old_out);
  87.     close(STDERR_FILENO);
  88.     dup(old_err);
  89. }
  90.  
  91. void welcomeScreen()
  92.  
  93. {
  94.     printf("\n-------------------------------------------------\n");
  95.     printf("\tWelcome to MINI-shell  \n");
  96.     printf("\tAuthor :Giovanni Formisano Francesco D'Alia\n");
  97.     printf("-------------------------------------------------\n");
  98.     printf("\n\n");
  99. }
  100.  
  101. void shellPrompt(char *currentDirectory)
  102. {
  103.     printf("%s :> ",getcwd(currentDirectory, 1024));
  104. }
  105.  
  106.  
  107. int main(void)
  108. {  
  109.     char* currentDirectory;
  110.     char ***argvv;
  111.     int argvc;
  112.     char **argv;
  113.     char *filev[3];
  114.     int bg;
  115.     int err;
  116.     int ret,pid,status,pid2,pid3;
  117.     int fp[2],fp2[2];
  118.    
  119.    
  120.     setbuf(stdout, NULL);           /* Unbuffered */
  121.     setbuf(stdin, NULL);
  122.    
  123.     copyFileDescriptor();
  124.    
  125.     welcomeScreen();
  126.    
  127.     currentDirectory = (char*) calloc(1024, sizeof(char));
  128.    
  129.     while (1) {
  130.        
  131.         shellPrompt(currentDirectory);
  132.         //fprintf(stderr, "%s", "msh> ");   /* Prompt */
  133.        
  134.         ret = obtain_order(&argvv, filev, &bg);
  135.         if (ret == 0) break;        /* EOF */
  136.        
  137.        
  138.        
  139.         if (ret == -1) continue;    /* Syntax error */
  140.         argvc = ret - 1;        /* Line */
  141.         if (argvc == 0) continue;   /* Empty line */
  142.        
  143.    
  144.     //This variable args count how many command the user put on the shell
  145.     int args =0;
  146.    
  147.     //This FOR count count how many command the user put on the shell
  148.     for (argvc = 0; (argv = argvv[argvc]); argvc++)
  149.        
  150.         args++;        
  151.    
  152.         for (argvc = 0; (argv = argvv[argvc]); argvc++) {
  153.            
  154.             // First of all I check how many command I have insert, in this case with only one command
  155.             //I creat the fork to execution of that command while the father wait the child that it's finish
  156.             if (args == 1) {
  157.                
  158.                 redirection(filev);
  159.                
  160.                 //Create a fork
  161.                 pid = fork();
  162.                
  163.                 //Check the error
  164.                 if ( pid < 0 ){
  165.                    
  166.                     printf("error create fork!!!!");
  167.                     exit(1);
  168.                 }
  169.                 //This is child
  170.                 if ( pid == 0 ){
  171.                        
  172.                         //This command exe the command that find inside /bin/bash
  173.                         err = execvp((char *)argvv[argvc][0],argvv[argvc]);
  174.                    
  175.                         //Check the error of exevp
  176.                         if (err < 0)
  177.                             perror("errore execvp");
  178.                     exit(0);
  179.                
  180.                 }else {
  181.                     //This is the father and than with check (!bg) the programm control if there is or no
  182.                     // the command in background
  183.                     if(!bg) {
  184.                        
  185.                         //Wait the termination of child
  186.                         wait(&status);
  187.                     }
  188.                    
  189.                     else {
  190.                         printf("[%d]\n",pid);
  191.                         }
  192.                    }   
  193.             }
  194.            
  195.             //Recall the function setupFileDescriptor to rearrange the STANDARD INPUT OUTPU ERR
  196.             setupFiledescriptor();
  197.            
  198.             // First of all I check how many command I have insert, in this case with only two command
  199.             //Than I create a pipe to connect the two process. To do this I must create two fork, because the idea is
  200.             //one fork() for each process
  201.             if (args == 2) {
  202.                
  203.                 redirection(filev);
  204.                
  205.                 //Create the first fork()
  206.                 pid = fork();
  207.                
  208.                 //Check the error
  209.                 if ( pid < 0 ){
  210.                    
  211.                     printf("error create fork!!!!");
  212.                     exit(1);
  213.                 }
  214.                 if ( pid == 0 ){
  215.                    
  216.                     //Create a pipe for the connection and use two file descriptor
  217.                     pipe(fp);
  218.                    
  219.                     //I creat the second fork()
  220.                     pid2 = fork();
  221.                    
  222.                     if ( pid2 == 0 )
  223.                        
  224.                     {  
  225.                         //Here close the file descriptor STDOUTPUT
  226.                         close(STDOUT_FILENO);
  227.                        
  228.                         //Redirection the STDOUT on OUTPUT of pipe
  229.                         dup2(fp[1],STDOUT_FILENO);
  230.                        
  231.                         //Close the INPUT of pipe because must close the file descriptor that pipe don't use
  232.                         close(fp[0]);
  233.                        
  234.                         //This command exe the command that find inside /bin/bash
  235.                         err = execvp((char *)argvv[argvc][0],argvv[argvc]);
  236.                        
  237.                         //Check the error of exevp
  238.                         if (err < 0)
  239.                             perror("errore execvp");
  240.                         exit(0);
  241.                     }
  242.                     //Wait the termination of child
  243.                     wait(&status);
  244.                    
  245.                     //Close the INPUT
  246.                     close(STDIN_FILENO);
  247.                    
  248.                     //Redirection the STDINPUT on INPUT of pipe
  249.                     dup2(fp[0],STDIN_FILENO);
  250.                    
  251.                     //Close the OUTPUT of pipe because must close the file descriptor that pipe don't use
  252.                     close(fp[1]);
  253.                    
  254.                     //This command exe the second commad that user insert
  255.                     err = execvp((char *)argvv[argvc+1][0],argvv[argvc+1]);
  256.                    
  257.                     //Check the error of exevp
  258.                     if (err < 0)
  259.                         perror("errore execvp");
  260.                     exit(0);
  261.                    
  262.                 }else{
  263.  
  264.                     //This is the father and than with check (!bg) the programm control if there is or no
  265.                     // the command in background
  266.                     if(!bg) {
  267.                        
  268.                         //Wait the termination of child
  269.                         wait(&status);
  270.                         argvc++;
  271.                     }
  272.                    
  273.                     else {
  274.                         printf("[%d]\n",pid);
  275.                     }
  276.                 }
  277.             }
  278.            
  279.             //Recall the function setupFileDescriptor to rearrange the STANDARD INPUT OUTPU ERR
  280.             setupFiledescriptor();
  281.            
  282.             // First of all I check how many command I have insert, in this case with only three command
  283.             //Than I create two pipe to connect three process. To do this I must create three fork, because the idea is
  284.             //one fork() for each process.
  285.             //The idea is the fork many inside exec the first command, the second fork exec the second command,
  286.             // and the firs fork exec the last command.
  287.             if (args == 3) {
  288.                
  289.                 redirection(filev);
  290.                
  291.                 //Create the first fork()
  292.                 pid = fork();
  293.                
  294.                 //Check the error
  295.                 if ( pid < 0 ){
  296.                    
  297.                     printf("error create fork!!!!");
  298.                     exit(1);
  299.                    
  300.                 }
  301.                
  302.                 if ( pid == 0 ){
  303.                    
  304.                     //Create a pipe for the connection and use two file descriptor
  305.                     pipe(fp);
  306.                    
  307.                     //Create the second fork()
  308.                     pid2 = fork();
  309.                    
  310.                     //Chech error of second fork()
  311.                     if ( pid2 < 0 ){
  312.                        
  313.                         printf("error create fork!!!!");
  314.                         exit(1);
  315.                     }
  316.                    
  317.                     if ( pid2 == 0 )
  318.                        
  319.                     {  
  320.                         //I create the second pipe
  321.                         pipe(fp2);
  322.                        
  323.                         //I creat the third fork()
  324.                         pid3 = fork();
  325.                        
  326.                         //Check the error of third fork()
  327.                         if ( pid3 < 0 ){
  328.                            
  329.                             printf("error create fork!!!!");
  330.                             exit(1);
  331.                         }
  332.                         if ( pid3 == 0){
  333.                            
  334.                             //Close the INPUT
  335.                             close(fp2[0]);
  336.                            
  337.                             //Redirection the STDOUT on OUTPUT of pipe
  338.                             dup2(fp2[1],STDOUT_FILENO);
  339.                            
  340.                             //Close the INPUT of pipe because must close the file descriptor that pipe don't use
  341.                             close(fp2[1]);
  342.                            
  343.                             //This command exe the first command
  344.                             err = execvp((char *)argvv[argvc][0],argvv[argvc]);
  345.                            
  346.                             //Check error of execvp
  347.                             if (err < 0)
  348.                                 perror("errore execvp");
  349.                             exit(0);
  350.                        
  351.                         }else {
  352.                            
  353.                             //Wait the termination of child
  354.                             wait(&status);
  355.                            
  356.                             //Close the INPUT
  357.                             close (fp2[1]);
  358.                            
  359.                             //With this two function dup there is the connection of second command with
  360.                             //third command exchanging the INPUT of one with OUTPUT of the other one
  361.                             dup2(fp2[0],STDIN_FILENO);
  362.                             dup2(fp[1],STDOUT_FILENO);
  363.                            
  364.                             ////Close the INPUT of pipe one because must close the file descriptor that pipe don't use
  365.                             close (fp[0]);
  366.                            
  367.                             //Close the OUTPUT of pipe two because must close the file descriptor that pipe don't use
  368.                             close(fp2[1]);
  369.                            
  370.                             //This command exe the second command
  371.                             err = execvp((char *)argvv[argvc+1][0],argvv[argvc+1]);
  372.                            
  373.                             //Check error of execvp
  374.                             if (err < 0)
  375.                                 perror("errore execvp");
  376.                             exit(0);
  377.  
  378.                         }
  379.  
  380.                     }
  381.                    
  382.                     //Wait the termination of child
  383.                     wait(&status);
  384.                    
  385.                     //Close the STDIN
  386.                     close(STDIN_FILENO);
  387.                    
  388.                     //Redirection the STDINPUT on INPUT of pipe
  389.                     dup2(fp[0],STDIN_FILENO);
  390.                    
  391.                     //Close the OUTPUT of pipe two because must close the file descriptor
  392.                     close(fp[1]);
  393.                    
  394.                     //This command exe the third command
  395.                     err = execvp((char *)argvv[argvc+2][0],argvv[argvc+2]);
  396.                    
  397.                    
  398.                     if (err < 0)
  399.                         perror("errore execvp");
  400.                     exit(0);
  401.                    
  402.                 }else{
  403.                    
  404.                     //This is the father and than with check (!bg) the programm control if there is or no
  405.                     // the command in background
  406.                     if(!bg) {
  407.                        
  408.                         //Wait the termination of child
  409.                         wait(&status);
  410.                        
  411.                         argvc = argvc + 2;
  412.                     }
  413.                    
  414.                     else {
  415.                         printf("[%d]\n",pid);
  416.                     }
  417.                 }
  418.             }
  419.            
  420.             //Recall the function setupFileDescriptor to rearrange the STANDARD INPUT OUTPU ERR
  421.             setupFiledescriptor();
  422.         }
  423.         setupFiledescriptor();
  424.     }
  425.     return 0;
  426. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement