使用 execvp child 调用转储 logcat

dumping logcat with execvp child call

我想将 logcat 转储到某个文件,所以在 shell 如果我这样做

logcat -d -f /data/logcat_dumped  

上面的命令会将 logcat 转储到文件并退出,所以我想通过 C 编程实现同样的效果。下面是代码

const char command[] = "logcat";
pid_t pid = fork();
/* handle error case */
if (pid < 0) {
    printf("*** fork: %s\n", strerror(errno));
    return pid;
}
/* handle child case */
if (pid == 0) {
    const char *args[1024] = { "-d", "-f", "/data/logcat_dumped", NULL};
    printf("start of exec\n");
    execvp(command, (char**) args);
    printf("*** exec(%s): %s\n", command, strerror(errno));
    fflush(stdout);
    _exit(-1);
}
else
{
    int status;
    printf("wat for pid %d\n", pid);
    pid_t p = waitpid(pid, &status, WUNTRACED);
    printf("pid %d ret %d\n", pid, p);
    if (p == pid) {
        if (WIFSIGNALED(status)) {
            printf("*** %s: Killed by signal %d\n", command, WTERMSIG(status));
        } else if (WIFEXITED(status) && WEXITSTATUS(status) > 0) {
            printf("*** %s: Exit code %d\n", command, WEXITSTATUS(status));
        }
        return status;
    }

}

这里execvp还没有全部终止。 Parent 正在等待 child 终止,但在这种情况下 child 不是 正在终止,但 parent 已被阻止。

Child 创建了文件 /data/logcat_dumped 并将日志转储到其中,但 child 未终止。这里可能是什么错误? logcat 本身是不是终止了?? 有逻辑错误吗??

以上程序的输出是

wat for pid 1581
start of exec      

不确定这是否是错误的全部,但像这样:

const char *args[1024] = { "-d", "-f", "/data/logcat_dumped", NULL};
printf("start of exec\n");
execvp(command, (char**) args);

您告诉 logcat 它的进程名称是 -d,它的第一个参数是 -f。另外,为什么需要 1024(!) 个指针数组?在这种情况下,当您正确地将进程名称作为第一个条目传递时,5 会执行(argv[0] ... 按照惯例与正在执行的命令相同)。

改变这个

const char *args[1024] = { "-d", "-f", "/data/logcat_dumped", NULL};

成为

const char * args[] = {command, "-d", "-f", "/data/logcat_dumped", NULL};

来自 man 3 exec:

The first argument, by convention, should point to the filename associated with the file being executed.


也没有必要将 WUNTRACED 传递给 waitpid()。就这样称呼它:

pid_t p = waitpid(pid, &status, 0);

添加错误检查始终是一个好主意,因此在调用 waitpid() 之后扩展逻辑,如下所示:

if (p == pid) {
...
}
else if ((pid_t) -1) = p)
{
  perror("waitpid() failed");
}

...

此外^2 在将它们传递给 execvp() 时不需要转换 args

应该这样做:

execvp(command, args);