执行 fork 调用会为 Linux 提供退出状态 0x3

问题描述 投票:0回答:1
  • 操作系统:Windows 11

  • Cp:GCC 11.4.0

  • 硬件:英特尔

我有一个从 shell 程序中提取的示例。我正在尝试执行多个由 & '分隔'的程序。给定一个固定的字符串数组,这些字符串是有效的 bash,命令参数由“&”分隔,我应该能够并行分叉和执行所有单独的程序调用。不幸的是,我在分叉时遇到退出状态 0x3(无法打开指定的路径)。我不确定这是从哪里来的,也不知道为什么。

下面是我的原始程序的简化版本。首先,构建程序数组,然后将其传递给“execute_programs”函数,该函数将分叉并执行每个新的有效调用。对“execv”的调用可以忽略,但我保留它是为了显示完整的图片。在此示例中,仅发生一个分叉。我收到输出,

PID -1 的子进程退出,状态为 0x3。

我不明白为什么会发生这种情况。可能还有其他错误,但这个结果对我来说完全出乎意料且难以捉摸。我希望得到一些帮助。

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

int execute_programs(int argc, char *argv[])
{
    int n = 0;
    int cnt = 0;
    int current_cnt = 0;

    while (argv[cnt] != NULL && cnt < argc)
    {
        if (strcmp(argv[cnt], "&") == 0)
        {
            // Block the array.
            argv[cnt] = NULL;

            // Update variables.
            n++;             // Number of programs grows.
            current_cnt = 0; // Number of current arguments goes back to zero.

            if (current_cnt > 0) // There is an adequate number of child processes.
            {
                // Start child process.
                pid_t rc;
                if ((rc = fork()) < 0)
                {
                    // There was an error.
                    abort();
                }
                else if (rc == 0)
                {
                    // Run the i'th process.
                    // printf("%d\n", execv(argv[cnt - current_cnt], &argv[cnt]));
                    exit(0);
                }
            }
        }

        current_cnt++; // Increment number of current arguments.
        cnt++;         // Increment count;
    }

    /* Wait for children to exit. */
    int status;
    pid_t pid;
    while (n > 0)
    {
        pid = wait(&status);
        printf("Child with PID %ld exited with status 0x%x.\n", (long)pid, status);
        --n;
    }

    // return;
    return 0;
}

int main(int argc, char *argv[])
{
    char *programs[5];
    programs[0] = strdup("echo");
    programs[1] = strdup("\"ah\"");
    programs[2] = strdup("&");
    programs[3] = strdup("ls");
    programs[4] = NULL;

    execute_programs(5, programs);
    return 0;
}

编辑:“execv”调用被注释掉,因为我可能没有正确使用它。尽管如此,如果没有它,错误就会发生。给出了相同的错误消息。

c fork system-calls error-code
1个回答
0
投票

这篇文章让我想起了几年前我在

getopt()
函数中遇到的一个问题,该函数需要
argc
argv
就像
execv()
一样。我得出的结论是每个参数字符串应该在连续的字符数组中,但我找不到官方文档这么说。

int main(int argc, char *argv[]) {
  char cmd_buffer[256];
  snprintf(cmd_buffer, sizeof(cmd_buffer),
           R"(echo\0"ah"&\0ls)");  // echo "ah" & ls -> continuous string
                                   //     0    0 0   -> null-terminate
                                   // 0123456789abcd -> index

  char *programs[5];
  programs[0] = &cmd_buffer[0];
  programs[1] = &cmd_buffer[5];
  programs[2] = &cmd_buffer[9];
  programs[3] = &cmd_buffer[11];
  programs[4] = NULL;

  execute_programs(5, programs);
  return 0;
}

我在 WSL 上测试了上面的代码,它没有打印任何错误消息,而原始代码打印“Child with PID -1 exited with status 0x3”;

您需要做的是在单个 char 数组中构建一个以 null 结尾的参数,并将 argv 设置为指向每个参数的开头。

© www.soinside.com 2019 - 2024. All rights reserved.