C - 输出中的垃圾字符

时间:2015-04-16 16:07:12

标签: c character fork execl

让我们说,我有两个程序--input.c& output.c 我想要做的就是使用execl()函数将一些“半金字塔”格式的有效载荷/字符发送到另一个。

Input.c中

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

#define SIZE 1024

int length;

int main(int argc, char *argv[])
{
    pid_t pid;
    char *target;
    //char payload[length+1];
    char payload[SIZE + 1];
    int status;
    int i = 0;

    if(argc < 2)
    {
        printf("Usage %s <length> <target>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    length = atoi(argv[1]);
    target = argv[2];

    while(i < length)
    {
        pid = fork();

        if(pid != 0)
        {
            waitpid(-1, &status, 0);
            //exit(0);
        }

        if(pid == 0)
        {
            payload[i] = 'A';
            payload[i + 1] = '\0';
            execl(target, target, payload, NULL);
            //printf("%s\n", payload);
        }
        ++i;
    }
    return 0;
}

评论的段落仅用于调试目的。因为您可以看到(尝试时),当您想要打印时,一切正常。

output.c (或者,如果您想要' target.c ')

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char buffer[30];
    strncpy(buffer, argv[1], sizeof(buffer));
    printf("Output: %s\n", buffer);

    return 0;
}

当我编译input.c时:

gcc input.c -o input

&安培; output.c:

gcc output.c -o output

确定。现在,一切都准备好了。比方说,我想发送一个有效载荷 - 长度为6

./input 6 ./output

但我输出的只是这个(或者只是用另一个junks字符):

Output: A
Output: 0A
Output: 0,A
Output: 0,�A
Output: 0,�8A
Output: 0,�8�A

我尝试了很多东西,但是所有这些都失败了,输出仍然是相同的,如上所示。

如果有人能帮助我并且可能告诉我问题在哪里,我将非常感激。使用fork()和execl()函数可能有问题吗?

2 个答案:

答案 0 :(得分:5)

知道了,你不应该更新 子代码...

这是一个修复程序(现在无法测试):

payload

[删除不相关的句子]

编辑(其他说明): while(i < length) { pid = fork(); payload[i] = 'A'; payload[i + 1] = '\0'; if(pid != 0) { waitpid(-1, &status, 0); //exit(0); } if(pid == 0) { execl(target, target, payload, NULL); //printf("%s\n", payload); } ++i; } 更新必须位于 父代码和子代码中。如果您不明白原因,我可以添加更多解释。

EDIT2(根据要求)。您需要下一个分叉子进程的更新有效内容。在您的代码中,所有子代码都被payload替换为execl()代码。因此target仅由第一个父进程(根进程)执行

您必须通过第一个父级更新有效负载,并使所有子级都可以访问它。将它放入此块也不起作用:

fork()

因此,您必须在父母和孩子都可以访问的位置更新它:在// block only executed by the first parent. if(pid != 0) { waitpid(-1, &status, 0); } 之后,在fork()阻止之前。

在您的代码中,您在公共块中递增if(pid == 0),但父级的i永远不会更新。因此,在子版块中,在payload之前,您在未初始化 C字符串的末尾添加“execl()

答案 1 :(得分:2)

当你的程序分叉时,它会创建一个新进程。这个新进程在if(pid == 0)之后改变payload,并运行exec(即执行output,然后死亡。即,你的有效负载变化留在孩子身上,并不影响父进程。只有++i,这就是您查看统一数据的原因。

在fork之前移动有效负载更改(或者至少在仅限子节点之外),因此它也在父级中移动。