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?
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
?