Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirection inside call to execvp() not working

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!

like image 598
Greg S. Avatar asked Dec 09 '12 03:12

Greg S.


2 Answers

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.

like image 106
user4815162342 Avatar answered Sep 28 '22 00:09

user4815162342


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. */
}
like image 26
tmyklebu Avatar answered Sep 28 '22 01:09

tmyklebu