深入剖析Android中init进程实现的C语言源码

2020-01-06 13:38:30丽君

只讲原理是不行的,我们直接来看一下__lib_prenit函数代码的相关实现:

 

 
  1. void __attribute__((constructor)) __libc_prenit(void);  void __libc_prenit(void) 
  2. {  // ... 
  3. __libc_init_common(elfdata); // 调用这个函数  // ... 
  4. }   
  5.   __libc_init_common函数为: 
  6.   void __libc_init_common(uintptr_t *elfdata) 
  7. {  // ... 
  8. __system_properties_init(); // 初始化客户端的属性存储区域  } 
  9.    
  10. __system_properties_init函数有回到了我们熟悉的/bionic/libc/bionic/system_properties.c文件:   
  11. static int get_fd_from_env(void)  { 
  12. char *env = getenv("ANDROID_PROPERTY_WORKSPACE");   
  13. if (! env) {  return -1; 
  14. }   
  15. return atoi(env);  } 
  16.   static int map_prop_area() 
  17. {  bool formFile = true; 
  18. int result = -1;  int fd; 
  19. int ret;   
  20. fd = open(property_filename, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);  if (fd >= 0) { 
  21. /* For old kernels that don't support O_CLOEXEC */  ret = fcntl(fd, F_SETFD, FD_CLOEXEC); 
  22. if (ret < 0)  goto cleanup; 
  23. }   
  24. if ((fd < 0) && (error == ENOENT)) {  fd = get_fd_from_env(); 
  25. fromFile = false;  } 
  26.   if (fd < 0) { 
  27. return -1;  } 
  28.   struct stat fd_stat; 
  29. if (fstat(fd, &fd_stat) < 0) {  goto cleanup; 
  30. }   
  31. if ((fd_stat.st_uid != 0)  || (fd_stat.st_gid != 0) 
  32. || (fd_stat.st_mode & (S_IWGRP | S_IWOTH) != 0)  || (fd_stat.st_size < sizeof(prop_area))) {