使用execvp子调用转储logcat

时间:2015-07-23 07:44:58

标签: android c exec fork logcat

我想将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还没有终止。 父母正在等待孩子终止,但在这种情况下孩子不是 终止所有和父母被阻止。

Child创建了文件/ data / logcat_dumped并将日志转储给它,但是子节点没有终止。这可能是什么错误? logcat本身不会终止? 任何逻辑错误?

以上程序的输出是

wat for pid 1581
start of exec      

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:1)

更改此

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

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

来自man 3 exec

  

按照惯例,第一个参数应指向与正在执行的文件关联的文件名。

此外,无需将WUNTRACED传递给waitpid()。只需将其称为:

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

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

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

...

另外^ 2在将args传递给execvp()时无需投射execvp(command, args);

这应该做:

$("a").click(function () {
    alert($('#my-contenteditable-div').html());
});