博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android init.rc文件解析过程详解(三)
阅读量:4047 次
发布时间:2019-05-25

本文共 2747 字,大约阅读时间需要 9 分钟。

本文转载自


 

                                                                                                                            Android init.rc文件解析过程详解(三)

三、相关结构体

 

     1listnode

listnode结构体用于建立双向链表,这种结构广泛用于kernel代码中, android源代码中定义了listnode结构体以及相关操作双向链表的方法,与kernel中的定义类似。

 

这个实现的核心思想是:在用户自定义的结构体xx中定义一个listnode类型的成员,

这个listnode类型成员的作用就是能将xx类型的变量组成一个双向链表。下面我们来看一下是listnode是怎么做到的。

 

//listnode类型里面只有两个指针prev,next

struct listnode

{

    struct listnode *next;

    struct listnode *prev;

};

 

//将链表中的一个node转换成自定义结构体中的一个对象

#define node_to_item(node, container, member) \

    (container *) (((char*) (node)) - offsetof(container, member))

 

//初始化一个链表

void list_init(struct listnode *node)

{

    node->next = node;

    node->prev = node;

}

 

//将一个节点到链表

void list_add_tail(struct listnode *head, struct listnode *item)

{

    item->next = head;

    item->prev = head->prev;

    head->prev->next = item;

    head->prev = item;

}

 

//删除一个节点

void list_remove(struct listnode *item)

{

    item->next->prev = item->prev;

    item->prev->next = item->next;

}

 

理解node_to_item宏是理解listnode用法的关键,这个宏的作用是将一个listnode指针转换成了一个指定类型(自定义)的指针,这个宏先使用offsetof函数获取到指定结构体中指定成员变量的地址偏移量,然后通过指针运算获得listnode指针变量所在结构体变量的指针。

这种实现与我们课堂上所学的链表实现方法不太一样,教科书上的实现是在listnode中存储了自定义的数据,而这个实现是在自定义的数据当中存储listnode指针。

 

 

 

2action结构体

     前面已经讲过on类型的section解析之后会生成一个双向链表action_list, 这个action_list每个node表示就是action结构体的对象,也就是说一个on类型的section都会生成一个action结构体的对象。

    

action结构体定义如下:

 

struct action {

        /* node in list of all actions */

    struct listnode alist;

        /* node in the queue of pending actions */

    struct listnode qlist;

        /* node in list of actions for a trigger */

    struct listnode tlist;

 

    unsigned hash;

    const char *name;

   

    struct listnode commands;        //节点为command结构体的双向链表

    struct command *current;

};

 

     action结构体除了用在on类型的section, 也用在service类型的section,下面介绍service结构体时会说明。

 

3command结构体

 

Command结构体定义如下:

struct command

{

        /* list of commands in an action */

    struct listnode clist;

 

    int (*func)(int nargs, char **args);

    int nargs;

    char *args[1];

};

 

command结构体比较简单, 用于标识一个命令,包含双向链表指针、对应的执行函数、参数个数以及命令关键字。

 

4service结构体

 

 

struct service {

        /* list of all services */

    struct listnode slist;                  //将结构体链接成service_list

 

    const char *name;

    const char *classname;

 

    unsigned flags;

    pid_t pid;

    time_t time_started;    /* time of last start */

    time_t time_crashed;    /* first crash within inspection window */

    int nr_crashed;         /* number of times crashed within window */

   

    uid_t uid;

    gid_t gid;

    gid_t supp_gids[NR_SVC_SUPP_GIDS];

    size_t nr_supp_gids;

 

#ifdef HAVE_SELINUX

    char *seclabel;

#endif

 

    struct socketinfo *sockets;

    struct svcenvinfo *envvars;

 

    struct action onrestart;  /* Actions to execute on restart. */

   

    /* keycodes for triggering this service via /dev/keychord */

    int *keycodes;

    int nkeycodes;

    int keychord_id;

 

    int ioprio_class;

    int ioprio_pri;

 

    int nargs;

    /* "MUST BE AT THE END OF THE STRUCT" */

    char *args[1];

};

 

service结构体存储了service的相关信息, 包括进程号、启动时间、名字等, 字段onrestart

就用到了action结构体, onrestart这个option后面通常跟着一个命令,所以也用action结构体来表示。

 

你可能感兴趣的文章
[关注大学生]李开复给中国计算机系大学生的7点建议
查看>>
[关注大学生]大学毕业生择业:是当"鸡头"还是"凤尾"?
查看>>
[茶余饭后]10大毕业生必听得歌曲
查看>>
gdb调试命令的三种调试方式和简单命令介绍
查看>>
C++程序员的几种境界
查看>>
VC++ MFC SQL ADO数据库访问技术使用的基本步骤及方法
查看>>
VUE-Vue.js之$refs,父组件访问、修改子组件中 的数据
查看>>
Vue-子组件改变父级组件的信息
查看>>
Python自动化之pytest常用插件
查看>>
Python自动化之pytest框架使用详解
查看>>
【正则表达式】以个人的理解帮助大家认识正则表达式
查看>>
性能调优之iostat命令详解
查看>>
性能调优之iftop命令详解
查看>>
非关系型数据库(nosql)介绍
查看>>
移动端自动化测试-Windows-Android-Appium环境搭建
查看>>
Xpath使用方法
查看>>
移动端自动化测试-Mac-IOS-Appium环境搭建
查看>>
Selenium之前世今生
查看>>
Selenium-WebDriverApi接口详解
查看>>
Selenium-ActionChains Api接口详解
查看>>