I am currently taking an OS class and our current project is to create a fully functional shell. I have a function for executing various commands using execv() and it works, but occasionally when I use certain commands like wc or ls -a I will get a malloc(): memory corruption aborted(core dumped) error. I am assuming it has something to do with memory management.
I use the new operator here
const char **cmdAndArgs = new const char *[cmdAndArgsVect.size() + 1]
and I thought I could just delete() the array at the end of the function, but when I do that, every input for my other commands comes in as ' !'.
Here is the full function in question
static int shellCommand(String_std lineCommand) {
std::vector<String_std> cmdAndArgsVect = splitCmd(lineCommand);
const char **cmdAndArgs = new const char *[cmdAndArgsVect.size() + 1];
bool redirectOut = false;
int redirectIndex;
const char *command = cmdAndArgsVect[0].c_str();
//changes the paths into const char *
String_std usrPath = "/usr/bin/";
usrPath += command;
const char *charUsrPath = usrPath.c_str();
String_std binPath = "/bin/";
binPath += command;
const char *charBinPath = binPath.c_str();
String_std localPath = "/usr/local/bin/";
localPath += command;
const char *charLocalPath = localPath.c_str();
//sets up argument array for execv
if (cmdAndArgsVect.size() + 1 == 2) {
//No arguments, but array still needs to be null terminating
cmdAndArgs[1] = NULL;
} else {
for (int i = 1; i < cmdAndArgsVect.size(); ++i) {
//in case of redirect operator
if (cmdAndArgsVect[i].compare(">") == 0) {
cmdAndArgs[i] = NULL;
redirectOut = true;
redirectIndex = i;
break;
}
cmdAndArgs[i] = cmdAndArgsVect[i].c_str();
}
//end of arguments, array needs to be null terminating unless redirect operator exist
if (!redirectOut) cmdAndArgs[cmdAndArgsVect.size() + 1] = NULL;
}
//section to check if redirect was done correctly
if (redirectOut) {
if (cmdAndArgsVect.size() != redirectIndex + 2) {
std::cout << "that is not the correct format for a redirect command" << "\n";
return 1;
}
}
pid_t pid = fork();
int status;
if (pid == -1) {
perror("did not fork properly");
//2 means that the fork failed
return 2;
} else if (pid == 0) {
if (redirectOut) {
const char *file = cmdAndArgsVect[redirectIndex + 1].c_str();
int fd = open(file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
dup2(fd, 1); // make stdout go to file
dup2(fd, 2); // makes stderr go to the file
close(fd);
}
cmdAndArgs[0] = charBinPath;
if (execv(charBinPath, (char **) cmdAndArgs) != -1) exit(0);
cmdAndArgs[0] = charUsrPath;
if (execv(charUsrPath, (char **) cmdAndArgs) != -1) exit(0);
cmdAndArgs[0] = charLocalPath;
if (execv(charLocalPath, (char **) cmdAndArgs) != -1) exit(0);
std::cout << command << ": is not a valid command" << "\n";
exit(-1);
}
waitpid(pid, &status, 0);
return 1;
}
Aucun commentaire:
Enregistrer un commentaire