Search code examples
cforkexeccommand-promptbin

launching bin programs with fork and exec


im coding a microshell that will launch programs from bin file with fork and exec and it works fine but it always gets input in the next line without command prompt and i dont know how to deal with that

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#define MAX 4096
#define BLUE "\x1b[94m"
#define CLEAR "\x1b[0m"
int main()
{
    int pyk = 1;
    while (pyk == 1)
    {
        struct stat buf;
        const char *space = " ";
        const char *enter = "\n";
        char *token;
        char input[MAX];
        char *arg;
        char *cwd = getcwd(NULL, 0);
        printf(BLUE "[{%s}] $ ", cwd);
        printf(CLEAR);

        fgets(input, MAX, stdin);
        token = strtok(input, space);
        arg = strtok(NULL, enter);

        if (!strncmp(token, "/bin/", 5))
        {
            if (!stat(token, &buf))
            {
                if (fork() == 0)
                {

                    pyk = 0;

                    execl(token, arg, NULL);

                    continue;
                }
                else
                {
                    continue;
                }
            }
        }
    }
    return 0;
}
[{/home/maks/lab/vsc}] $ /bin/ls ls
[{/home/maks/lab/vsc}] $ a.out  messenger  pliczek.cm  shel  shel.c  shel.o  test  test.c  -W

[{/home/maks/lab/vsc}] $ 

the empty space is where it gets input right after ls and all i wanna do is to put there command promt keep in mind its just a part of my code


Solution

  • You only want to continue once the child process has finished, so you have to wait for it to do that:

    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h> 
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/wait.h>
    #define MAX 4096
    #define BLUE "\x1b[94m"
    #define CLEAR "\x1b[0m"
    int main() 
    {  
      int pyk=1;
       while(pyk==1){
                 struct stat buf;
                  const char *space=" ";
                const char *enter="\n"; 
                char *token;
                char input[MAX];
                char *arg;
                char * cwd = getcwd(NULL, 0);
                int child;
                  printf(BLUE "[{%s}] $ ", cwd);
                   printf(CLEAR);
                    fflush(stdout);
                  fgets(input, MAX, stdin);
                  token = strtok(input, space);
                  arg = strtok(NULL, enter);      
                 
                   if (!strncmp(token,"/bin/",5))
                    {
                     
                        if (!stat(token,&buf))
                        {
                           child = fork();
    
                            if(child==0)
                            {  
                                pyk=0;
                                  execl(token, arg, NULL);
                                        continue;               
                            }
                                else
                                {      
                                        wait(NULL);           
                                }  
                    }
       }
       }
     return 0;
    }