声明char数组会导致execv()无法正常工作 [英] Declaring char array causes execv() to not work

查看:114
本文介绍了声明char数组会导致execv()无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了以下代码,以便在c unix中使用管道:

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是我之前编译的文件.它只是计算发送给它的3个参数的平均值.

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

输出为4,但是当我尝试从流中实际读取时,我为char buffer[10]添加了一个声明,代码停止工作.也就是说,没有提供输出.我试图对其进行重命名,以将脱节处理移至if语句的开头.但没有任何效果.

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?

推荐答案

exec*()调用一起使用的参数数组必须以(char*)NULL终止.

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

此行

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

应该是

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

由于它不在您的代码中,因此exec()可能会丢失搜索内容.

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

不幸的是,由于您的代码版本未声明a并且execv()在指向"5"的指针之后立即发现了NULL,因此堆栈可能已经干净(填充了0).在堆栈上创建a之后,更改了堆栈的内容,这使得execv()在搜索NULL时迷路了.

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.

另外值得一提的是,OP的代码在大多数相关的系统调用中都错过了错误检查.

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

这样做以及对错误原因的详细检查(可能通过使用perror()的调用)可能通过提供相关信息来解决此问题.

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.

特别是将其放置在调用execv()之后,很快就会发现问题所在:

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");

这篇关于声明char数组会导致execv()无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆