Skip to content
Advertisement

C++ Command not recognized after fork() and execl() call (Linux)

I’m trying to create a program that can open a terminal browser and navigate through a website. It works fine up until the child process is called. The following error shows up

“xdotool: Unknown command: search –onlyvisible –name Terminal windowactivate keydown Down”

I’ve tested the command in a separate terminal and it indeed works but it doesn’t get recognized in my code. I get the feeling it might have to do with the fact that execl doesnt return back to main but I’m new to programming so I don’t know for certain.

Heres the code

#include <iostream>
#include <string>
#include <unistd.h>

using namespace std;

int main(int argc, char *argv[]) {

string thread;
cout << "website: ";
cin >> thread;

const char* xdo = "xdotool";
pid_t pid = fork();
string strThread = "" + thread;
string xdoCMD = " search --onlyvisible --name Terminal windowactivate keydown Down";

if (pid < 0) {
cout << "Process failed" << endl;
return 1;
} 
else if (pid == 0) {
execl("/usr/bin/xdotool", "xdotool", xdoCMD.c_str(), (char *) NULL);
}

else {
//  sleep(1);
execl("/usr/bin/elinks", "elinks", strThread.c_str(), (char *) NULL);
}
} 

Advertisement

Answer

execl(3) is calling execve(2) (whose arguments go into the main of the executed program). They return only on failure.

So

execl("/usr/bin/xdotool", "xdotool", xdoCMD.c_str(), (char *) NULL);

is calling the xdotool program with two arguments, xdotool and xdoCMD.c_str() -as a single second argument.

You should split xdoCMD.c_str() into several pieces. Build an appropriate (NULL terminated!) array of char* from it, then call execvp(3) on that.

In effect, you should mimic what the shell does. Perhaps you might even want globbing (but you need to decide what kind of expansions you want; beware perhaps of code injection). See glob(7).

Don’t forget to check against failure (of fork, execvp etc…)

BTW, both the gdb debugger (don’t forget to compile with g++ -Wall -g) and strace(1) are useful to find such a bug.

Advertisement