I'm having an issue with a process being stuck on wait. I've been troubleshooting this issue and its the only bug i have currently for my shell program.
The problem is the program should exit when the user enters "exit". However it seems if the user enters an invalid string the program gets stuck on wait(). this results in having to type exit twice to exit instead of once. How do I stop this from happening, how do i exit from the wait() call when a user enters a dumb string?
Steps to reproduce:
- compile and run with gcc/g++
- type in an expletive of your choice
- type exit
- notice the program doesnt exit (because its stuck on wait() but prompting
- type exit again
- program exits
#include <iostream>
#include <unistd.h>
#include "stdlib.h"
#include "stdio.h"
#include <iostream>
#include <string>
#include <sys/wait.h>
#include <sstream>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
using std::string;
using std::cout;
using std::endl;
bool exitstatus;
int argsIndex = 0;
pid_t pid;
int main(void)
{
char * args[100];
string check = "";
while(exitstatus==false)
{
cout<<"tinyshell:~>";
std::getline(std::cin, check);
if(check == "exit"){
exitstatus==true;
}
if(exitstatus==false&&check!="cd..")
{
pid = fork();
perror("");
if (pid < 0) { /* error occurred */
fprintf(stderr, "Fork Failed");
//return 1;
}
else if (pid == 0 ) { /* child process */
execvp(args[0],args);
perror("");
}
else if(check!= "&"){/* parent will wait for the child to complete */
wait(NULL);
perror("");
// cout <<"Child Complete" << endl;
}
else
{
}
}
}
return 0;
};
It may have to do something with this line:
Did you, by any chance meant:
gcc
reports something like this for it anyway (-Wall
):That's a pretty nice example showing why enabling warnings is a good practice ...
There's also a more subtle problem with your code. You're not checking the result of your
execvp
function. So basically if you enter some garbage command in your shell your exec will fail but your child process will continue running the same code as the parent (the loop).Just add an
exit(EXIT_FAILURE);
after yourexecvp()
call.