Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Executing shell commands in c++ with exec

I've been given the assignment to write a small shell program in C++. It's supposed to take the same commands as a regular bash shell (e.g.: mv, cmp, etc.) and then use fork() and exec() to call the bash version of the function.

I've tried a bunch of ways to call the functions, but I keep running into this issue: when the file is in the same directory as the executable it works (e.g.: "tail test.txt"), but when the file is in a different directory it does not (e.g.: "tail ~/Documents/test.txt") and it tells me that the file doesn't exist. The exact wording is:

tail: cannot open '~/Documents/test.txt' for reading: No such file or directory

but the file does exist, and the same command works in the regular bash shell.

Now I'm really lost on this, it's supposed to work for files in any directory, and I can't figure out what I'm doing wrong here.

This is the relevant code (pretty much identical for all commands):

pid_t pid = fork();
if(pid > 0)
{
   wait(NULL);
}
else if(pid == 0)
{
    execl("/bin/mv","mv", arg1.c_str(), arg2.c_str(), NULL);
    exit(1);
}

I tried using different versions of exec, but I ran into issues with the commands that require a char *const[] as argument, since the file path is a variable it wouldn't accept it.

char *const args[] = {"/usr/bin/tail", arg1.c_str(), "-n 5", NULL}; // error here
pid_t pid = fork();
if(pid > 0)
{
    wait(NULL);
}
else if(pid == 0)
{
    execv("/usr/bin/tail", args);
    exit(1);
}

The other versions I've (unsuccessfully) tried are:

char *env[] = {"PATH=~/"};
execle("/usr/bin/tail", "tail", arg1.c_str(), "-n 5", NULL, env);
execlp("/usr/bin/tail", "tail", arg1.c_str(), "-n 5", NULL);

Any help is very much appreciated!

like image 218
nick Avatar asked Jul 01 '26 07:07

nick


1 Answers

~ is a special character interpreted by the shell, not the filesystem. Since you are pretending to be a shell, you need to implement handling for ~ if you want it to work.

For inspiration, you can see how Python implements it (as the function os.path.expanduser()) here: https://github.com/python/cpython/search?utf8=%E2%9C%93&q=%22def+expanduser%22&type=

If you don't want to implement this, simply pass /home/yourusername instead of ~ to your program.

Finally, a note: PATH is an environment variable that specifies where to find programs, not files in general. That's why it wasn't useful in your trials.

like image 174
John Zwinck Avatar answered Jul 03 '26 21:07

John Zwinck



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!