Reputation: 215
Been working on a shell project. I have set up the I/O redirection, but I'm clearly missing something because when test it with a line like: "ls -al > outfile" it creates the outfile on my desktop, but leaves it empty and the program returns the following error:
ls: >: No such file or directory
Error: Failure to wait for child.
: Interrupted system call
Here is my code:
pid_t child = fork();
if (child < 0)
{
perror( "Error: Fork failure.\n" );
exit(1);
}
else if (child == 0)
{
//If < file (read)
if (inpt)
{
int fd_in = open(argumnts[index+1], O_RDONLY, 0);
dup2(fd_in, STDIN_FILENO);
close(fd_in);
inpt = 0;
}
//If > file (create or truncate)
if (outpt)
{
int fd_out_A = open(argumnts[index+1], O_CREAT | O_TRUNC, 0666);
dup2(fd_out_A, STDOUT_FILENO);
close(fd_out_A);
outpt = 0;
}
execvp (argumnts[0], argumnts);
perror(command);
exit(0);
}
else
{
inpt = 0;
outpt = 0;
outptApp = 0;
if ( waitpid(child, 0, WUNTRACED) < 0 )
perror( "Error: Failure to wait for child.\n" );
}
}
} //End While(1) loop
The comparator function just checks to see if the command argument entered was "<", ">", or ">>", then returns the index where it is contained.
Not sure what I'm missing here, but it returs the errors mentioned before. Any idea?
Upvotes: 0
Views: 1860
Reputation: 17041
There are two separate things going on.
ls: >: No such file or directory
can be fixed by setting argumnts[index]=NULL
before calling execvp
. ls
is seeing the > outputfile
as additional filenames it should list. The NULL
to terminate the argument list will take care of that.
Error: Failure to wait for child. : Interrupted system call
: something is happening while waiting. Interrupted system calls (EINTR
) are often not a problem and can be restarted with no ill effects. I found the following suggestion here to replace the single call to waitpid
:
"A typical code sequence would be:
while((pid = waitpid(,,)) == -1) { switch (errno) { case EINTR: continue; default: printf(stderr, ...) break; }} ... rest of normal waitpid-hanling goes here ...
Also, you'll probably have to install a signalhandler for at least SIGCHLD . "
Also, I note you have not redirected stderr, which may cause interactions between parent and child. One other question - did you hit control-C? If so, see here.
Also, WUNTRACED
may or may not be something you want to specify, depending on whether you're handling terminal signals. See the manpage for waitpid(2), e.g., here. Perhaps 0
, or WEXITED
?
Upvotes: 3