cstdoutexecvpdup2

problem in writing to terminal after using execvp and dup2 syscalls


Line number #15 { printf("This goes to the terminal\n"); } is not getting printed anywhere not in the terminal nor in the file.

//inputs   argc = 3 :- ./executable_file  output_file  command
    int main(int argc, char **argv)
    {
        if(argc < 3)
        {
            return 0;
        }
        int stdout_copy = dup(1);
        int fd = open(argv[1], O_CREAT | O_RDWR | O_TRUNC, 0644);
        if (fd < 0)
        {
            printf("ERROR\n");
            return 0;
        }
        printf("This goes to the standard output(terminal).\n");
        printf("Now the standard output will go to \"%s\" file  .\n", argv[1]);
        dup2(fd, 1);
        printf("This output goes to \"%s\"\n",argv[1]);
        close(fd);
        execvp(argv[2],argv+2);
        dup2(stdout_copy,1);
        printf("This goes to the terminal\n");
        return 0;
    }

Apologies for the Previous Question : I'm really sorry, it was my mistake in analysing it. And special thanks for all answers and hints.


Solution

  • problem in writing to terminal after using execvp and dup2 syscalls

    Neither:

        execvp(argc[2],argc+2);
        dup2(stdout_copy,1);
        printf("This goes to the terminal\n");
    

    Or:

        dup2(stdout_copy,1);
        execvp(argc[2],argc+2);
        printf("This goes to the terminal\n");
    

    ...will output to stdout if the call to execvp(argc[2],argc+2); succeeds.
    However, both will output to stdout if it fails.
    (Unless command line arguments are incorrect, dup2() likely has nothing to do with failure to output to stdout. See additional content below for how to check this.)

    Read all about it here: execvp.
    In a nutshell, execvp() replaces the current process with a new process. If it is successful the current process is no longer what you are viewing on the terminal. Only when it is not successful will the commands following it be executed.

    The following suggestions are not precisely on-topic, but important nonetheless...

    Change:

    int main(int argv, char **argc)
    

    To:

    int main(int argc, char **argv)  //or  int main(int argc, char *argv[]), either are fine.
    

    This will be the foundation of seeing normal behavior. Anything else is very confusing to future maintainers of your code, and to people trying to understand what you are doing here.
    These names are easily remembered by keeping in mind that argc is used for the count of command line arguments, and argv is the vector that is use to store them.

    Also, your code shows no indications that you are checking/validating these arguments, but given the nature of your program, they should be validated before going on. For example:

    //verify required number of command line arguments was entered
    if(argc <!= 3)//requires at least one additional command line argument
    {
        printf("Usage: prog.exe [path_filename]\nInclude path_filename and try again.\nProgram will exit.");
        return 0;
    }
    //check if file exists before going on
    if( access( argv[1], F_OK ) != -1 ) 
    {
         // file exists
    } else {
         // file doesn't exist
    }
    //do same for argv[2]
    

    (2nd example to check file in Linux environment is from here)

    BTW, Knowing the command line arguments that were passed into the program, would help to provide a more definitive answer here. Their syntax and content, and whether or not the files that they reference exist, determine how the call to execvp will behave.

    Suggestions