Jump to content

A little mind boggled by exec() ?

- - - - -

  • Please log in to reply
5 replies to this topic

#1
agnl666

agnl666

    Programmer

  • Members
  • PipPipPipPip
  • 173 posts
  • Programming Language:C, Java, C++
  • Learning:Python, Assembly
Hello and thanks in advance,

I am currently working on a program that will launch another program multiple times though I have hit a road block. I am attempting to launch a new process within a loop by forking and then calling exec with the child process. This seems to work fine though as soon as I place exec within a loop it all fails. I was hoping someone would know why and suggest a possible solution to allow me to launch a new process within a loop multiple times.

Here is the code.


int main()
{
    const char *PROG_DIR = "/home/me/Desktop/SandBox/Dummy";
    const char *PROG_NAME = "Dummy";

    char *arg[] = {(char*)PROG_NAME};
    cout << "START" << endl;
    int status;
    for (unsigned int i = 0; i < 5; i++) 
    {
        int pid = vfork();
        if (pid == 0)  // this is the child proccess
        {
            execv(PROG_DIR, arg);
            
            // only reached if execv() fails
            cerr << "FAIL" << endl; exit(EXIT_SUCCESS);
        }
        wait(&status);  // forces the parent to wait until the child is finished 
        
        cout << status << endl;
    }
    if (status == 0)
    {
        cout << "END" << endl;
    }
}


So I have narrowed the problem down to execv() not actually being executed though I do not know why.

This is the "Dummy" code.


int main(int argc, char* argv[])
{
    // kill time
    usleep(1000000);
    cout << "RUN" << endl;
    exit(0);
    return 1;
}


Both of these pieces of code compile properly (I have the include statements needed).

The output for the program is :

START
FAIL
0
FAIL
0
FAIL
0
FAIL
0
FAIL
0
END

though I would expect and like it to be :

START
RUN
0
RUN
0
RUN
0
RUN
0
RUN
0
END

Which would indicate execv() is being called and run properly. I have checked the paths and names and everything is correct so upon several hours of beating my head off the wall I have narrowed the problem down to the execv() call.

Thank you for any and all help with this problem.

#2
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,720 posts
  • Programming Language:C, Java, C++, PHP, Python, Perl, Assembly, Bash, Others
  • Learning:JavaScript
Change your arguments to:

char *arg[] = {(char *)PROG_NAME, NULL};

See if that works.
sudo rm -rf /

#3
agnl666

agnl666

    Programmer

  • Members
  • PipPipPipPip
  • 173 posts
  • Programming Language:C, Java, C++
  • Learning:Python, Assembly
Thank you. It was a success!

This did not seem to matter when implementing execv() outside of a loop though seems to have made a world of difference when using it within the loop.

#4
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,720 posts
  • Programming Language:C, Java, C++, PHP, Python, Perl, Assembly, Bash, Others
  • Learning:JavaScript
Hm. It should've always failed if you didn't have a terminating null.
sudo rm -rf /

#5
agnl666

agnl666

    Programmer

  • Members
  • PipPipPipPip
  • 173 posts
  • Programming Language:C, Java, C++
  • Learning:Python, Assembly

int main() 
{
     const char *PROG_DIR = "/home/me/Desktop/SandBox/Dummy";
     const char *PROG_NAME = "Dummy";
      char *arg[] = {(char*)PROG_NAME};
     cout << "START" << endl;

     int status;
     // for (unsigned int i = 0; i < 5; i++)              < -- This is now no longer in a loop
     {
         int pid = vfork();
         if (pid == 0)  // this is the child proccess
         {
             execv(PROG_DIR, arg);
                         
            // only reached if execv() fails
             cerr << "FAIL" << endl;    exit(EXIT_SUCCESS);
          }         
         wait(&status);  // forces the parent to wait until the child is finished                   
         cout << status << endl;
     }
     if (status == 0)
     {
         cout << "END" << endl;
     }
}


I considered that before posting and tested the above code. I found that this would work, though once the loop was implemented it would no longer function. This was a huge source of confusion and why I did not think that the NULL would really make a huge difference.

Most of the C/C++ programming I have been doing has been more to the C++ end of the spectrum. I think I am going to have to start thinking more C when dealing with older libraries because when looking at this, it seem obvious that the simplest implementation would of execv() would required a NULL at the end because the array length is not provided.

Thank you again! : )

#6
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,720 posts
  • Programming Language:C, Java, C++, PHP, Python, Perl, Assembly, Bash, Others
  • Learning:JavaScript
Read the documentation for the functions, as it'll save you a lot of time (and hair). I speak from experience. :D
sudo rm -rf /




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users