Android培训班(30)

<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->

init.rc文件里第一个初始化的服务是sh服务,如下:

## Daemon processes to be run by init.

##

service console /system/bin/sh

console

 

sh服务是控制台服务,其实它是从NetBSD移植过来的,因此它的命令也是比较有限的,不过作为嵌入式系统,使用shell的机会不多。

sh服务的代码在目录:Android-2.0/system/core/sh

sh服务使用flex工具生成词法分析代码,使用bison生成语法分析代码。

 

下面来分析这个服务主要代码,先从main函数开始,如下:

int

main(int argc, char **argv)

{

struct jmploc jmploc;

struct stackmark smark;

volatile int state;

char *shinit;

 

下面这行代码,就是我为了加入调试使用的。

/* caijs add debug */

out2str("caijs add debug/n");

 

#if PROFILE

monitor(4, etext, profile_buf, sizeof profile_buf, 50);

#endif

state = 0;

 

下面这段代码设置执行命令异常的处理。

if (setjmp(jmploc.loc)) {

/*

* When a shell procedure is executed, we raise the

* exception EXSHELLPROC to clean up before executing

* the shell procedure.

*/

switch (exception) {

case EXSHELLPROC:

rootpid = getpid();

rootshell = 1;

minusc = NULL;

state = 3;

break;

 

case EXEXEC:

exitstatus = exerrno;

break;

 

case EXERROR:

exitstatus = 2;

break;

 

default:

break;

}

 

if (exception != EXSHELLPROC) {

if (state == 0 || iflag == 0 || ! rootshell)

exitshell(exitstatus);

}

reset();

if (exception == EXINT

#if ATTY

&& (! attyset() || equal(termval(), "emacs"))

#endif

) {

out2c('/n');

flushout(&errout);

}

popstackmark(&smark);

FORCEINTON; /* enable interrupts */

if (state == 1)

goto state1;

else if (state == 2)

goto state2;

else if (state == 3)

goto state3;

else

goto state4;

}

handler = &jmploc;

#ifdef DEBUG

#if DEBUG == 2

debug = 1;

#endif

opentrace();

trputs("Shell args: "); trargs(argv);

#endif

 

 

rootpid = getpid();

这行代码通过调用函数getpid 获取进程标识。

 

rootshell = 1;

init();

初始化内部支持的命令。

 

setstackmark(&smark);

 

 

procargs(argc, argv);

这行代码根据命令行进行处理。

 

 

下面代码读取配置参数。

if (argv[0] && argv[0][0] == '-') {

state = 1;

read_profile("/etc/profile");

state1:

state = 2;

read_profile(".profile");

}

state2:

state = 3;

if (getuid() == geteuid() && getgid() == getegid()) {

if ((shinit = lookupvar("ENV")) != NULL && *shinit != '/0') {

state = 3;

read_profile(shinit);

}

}

state3:

state = 4;

if (sflag == 0 || minusc) {

static int sigs[] = {

SIGINT, SIGQUIT, SIGHUP,

#ifdef SIGTSTP

SIGTSTP,

#endif

SIGPIPE

};

#define SIGSSIZE (sizeof(sigs)/sizeof(sigs[0]))

int i;

 

for (i = 0; i < SIGSSIZE; i++)

setsignal(sigs[i], 0);

}

 

if (minusc)

evalstring(minusc, 0);

 

 

下面的代码调用函数cmdloop 来进入shell的命令处理。

if (sflag || minusc == NULL) {

state4: /* XXX ??? - why isn't this before the "if" statement */

cmdloop(1);

}

#if PROFILE

monitor(0);

#endif

 

最后退出shell的执行。

exitshell(exitstatus);

/* NOTREACHED */

}

posted @ 2011-01-02 12:04  ajuanabc  阅读(109)  评论(0编辑  收藏  举报