Corrected some memory leaks at exit due to stringToArgcArgv().
This commit is contained in:
parent
dd2e2ad50b
commit
40f2b2ee6b
6 changed files with 48 additions and 13 deletions
|
@ -92,6 +92,8 @@ namespace mshconsole {
|
||||||
while (poptPeekArg(pc) != NULL)
|
while (poptPeekArg(pc) != NULL)
|
||||||
nonOptionArgs.push_back(const_cast<const char*>(poptGetArg(pc)));
|
nonOptionArgs.push_back(const_cast<const char*>(poptGetArg(pc)));
|
||||||
|
|
||||||
|
poptFreeContext(pc);
|
||||||
|
|
||||||
return (*funcCommand)(c,datas,nonOptionArgs);
|
return (*funcCommand)(c,datas,nonOptionArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,5 +112,10 @@ namespace mshconsole {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Command::~Command(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
const struct poptOption Command::POPT_TERMINATOR = {NULL,'\0',POPT_ARG_NONE,NULL,-1,NULL,NULL};
|
const struct poptOption Command::POPT_TERMINATOR = {NULL,'\0',POPT_ARG_NONE,NULL,-1,NULL,NULL};
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,17 +55,21 @@ int main(int argc, char **argv)
|
||||||
string c = "msh-console-test";
|
string c = "msh-console-test";
|
||||||
string ps = "[msh-console-test]:";
|
string ps = "[msh-console-test]:";
|
||||||
Shell mshConsoleTest(c, ps, cin,cout,cerr, &setup);
|
Shell mshConsoleTest(c, ps, cin,cout,cerr, &setup);
|
||||||
Command* help = new Command("help", &helpExecute);
|
Command help("help", &helpExecute);
|
||||||
struct poptOption h = {"help",'h',POPT_ARG_NONE,NULL,1000,"advance","advaced options"};
|
struct poptOption h = {"help",'h',POPT_ARG_NONE,NULL,1000,"advance","advaced options"};
|
||||||
struct poptOption p = {"prova",'p',POPT_ARG_STRING,NULL,1000,"cose","cosecose"};
|
struct poptOption p = {"prova",'p',POPT_ARG_STRING,NULL,1000,"cose","cosecose"};
|
||||||
help->addOption(h);
|
help.addOption(h);
|
||||||
help->addOption(p);
|
help.addOption(p);
|
||||||
|
|
||||||
|
Command exit("exit", &exitExecute);
|
||||||
|
Command cd("cd", &cdExecute);
|
||||||
|
|
||||||
//add builtin commands
|
//add builtin commands
|
||||||
mshConsoleTest.addCmd(help);
|
mshConsoleTest.addCmd(&help);
|
||||||
mshConsoleTest.addCmd(new Command("exit", &exitExecute));
|
mshConsoleTest.addCmd(&cd);
|
||||||
mshConsoleTest.addCmd(new Command("cd", &cdExecute));
|
mshConsoleTest.addCmd(&exit);
|
||||||
mshConsoleTest.launch();
|
mshConsoleTest.launch();
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,11 +60,10 @@ namespace mshconsole {
|
||||||
|
|
||||||
//Run the shell loop.
|
//Run the shell loop.
|
||||||
int exitCode;
|
int exitCode;
|
||||||
|
std::string* line=nullptr;
|
||||||
|
struct Params p;
|
||||||
|
|
||||||
try{
|
try{
|
||||||
std::string* line=nullptr;
|
|
||||||
struct Params p;
|
|
||||||
|
|
||||||
while(1){
|
while(1){
|
||||||
delete line;
|
delete line;
|
||||||
outputStream << ps << " "; //Print the prompt.
|
outputStream << ps << " "; //Print the prompt.
|
||||||
|
@ -91,8 +90,13 @@ namespace mshconsole {
|
||||||
|
|
||||||
//Execute the command.
|
//Execute the command.
|
||||||
executeCmd(p);
|
executeCmd(p);
|
||||||
|
|
||||||
|
//Free p
|
||||||
|
deleteParams(p);
|
||||||
};
|
};
|
||||||
} catch(CommandExecutor::ExitException c) {
|
} catch(CommandExecutor::ExitException c) {
|
||||||
|
delete line;
|
||||||
|
deleteParams(p);
|
||||||
exitCode=c.getCode();
|
exitCode=c.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +124,9 @@ namespace mshconsole {
|
||||||
catch (CommandNotFoundException){}
|
catch (CommandNotFoundException){}
|
||||||
|
|
||||||
//execute bash command or program
|
//execute bash command or program
|
||||||
if((a=execvp(p.argv[0], p.argv)) == -1) {
|
a=execvp(p.argv[0], p.argv);
|
||||||
|
|
||||||
|
if(a == -1) {
|
||||||
outputStream << name << ": execution failed. Errno is set to: "<<strerror(errno)<<"\n";
|
outputStream << name << ": execution failed. Errno is set to: "<<strerror(errno)<<"\n";
|
||||||
std::exit(EXIT_FAILURE);
|
std::exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
@ -181,9 +187,14 @@ namespace mshconsole {
|
||||||
struct sigaction* setHandler(unsigned signal, void (*funcptr)(int, siginfo_t*, void*)){
|
struct sigaction* setHandler(unsigned signal, void (*funcptr)(int, siginfo_t*, void*)){
|
||||||
struct sigaction* before = new struct sigaction();
|
struct sigaction* before = new struct sigaction();
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
|
sigset_t mask;
|
||||||
|
sigemptyset(&mask);
|
||||||
|
sigaddset(&mask, SIGTERM);
|
||||||
|
sa.sa_mask=mask;
|
||||||
sa.sa_sigaction = funcptr;
|
sa.sa_sigaction = funcptr;
|
||||||
sa.sa_flags = 0;
|
sa.sa_flags = SA_RESTART;
|
||||||
sigaction(signal, &sa, before);
|
sigaction(signal, &sa, before);
|
||||||
|
return before;
|
||||||
}
|
}
|
||||||
|
|
||||||
void restoreHandler(unsigned signal, struct sigaction* before){
|
void restoreHandler(unsigned signal, struct sigaction* before){
|
||||||
|
@ -212,6 +223,10 @@ namespace mshconsole {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Shell::deleteParams(struct Params p){
|
||||||
|
freeString(p.argc,p.argv);
|
||||||
|
}
|
||||||
|
|
||||||
bool Shell::SIGINTRaised = false;
|
bool Shell::SIGINTRaised = false;
|
||||||
|
|
||||||
void Shell::addCmd(Command* cmd, bool isthread){
|
void Shell::addCmd(Command* cmd, bool isthread){
|
||||||
|
|
|
@ -71,6 +71,7 @@ namespace mshconsole {
|
||||||
static void SIGINTHandler(int,siginfo_t *info, void *);
|
static void SIGINTHandler(int,siginfo_t *info, void *);
|
||||||
std::string* readLine();
|
std::string* readLine();
|
||||||
struct Params splitLine(const std::string* line);
|
struct Params splitLine(const std::string* line);
|
||||||
|
void deleteParams(struct Params p);
|
||||||
|
|
||||||
class IsUndoingLineException {};
|
class IsUndoingLineException {};
|
||||||
class CommandNotFoundException {};
|
class CommandNotFoundException {};
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace StringToArgcArgv{
|
||||||
{
|
{
|
||||||
std::vector<std::string> args = parse(str);
|
std::vector<std::string> args = parse(str);
|
||||||
|
|
||||||
*argv = (char**)std::malloc((args.size()+1) * sizeof(char*));
|
*argv = new char*[args.size()+1]();
|
||||||
|
|
||||||
int i=0;
|
int i=0;
|
||||||
for(std::vector<std::string>::iterator it = args.begin();
|
for(std::vector<std::string>::iterator it = args.begin();
|
||||||
|
@ -45,7 +45,7 @@ namespace StringToArgcArgv{
|
||||||
++it, ++i)
|
++it, ++i)
|
||||||
{
|
{
|
||||||
std::string arg = *it;
|
std::string arg = *it;
|
||||||
(*argv)[i] = (char*)std::malloc((arg.length()+1) * sizeof(char));
|
(*argv)[i] = new char[arg.length()+1]();
|
||||||
std::strcpy((*argv)[i], arg.c_str());
|
std::strcpy((*argv)[i], arg.c_str());
|
||||||
}
|
}
|
||||||
(*argv)[i]=NULL;
|
(*argv)[i]=NULL;
|
||||||
|
@ -53,6 +53,13 @@ namespace StringToArgcArgv{
|
||||||
*argc = args.size();
|
*argc = args.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void freeString(int& argc, char**& argv){
|
||||||
|
for(int i=0; i<argc; i++){
|
||||||
|
delete[] argv[i];
|
||||||
|
}
|
||||||
|
delete[] argv;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> parse(const std::string& args)
|
std::vector<std::string> parse(const std::string& args)
|
||||||
{
|
{
|
||||||
std::stringstream ain(args); // used to iterate over input string
|
std::stringstream ain(args); // used to iterate over input string
|
||||||
|
|
|
@ -42,5 +42,6 @@ namespace StringToArgcArgv{
|
||||||
bool _isWhitespace(char c);
|
bool _isWhitespace(char c);
|
||||||
std::vector<std::string> parse(const std::string& args);
|
std::vector<std::string> parse(const std::string& args);
|
||||||
void stringToArgcArgv(const std::string& str, int* argc, char*** argv);
|
void stringToArgcArgv(const std::string& str, int* argc, char*** argv);
|
||||||
|
void freeString(int& argc, char**& argv);
|
||||||
}
|
}
|
||||||
#endif //STRINGTOARGCARGV_H
|
#endif //STRINGTOARGCARGV_H
|
||||||
|
|
Loading…
Reference in a new issue