繁体   English   中英

fork / exec:stderr / stdout丢失

[英]fork/exec: stderr/stdout lost

我写这将启动一个新的进程组,然后派生一个PROGRAMM。

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

int main(int argc, char** argv) {
    if(0 != setpgid(0,0)) {
        fprintf(stderr, "Process group creation failed.");
    }
    pid_t pid = fork();
    if(-1 == pid) {
        // ups, error
        fprintf(stderr, "Fork failed!\n");
        return 1;
    } else if(0==pid) {
        // this is the child process
        char **partial = malloc((argc-1)*sizeof(char*));
        for(int i=1;i<argc;i++) {
            partial[i-1] = argv[i];
        }
        execvp(partial[0], partial);
        exit(127);
    }
    // this is the parent process
    int status;
    waitpid(pid, &status, 0);
    return status;
}

如果我用

./pgroup echo Test

它按预期工作。

如果我用

./pgroup bash -c "echo Test"

没有输出写入我的终端。 这是为什么?

execve调用导致段错误:

==22934== Command: ./testt bash -c echo\ Test
==22934== 
==22935== Syscall param execve(argv) points to unaddressable byte(s)
==22935==    at 0x4EF9537: execve (in /usr/lib64/libc-2.20.so)
==22935==    by 0x4EF9D35: execvpe (in /usr/lib64/libc-2.20.so)
==22935==    by 0x400822: main (testt.c:23)
==22935==  Address 0x51f2058 is 0 bytes after a block of size 24 alloc'd
==22935==    at 0x4C29BCF: malloc (in /usr/lib64/valgrind /vgpreload_memcheck-amd64-linux.so)
==22935==    by 0x4007C5: main (testt.c:18)
==22935== 

特别是,不要弄乱argv [0](您不在这里,只说而已)。 而且-这是关键-您必须将其他args strcpy()放入堆空间,而不仅仅是传递现有的指针。 您没有分配该argv,因此不要期望它在启动例程再次运行时“缠住”等等。最后,您需要将NULL复制到参数列表的和。

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

不要这样混合标题。 sys /标头放在首位。

int main(int argc, char** argv) {
    if(0 != setpgid(0,0)) {
        fprintf(stderr, "Process group creation failed.");
    }

尤达式的比较看起来很糟糕,没有优点。

    pid_t pid = fork();
    if(-1 == pid) {
        // ups, error
        fprintf(stderr, "Fork failed!\n");
        return 1;
    } else if(0==pid) {
        // this is the child process
        char **partial = malloc((argc-1)*sizeof(char*));
        for(int i=1;i<argc;i++) {
            partial[i-1] = argv[i];
        }

这个练习的目的是什么? argv ++怎么样,然后您可以直接在execvp中使用它。 你的循环是残暴的,不必要的。 您malloc argc-1,但循环条件是i <argc,这是不可思议的,这是由i的另一个怪异(不是从0开始)弥补的。错误引发样式。

另外,您没有验证任何参数。

        execvp(partial[0], partial);

如果检查了错误,您将看到失败。 最简单的“首次联系”工具是strace,它将告诉您确切的情况,请参阅:

[pid 15735] execve(“ / usr / bin / bash”,[“ bash”,“ -c”,“ echo test”,0x20fe1],[/ * 58 vars * /])= -1 EFAULT(错误地址)

由此可见,arg数组未正确终止,内核尝试在某些垃圾中进行复制。

因此,您的“回声测试”示例纯属偶然,因为它恰好在其中为零。

如果您在malloc中启用了调试,则在这种情况下也会失败。

        exit(127);

那不是你如何退出一个没有被执行的孩子。 参见_Exit。

    }
    // this is the parent process
    int status;
    waitpid(pid, &status, 0);
    return status;

此值不适合撤消。 请参见waitpid联机帮助页中的相关宏。 壳支撑的值从0到255这样的回报32512它是由256整除,因此最终被0。

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM