文章将描述在Android2.3.7中移植wifi所碰到的一个chown失败问题,并记录问题分析的过程。
注意文章中引用了《UNIX环境高级编程》。
1:发现问题
启动Android 的wifi硬件的时候,system_server进程将调用hardware层所提供的wifi_start_supplicant(), 该函数将会调用ensure_config_file_exists()来确认配置文件。
如/data/misc/wifi/wpa_supplicant.conf中的文件不存在,将会新建一个并“COPY”/system/etc/wifi/wpa_supplicant.conf文件中的内容。完成后将会对新建的文件进行chown的系统调用,这时候错误就发生了E/WifiHW ( 92): Error changing group ownership of /data/misc/wifi/wpa_supplicant.conf to 1010: Operation not permitted。
2:分析问题
1):遇到这类问题第一时间就是google了,国外的报出了问题,但没有决定。国内的解决了,但方法令人吐血,不是直接手动copy文件就是直接chown代码去掉。哎,本着学习的心态继续下去。
2):网上实在找不到解决办法,哪从0开始吧。首先看了《UNIX环境高级编程》4.11chown的说明。大致的意思就是在_POSIX_CHOWN_RESTRICTED起用作的情况下:
(1):只有超级用户进程能更改该文件的用户ID。
(2):若满足下列条件,一个非超级用户进程可以更改该文件的的组ID.
(a):进程拥有此文件(其有效用户ID等于该文件的用户ID).
(b):参数owner等于文件的用户ID,参数group等于进程的有效组ID或进程的添加组ID之一。
好了当前进程system_server的有效用户ID是system,不是超级用户,而chown(SUPP_CONFIG_FILE, AID_SYSTEM, AID_WIFI),也只是想改变文件的组ID。哪么新建出的文件的uID,跟gID又是什么呢?这将决定到条件(b)是否成立。
另外_POSIX_CHOWN_RESTRICTED是否定义,可用pathconf或fpathconf函数查询。
3):新建文件(使用open,creat)的用户ID为进程的有效用户ID。而组ID呢,这个有点复杂,在《UNIX环境高级编程》4.6提到新建文件组ID的问题。POSIX.1允许选择下列之一作为新文件的组ID,
(a):新文件的组ID可以是进程的有效组ID.
(b):新文件的组ID可以是它所有目录的组ID.