Thread: Process get's killed when invoking bash interactive with oneliner

  1. #1
    Registered User
    Join Date
    Jun 2022
    Posts
    4

    Unhappy Process get's killed when invoking bash interactive with oneliner

    Hi,

    I was coding a shell for fun and I discovered a weird bahaviour when invoking bash like this :
    Code:
    bash -ic <some_command>
    Basically instead of looping through, the program gets killed and I don't really know why. Could someone have an explanation ?

    Here is the basic code :

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    
    void loop_pipe (char***cmd)
    {
         pid_tpid,wpid;
         intstatus;
    
         pid=fork();
         if(pid==0)
         {
         // Child process
         if(execvp((*cmd)[0],*cmd)==-1)
             perror("Command error");
         exit(EXIT_FAILURE);
         }
         elseif(pid<0)
         {
             // Error forking
             perror("Fork error");
         }
         else
         {
             // Parent process
             do{
                 wpid=waitpid(pid,&status,WUNTRACED);
             }while(!WIFEXITED(status)&&!WIFSIGNALED(status));
         }
    
    }
    
    int main()
    {
         char*ls[]={"bash","-ic","uname",NULL};
         char**cmd[]={ls,NULL};
    
         while(1)
         {
             loop_pipe(cmd);
         }
    }


    Thanks !
    Last edited by Liwinux; 06-07-2022 at 10:43 AM.

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    Please edit your post and copy/paste your code as plain text.

    Presumably your problem is that you are forcing the shell to run interactively with -i. Try getting rid of that.

    BTW, you're missing <sys/wait.h> for waitpid.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  3. #3
    Registered User
    Join Date
    Jun 2022
    Posts
    4
    I just did that, I don't know where this weird colored formatting thing came from.

    The thing is that I'm coding a shell to I have to prevent this from happening. But how does running bash in interactive mode completely kills the parent process that executed it ? I'm forking the process so again how does bash gets to have my shell killed ?

    Not to mention that running bash with only the -i option doesn't to anything, it's rather combination or -ic that completely wrecks my shell or this code above

    EDIT :

    I think I got confused. My process wasn't being killed. It was suspended due to the interactive options you were right. But now I want to simulate the behavior of bash. If I run bash -ic, my previous bash doesn't get suspend. Whereas my shell does and I want to avoid that bu I don't know how then.
    Last edited by Liwinux; 06-07-2022 at 10:28 AM.

  4. #4
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    Looks like you might have just copy/pasted your code again from this website. Notice how all the spacing is gone? Look at the first two lines in loop_pipe.
    Anyway, obviously if you are making your own shell you can't invoke bash. That would be pointless! Your shell will be a replacement for the bash shell.

    EDIT: just saw your edit.
    Yeah, I was going to say that for me it's suspended.

    If I run bash -ic, my previous bash doesn't get suspend.
    Why would it? The bash you ran with bash -ic executes its command and exits. It's that bash (not the "previous" one) that is getting suspended in your program. I'm not entirely sure why, but I suspect you cannot combine -i and -c since the definition of -c is to run the given command and exit.

    EDIT2:
    It doesn't get suspended if you comment out the while(1) in main, therefore only calling loop_pipe once. Although it is killed, i.e., it doesn't just drop you into a second invocation of bash.
    Last edited by john.c; 06-07-2022 at 10:49 AM.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  5. #5
    Registered User
    Join Date
    Jun 2022
    Posts
    4
    Quote Originally Posted by john.c View Post
    Looks like you might have just copy/pasted your code again from this website. Notice how all the spacing is gone? Look at the first two lines in loop_pipe.
    Anyway, obviously if you are making your own shell you can't invoke bash. That would be pointless! Your shell will be a replacement for the bash shell.
    I just saw that it's now impossible for me to edit the main post. So if a mod could do it for me that would be awesome thanks.

    Quote Originally Posted by john.c View Post
    Why would it? The bash you ran with bash -ic executes its command and exits. It's that bash (not the "previous" one) that is getting suspended in your program. I'm not entirely sure why, but I suspect you cannot combine -i and -c since the definition of -c is to run the given command and exit.
    I mean, if it was bash that is running with -ic that got suspended, why does the program stop to execute then ? I'm still a bit confused here.
    I get the point where bash executes it's command, but then when it finishes, I should be putted back to my shell or in this case, I should be able to run again the same command, that is bash -ic uname. But somehow it gets suspended and I have to manually tell bash to resume the program, effectively iterate the infinite loop manually

    Quote Originally Posted by john.c View Post
    EDIT2:
    It doesn't get suspended if you comment out the while(1) in main, therefore only calling loop_pipe once. Although it is killed, i.e., it doesn't just drop you into a second invocation of bash.
    Well that would solve the question reading my example for sure. But how about my shell then ? I'm using the exact same "logic", get input from user, fork, execute command given by the user, wait on it to finish and repeat the whole process. So if the user passes bash -ic <command> well my shell gets suspended and bash takes the lead. I'm still unsure what's going on I'm already sorry for my slow understanding
    Last edited by Liwinux; 06-07-2022 at 11:24 AM.

  6. #6
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    I'm still a bit confused here.
    I'm confused too. I have no idea why it's being suspended.
    I see what you mean that if you made an actual shell it would have trouble running a (possibly malformed) command like 'bash -ic command' and would apparently get suspended.
    Clearly bash does not get suspended when you run that command.

    BTW, here's a fixed-up version of your original code (slightly reorganized but the same) so someone can more easily copy it to run it.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
     
    void loop_pipe(char***cmd)
    {
        pid_t pid = fork();
        if (pid < 0)
        {
            perror("fork you");
            exit(EXIT_FAILURE);
        }
     
        if (pid == 0)
        {
            // Child process
            execvp((*cmd)[0], *cmd); // does not return on success
            perror("execvp error");
            exit(EXIT_FAILURE);
        }
     
        // Parent process
        int status;
        do {
            waitpid(pid, &status, WUNTRACED);
        } while (!WIFEXITED(status) && !WIFSIGNALED(status));
    }
     
    int main()
    {
        char *ls[] = {"bash", "-ic", "uname", NULL};
        char **cmd[] = {ls, NULL};
     
        while (1)
        {
            loop_pipe(cmd);
        }
        return 0;
    }
    A little inaccuracy saves tons of explanation. - H.H. Munro

  7. #7
    Registered User
    Join Date
    Jun 2022
    Posts
    4
    Quote Originally Posted by john.c View Post
    I'm confused too. I have no idea why it's being suspended.
    I see what you mean that if you made an actual shell it would have trouble running a (possibly malformed) command like 'bash -ic command' and would apparently get suspended.
    Clearly bash does not get suspended when you run that command.
    The thing is that if it's malformed well we get an error and ask for another input. Something I forgot to mention is that I settled my shell as the default one for my account. If I issue the command "bash -ic", my shell enters an infinite loop effectively giving the only possibility to kill it. Now, If bash is the default one and I use the command, my own shell get suspended and I get back to bash but I can resume (what we have discussed here already). But guess what ? I saw this somewhere that caught my attention.

    "When a background process reads from the terminal it gets a SIGTTIN signal. Normally, that will stop it, the job control shell notices and tells the user, who can say fg to continue this background process as a foreground process, and then this process can read from the terminal."

    Well this is exactly what I'm describing, and It could also explain why my shell enters an infinite loop as I'm not able to read from stdout anymore effectively getc returning EOF and thus entering an infinite loop. Only one thing left... Why is it happening.

    Quote Originally Posted by john.c View Post
    BTW, here's a fixed-up version of your original code (slightly reorganized but the same) so someone can more easily copy it to run it.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
     
    void loop_pipe(char***cmd)
    {
        pid_t pid = fork();
        if (pid < 0)
        {
            perror("fork you");
            exit(EXIT_FAILURE);
        }
     
        if (pid == 0)
        {
            // Child process
            execvp((*cmd)[0], *cmd); // does not return on success
            perror("execvp error");
            exit(EXIT_FAILURE);
        }
     
        // Parent process
        int status;
        do {
            waitpid(pid, &status, WUNTRACED);
        } while (!WIFEXITED(status) && !WIFSIGNALED(status));
    }
     
    int main()
    {
        char *ls[] = {"bash", "-ic", "uname", NULL};
        char **cmd[] = {ls, NULL};
     
        while (1)
        {
            loop_pipe(cmd);
        }
        return 0;
    }
    Many thanks, it's better then the original !

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How To Check if process is associated with invoking terminal?
    By olig1905 in forum Linux Programming
    Replies: 2
    Last Post: 11-09-2011, 09:02 AM
  2. Is DllMain's DLL_PROCESS_DETACH called when process is killed?
    By chiefmonkey in forum Windows Programming
    Replies: 3
    Last Post: 10-09-2009, 02:03 AM
  3. Interactive vs non-interactive terminal session question
    By Overworked_PhD in forum Tech Board
    Replies: 2
    Last Post: 06-18-2009, 07:30 PM
  4. leaked memory not freed after process is killed?
    By nantonop in forum Linux Programming
    Replies: 16
    Last Post: 09-05-2007, 01:08 PM
  5. Invoking MSWord
    By Donn in forum C Programming
    Replies: 21
    Last Post: 09-08-2001, 04:08 PM

Tags for this Thread