![](/img/trans.png)
[英]Reading stdout/stderr from an exec()'ed process in a daemon
[英]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.