Reputation: 9
I am new to C++ and Linux and I am confused on how to correctly pass an integer parameter using execlp() to a child class. I tried following the parameter requirements for this system call, however, the argument is not passing the correct value when I am executing the program. The char conversions is what is making me confused.
In the programs below, the parent accepts gender name pairs from the terminal. Next, it uses the fork() and exec() system calls where it passes the child number, gender, and name to the child program. The child program will output the statement. The output for the child numbers is off (should be: 1,2,3,4,...ect.). However, the output value is blank. Is it because of how I am initializing the argument in the execlp() system call?
Below is my code for the parent program - parent.cc:
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main (int argc, char* argv[])
{
int i, num = 0;
/* Holds the value of the number of pairs */
int pairs = (argc - 1) / 2;
pid_t pid;
cout << "I have " << pairs << " children." << endl;
/* Perform all child process depending on the number of name-gender pairs*/
for (i = 1; i <= argc-1; i+=2)
{
pid = fork();
/* Child process */
if (pid == 0)
{
char n[] = {char(num++)};
execlp("./c",n,argv[i],argv[i+1], NULL);
}
/* Parent will wait until all child processes finish */
wait(NULL);
}
cout << "All child process terminated. Parent exits." << endl;
/* Exits program */
return 0;
}
Here is my child program- child.cc
#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
using namespace std;
int main(int argc, char* argv[])
{
/* When child process starts, it will print out this statement */
cout << "Child # " << argv[0] << ": I am a " << argv[1] << ", and my name is " << argv[2] << endl;
exit(0);
}
Here is my output in the terminal:
g++ -o parent.cc
g++ -o c child.cc
./p boy Mark girl Emily boy Daniel girl Hailey
I have 4 children.
Child # : I am a boy, and my name is Mark
Child # : I am a girl, and my name is Emily
Child # : I am a boy, and my name is Daniel
Child # : I am a girl, and my Hailey
All child process terminated. Parent exits.
Upvotes: 0
Views: 1297
Reputation: 123410
There's two and a half issues:
argv[0]
is conventionally the program name, and failing to follow this convention means that e.g. ./c 1 boy Mark
will not work in a shell, and that the child process can't easily be substituted for something written in a different language.Here's the updated parent process:
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main (int argc, char* argv[])
{
int i, num = 0;
/* Holds the value of the number of pairs */
int pairs = (argc - 1) / 2;
pid_t pid;
cout << "I have " << pairs << " children." << endl;
/* Perform all child process depending on the number of name-gender pairs*/
for (i = 1; i <= argc-1; i+=2)
{
pid = fork();
/* Child process */
if (pid == 0)
{
string str = to_string(num);
execlp("./c",
"./c", // Conventionally the first argument is the program name
str.c_str(), // Pass in the correctly formatted number
argv[i],argv[i+1], NULL);
}
// Increment in the parent process so that the change is not lost
num++;
/* Parent will wait until all child processes finish */
wait(NULL);
}
cout << "All child process terminated. Parent exits." << endl;
/* Exits program */
return 0;
}
Accordingly, the child should access argv[1]
, 2, and 3, and not 0, 1 and 2.
Upvotes: 1