国际惯例, 我们先看一下源码:
1 init_parse_config_file("/init.rc");
在 init 进程的 main() 函数里, 会调用 init_parse_config_file() 方法解析 init.rc 脚本, 注意这里传递的参数是根目录下的 "/init.rc" 文件路径.
init_parse_config_file() 方法定义如下:
- int init_parse_config_file(const char *fn)
- {
- char *data;
- data = read_file(fn, 0); // 读取 / init.rc 文件内容到内存, 并返回起始地址存入 data
- if (!data) return -1;
- parse_config(fn, data); // 解析读入的字符内容
- DUMP();
- return 0;
- }
read_file() 方法的定义非常简单, 作用就是把指定的文件以字符的形式读入到内存中, 并返回起始地址及读入的数据大小.
其源码如下:
- /* reads a file, making sure it is terminated with \n \0 */
- // 该方法接收两个参数:
- // fn: 要读取的文件路径
- // _sz:unsigned int 类型的指针, 用于返回读入的字符个数
- // 该方法返回读取的字符内容的起始地址, 如果读取失败则返回 0
- void *read_file(const char *fn, unsigned *_sz)
- {
- char *data;
- int sz;
- int fd;
- struct stat sb;
- data = 0;
- fd = open(fn, O_RDONLY); // 以只读的方式打开文件
- if(fd < 0) return 0;
- // for security reasons, disallow world-writable
- // or group-writable files
- if (fstat(fd, &sb) < 0) {
- ERROR("fstat failed for'%s'\n", fn);
- goto oops;
- }
- if ((sb.st_mode & (S_IWGRP | S_IWOTH)) != 0) {
- ERROR("skipping insecure file'%s'\n", fn);
- goto oops;
- }
- sz = lseek(fd, 0, SEEK_END); // 获取文件长度, 有多少个字节
- if(sz < 0) goto oops;
- if(lseek(fd, 0, SEEK_SET) != 0) goto oops; // 定位到文件开头
- data = (char*) malloc(sz + 2); // 分配存储空间
- if(data == 0) goto oops;
- if(read(fd, data, sz) != sz) goto oops; // 读取文件内容
- close(fd); // 关闭文件
- data[sz] = '\n'; // 设置结尾字符
- data[sz+1] = 0;
- if(_sz) *_sz = sz;
- return data;
- oops:
- close(fd);
- if(data != 0) free(data);
- return 0;
- }
将文件的内容读入内存后, 接下来就可以进行解析了, 调用 parse_config() 方法来解析 init.rc 的内容.
来源: http://www.bubuko.com/infodetail-3382475.html