如果使用execl()运行binls -R,如何获得它的返回值?

问题描述 投票:0回答:1

我有一个Uni的任务,用Linux C语言。程序必须调用一个子进程,这个子进程必须执行 /bin/ls -R 命令,然后在父进程中写出返回值,不能是0,到目前为止,我只能使用 system() 呼叫,但我不能用这个。的 wait(&value) 线与 system() 函数,但不是用 execl. 目前我想出的代码。

int main(){
    int value=0;
    if(fork() == 0){
        printf("Running command, please wait..\n");
        sleep(2);
        char *path = "/bin/ls";
        char *arg1 = "-R";
        execl(path, arg1, NULL);
        exit(1);
    }

    wait(&value); 
    printf("\nProcessing return value, please wait..\n");
    sleep(2);
    printf("\nThe return value of the child: %d \n", value); 
}
c linux parent-child
1个回答
2
投票

如果使用execl()运行binls -R命令,如何获得它的返回值?

如果你 wait() 那么你 获取 /bin/ls -R.

不可能是0

不知道你说的是什么意思,但退出状态为... ... 0 意味着该进程正确退出。不同于 0 意味着发生了错误,所以你通常希望事情以 0而不是其他东西。

exec*() 函数系列在执行成功后不返回。请阅读手册页面 来了解更多。

如果你想让孩子失败,那么就传一个无效的路径到 execl 使其失败或只是 return 1 直接。为了使 ls -R 异曲同工 0 你可能想传递第三个参数给 execl() 指向一个您无法访问的路径,比如说 /root.


我也不完全确定你的代码有什么问题,因为它在我的机器上编译和工作正常。不过这里有一些经验法则,既可以发现问题,又可以避免问题的发生。

  1. 一定要阅读手册(在这种情况下 man 2 wait):

    If  wstatus  is  not NULL, wait() and waitpid() store status information in the int to which it points.  This
    integer can be inspected with the following macros (which take the integer  itself  as  an  argument,  not  a
    pointer to it, as is done in wait() and waitpid()!):
    
    WIFEXITED(wstatus)
          returns  true if the child terminated normally, that is, by calling exit(3) or _exit(2), or by return‐
          ing from main().
    
    WEXITSTATUS(wstatus)
          returns the exit status of the child.  This consists of the least significant 8  bits  of  the  status
          argument  that  the  child  specified in a call to exit(3) or _exit(2) or as the argument for a return
          statement in main().  This macro should be employed only if WIFEXITED returned true.
    
  2. 总是检查可能失败的函数是否有错误。提示:基本上99%的syscall都可能失败。forkwait 是其中的一些。

    pid_t child_pid = fork();
    if (child_pid == -1) {
        perror("fork() failed");
        return 1;
    }
    
    // ...
    
    pid_t res = wait(&child_status);
    if (res != child_pid) {
        perror("wait() failed");
        return 1;
    }
    
  3. 总是编译启用警告。gcc -Wall -Wextra -pedantic.

应用上述规则在大多数情况下,你只需要找出问题所在。下面是应用这些规则后的程序工作版本。

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

int main(void) {
    pid_t child_pid, res;
    int child_status;

    child_pid = fork();
    if (child_pid == -1) {
        perror("fork() failed");
        return 1;
    }

    if(child_pid == 0) {
        sleep(123);
        execl("/bin/ls", "-R", NULL);
        perror("execl() failed");
        exit(1);
    }

    res = wait(&child_status);
    if (res != child_pid) {
        perror("wait() failed");
        return 1;
    }

    if (WIFEXITED(child_status))
        printf("Child exited with status %d.\n", WEXITSTATUS(child_status));
    else if (WIFSIGNALED(child_status))
        printf("Child killed by signal %d.\n", WTERMSIG(child_status));
    else {
        puts("This should never happen! Something's really wrong.");
        return 1;
    }

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.