Declaring char array causes execv() to not work

╄→尐↘猪︶ㄣ 提交于 2020-01-22 02:41:20

问题


I wrote the following code in order to use pipes in c unix:

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>

int main ()
{
    int fds[2];
    pid_t pid;
    /* Create a pipe. File descriptors for the two ends of the pipe are
    placed in fds. */
    pipe (fds);
    /* Fork a child process. */
    pid = fork ();
    if (pid == (pid_t) 0) {
        //char abc[10]; - **Uncommenting this cause the program not to work.**
        /* This is the child process. Close our copy of the write end of
        the file descriptor. */
        close (fds[1]);
        // Read params
        FILE * stream;
        stream = fdopen (fds[0], "r");
        char* args[4]={"avg3.out","4","3","5"};

        /* Replace the child process with the “avg3” program. */
        execv("avg3.out", args);
    } else {
        /* This is the parent process. */
        FILE* stream;
        /* Close our copy of the read end of the file descriptor. */
        close (fds[0]);
        /* Convert the write file descriptor to a FILE object, and write
        to it. */
        dup2(fds[0], STDOUT_FILENO);
        stream = fdopen (fds[1], "w");
        fprintf (stream, "5 4 3");
        fflush (stream);
        close (fds[1]);
        /* Wait for the child process to finish. */
        waitpid (pid, NULL, 0);
    }
    return 0;
}

avg3.out is a file I compiled before. It simply calculate the average of the 3 params sent to it.

The output was 4, but when I tried to actually read from the stream, I added a declaration for char buffer[10] The code stopped working. That is, no output provided. I tried to rename it, to move the decleration to the start of the if statement. but nothing worked.

So, why does the program stop working when adding just an array declaration?


回答1:


The parameter-array to go with calls to exec*() needs to be (char*)NULL-terminated.

This line

char* args[4]={"avg3.out","4","3","5"};

should be

char* args[] = {"avg3.out", "4", "3", "5", NULL};

As it isn't in your code, exec() might get lost searching for it.

By bad luck the stack might have been clean (0 filled) for the version of your code not declaring a and execv() found a NULL right after the pointer pointing to "5". Having a created on the stack then changed the content of the stack which made execv() getting lost searching for the NULL.


Additionally its worth mentioning that the OP's code misses error checking on most of the relevant system call.

Having done so together with a detailed examation of the errors' causes, probably by using calls to perror() might have led to solving this issue by providing relevant information.

In particular placing it after the call to execv() it soon would have been obvious what's wrong:

 execv("avg3.out", args);
 perror("execv() failed");


来源:https://stackoverflow.com/questions/20220825/declaring-char-array-causes-execv-to-not-work

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!