Question

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?

Was it helpful?

Solution

There are two separate things going on.

  1. 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.

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top