I am writing a c program for a class that is a small shell. The user inputs a command, and the code executes it using the exec()
function.
I need to have a fork in the process so all the work is done in the child process. The only problem is that the child won't terminate properly and execute the command. When I run the code without the fork, it executes commands perfectly.
The problem seems to be coming from where I am creating the string to be used in the execv
call. It's the line of code where I call strcpy
. If I comment that out, things work fine. I also tried changing it to strncat
with the same problem. I'm clueless as to what's causing this and welcome any help.
#include <sys/wait.h>
#include <vector>
#include <sstream>
#include <cstdlib>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <unistd.h>
using namespace std;
string *tokenize(string line);
void setCommand(string *ary);
string command;
static int argument_length;
int main() {
string argument;
cout << "Please enter a unix command:\n";
getline(cin, argument);
string *ary = tokenize(argument);
//begin fork process
pid_t pID = fork();
if (pID == 0) { // child
setCommand(ary);
char *full_command[argument_length];
for (int i = 0; i <= argument_length; i++) {
if (i == 0) {
full_command[i] = (char *) command.c_str();
// cout<<"full_command " <<i << " = "<<full_command[i]<<endl;
} else if (i == argument_length) {
full_command[i] = (char *) 0;
} else {
full_command[i] = (char *) ary[i].c_str();
// cout<<"full_command " <开发者_如何学Python<i << " = "<<full_command[i]<<endl;
}
}
char* arg1;
const char *tmpStr=command.c_str();
strcpy(arg1, tmpStr);
execv((const char*) arg1, full_command);
cout<<"I'm the child"<<endl;
} else if (pID < 0) { //error
cout<<"Could not fork"<<endl;
} else { //Parent
int childExitStatus;
pid_t wpID = waitpid(pID, &childExitStatus, WCONTINUED);
cout<<"wPID = "<< wpID<<endl;
if(WIFEXITED(childExitStatus))
cout<<"Completed "<<ary[0]<<endl;
else
cout<<"Could not terminate child properly."<<WEXITSTATUS(childExitStatus)<<endl;
}
// cout<<"Command = "<<command<<endl;
return 0;
}
string *tokenize(string line) //splits lines of text into seperate words
{
int counter = 0;
string tmp = "";
istringstream first_ss(line, istringstream::in);
istringstream second_ss(line, istringstream::in);
while (first_ss >> tmp) {
counter++;
}
argument_length = counter;
string *ary = new string[counter];
int i = 0;
while (second_ss >> tmp) {
ary[i] = tmp;
i++;
}
return ary;
}
void setCommand(string *ary) {
command = "/bin/" + ary[0];
// codeblock paste stops here
You said:
Its the line of code where I call strcpy.
You haven't allocated any memory to store your string. The first parameter to strcpy is the destination pointer, and you're using an uninitialized value for that pointer. From the strcpy man page:
char *strcpy(char *s1, const char *s2);
The stpcpy() and strcpy() functions copy the string s2 to s1 (including the terminating `\0' character).
There may be other issues, but this is the first thing I picked up on.
精彩评论