static void open_console()
{
int fd;
if ((fd = open(console_name, O_RDWR)) < 0) {
fd = open("/dev/null", O_RDWR);
}
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
close(fd);
}
zap_stdio()比较狠,直接将STDIN,STDOUT,STDERR都干掉了,而open_console()则只是在/dev/console
不存在的情况下才干掉STDIN,STDOUT,STDERR,如果/dev/console存在,则将所有输入输出重定向到它
。
调用哪个取决于needs_console,
needs_console = (svc->flags & SVC_CONSOLE) ? 1 : 0;
而svc->flags关于SVC_CONSOLE的部分来自于system/core/init/parser.c
static void parse_line_service(struct parse_state *state, int nargs, char **args)
{
case K_console:
svc->flags |= SVC_CONSOLE;
break;
}
这也就是说如果init.rc中service部分有请求console,则可以打印到console。
但怎么样才能打印到系统的log中,可以使用logcat来查看呢?这就需要用到logwrapper。
system/core/logwrapper/logwrapper.c中,logwrapper先打开/dev/ptmx,查询到设备名后
fork()一个子进程并将STDOUT,STDERR定向到查询到的设备。
// redirect stdout and stderr
close(parent_ptty);
dup2(child_ptty, 1);
dup2(child_ptty, 2);
close(child_ptty);
然后开始执行要运行的程序
child(argc - 1, &argv[1]);
总结:
系统中的程序中输出log一般是到/dev/log/下的三个设备中,可以用logcat查看。
对于init运行的程序则有两种方法查看到log信息:
1.添加/system/bin/logwrapper,可以用logcat查看,例如
service /system/bin/logwrapper /system/bin/rild
2.添加console,像sh一样直接输出到console
service console /system/bin/sh
console