众所周知,android中对于java app有完整一套权限控制体系。因此,在java app中以jni方式、或者浏览器dlsym方式调用native库,并且native库需要调用linux内核的系统调用时,可能会遇到坑爹的权限问题。
进行系统调用可通过fork+exec族函数(fork时似乎浏览器进程会挂掉)或system()函数。在调用ping时就遇到此类问题。代码如下
int mysystem(const char* pCmd, char* pResult, int size)
{
int fd[2];
if(pipe(fd))
{
printf("pipe error!\n");
return -1;
}
fflush(stdout);
int bak_fd = dup(STDOUT_FILENO);
int new_fd = dup2(fd[1], STDOUT_FILENO);
system(pCmd);
read(fd[0], pResult, size-1);
pResult[strlen(pResult)-1] = 0;
close(fd[0]);
dup2(bak_fd, new_fd);
return 0;
}
结果此行read(fd[0], pResult, size-1);无论如何始终只读出一行PING 192.168.188.44 (192.168.188.44) 56(84) bytes of data,用各种方法,如popen+fread,现象相同。
甚至尝试用自己实现了ping的方法,具体见http://blog.youkuaiyun.com/junjieguo/article/details/7678496
但由于socket(PF_INET,SOCK_RAW,IPPROTO_ICMP)时,建立SOCK_RAW型的socket需要root权限,进程马上exit。
无论ping通ping不通,system的返回值WIFEXITED =1,WEXITSTATUS = 512。
最终原因是系统命令的权限问题,logcat屏蔽了很多底层打印导致问题难以定位。具体参考http://blog.youkuaiyun.com/zjg555543/article/details/7835693
解决方法:
busybox chmod 755 /system/bin/ping
busybox chmod u+s /system/bin/ping
busybox chmod g+s /system/bin/ping