I've been implementing a small program that executes a given command using execvp(). It works fine when not using redirection, but when I run a command such as:
cat file1.txt > redirected.txt
cat outputs the following error messages and fails:
cat: >: No such file or directory
cat: redirected.txt: No such file or directory
I've done some digging around and I'm starting to think that perhaps execvp() isn't allowed to do redirection because it doesn't run in the shell. Does that mean that I would have to manually pick out when redirection occurs and use pipes in my fork/exec code to get around this restriction? Is there a better way than to use execvp()?
Thanks!
Your "small program that executes a given command" is essentially a shell. Since you are writing a shell, it is your job to implement redirections with whatever syntax you desire. The >
redirection operator is not a feature of the kernel, it is a shell feature.
To implement sh
-style redirection, you must parse the command, locate the redirection operators, open the files and assign them to input/output descriptors. This must be done before calling execvp
. Look up the dup2
system call.
You can use system() if you really want to use that sort of syntax. As you noted, redirection and wildcard expansion and a whole bunch of other things are handled by the shell on Unix-like systems.
The way to do it with fork looks something like this:
int kidpid;
int fd = open("redirected.txt", O_WRONLY|O_TRUNC|O_CREAT, 0644);
if (fd < 0) { perror("open"); abort(); }
switch (kidpid = fork()) {
case -1: perror("fork"); abort();
case 0:
if (dup2(fd, 1) < 0) { perror("dup2"); abort(); }
close(fd);
execvp(cmd, args); perror("execvp"); abort();
default:
close(fd);
/* do whatever the parent wants to do. */
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With