Skip to content
Advertisement

no such file or directory after redirection – simple command line program

Im programming a shell. This is a small piece of it that handles redirects. I only included the snippet that is causing the error. This portion of the program is supposed to take a command/argument line and execute the line accordingly. The wc < junk > junk2 is an example of a command line input and for some reason when i execute the line its producing that error junk: >: open: No such file or directory. The rest of the program functions fine but its breaking here.

: wc < junk > junk2

junk: >: open: No such file or directory

   1       4      31 junk2
   1       4      31 total

I briefly had it working as intended but for some reason I must have lost a piece of the puzzle because it’s broken once again.

Ive looked at my array values and they are as expected. For some clarification I’m using a copy of the arguments array so the original is unchanged by setting the argument copy value to NULL. Im setting the argument copy value to null so the loop doesn’t repeatedly use a redirection.

If you have any advise or see the problem that I apparently can’t it would be appreciated.

    while (arguments[i] != NULL)
                        {


                            if ((strcmp(argumentsCopy[i], "<") == 0))
                            {
                                if ((access(argumentsCopy[i + 1], R_OK) == -1))
                                {
                                    printf("Cannot open %s for inputn", argumentsCopy[i + 1]);
                                    fflush(stdout);
                                    redirect = 1;
                                }
                                else
                                {

                                    int fd = open(argumentsCopy[i + 1], O_RDONLY);
                                    dup2(fd, STDIN_FILENO);
                                    close(fd);
                                    argumentsCopy[i] = NULL;
                                    redirect = 1;
                                    execvp(command, &arguments[i + 1]);
                                }

                            }
                            if ((strcmp(argumentsCopy[i], ">") == 0))
                            {


                                int fd = open(argumentsCopy[ i + 1], O_RDWR);
                                dup2(fd, STDOUT_FILENO);
                                close(fd);
                                argumentsCopy[i] = NULL;
                                redirect = 1;  // avoid repeat use of redirection symbol in arguments array
                                execvp(command, &arguments[i + 1]);
                            }

                            i++;
                        }
                        if (redirect == 0)
                        {

                            execvp(command, execArgs);  //execArgs is entire command w/ arguments
                        }
                        exit 0; //default if error occurred. 

Advertisement

Answer

First, note that you’re not correctly using the execvp function. Once a call to execvp (or any call in the exec family) succeeds, the execution of the current program terminates and is replaced by the program you are execing. Thus, control flow should never proceed past an execvp call unless that call failed. Therefore, you cannot call execvp until you are sure both the stdin and stdout file descriptors have been properly redirected (in the case that you have both input and output redirection). From your code sample, it appears you call execvp once either one is detected, which means your shell can only redirect input or output, not both.

However, that is not the source of the error you’re receiving. Consider the input wc < junk > junk2. Based on the information you provided, the command and arguments array will be populated as follows:

command = "wc"
arguments[0] = ">"
arguments[1] = "junk"
arguments[2] = "<"
arguments[3] = "junk2"
arguments[4] = NULL

When i = 0, the first if-statement will be taken, opening the file descriptor and performing execvp with the parameters command and &arguments[i+1]. These correspond to the file to be executed and the argv array passed to that function’s main method respectively. In this case, the command is wc and the args are { "junk", "<", "junk2", NULL } (as this is the value of the null terminated array beginning at &arguments[i+1]). On Unix systems, it is conventional for the first argument (argv[0]) to be the name of the current program. Thus the actual command line arguments begin at argv[1] (see Program Arguments for documentation). From wc‘s perspective, the command line arguments it should process are { "<", "junk2", NULL } after it processes what it believes to be its program name, argv[0], or junk.

wc takes as arguments the list of files it will process. In this case, it believes that list to be < and junk2, as "<" is an operator recognized by bash and other shells, not the executing program. Thus, wc (which believes its name is junk because of argv[0]) attempts to open < as an input file and fails, printing the message:

junk: >: open: No such file or directory
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement