之前的笔记搬运
文件操作
posix标准的文件操可以直接用open, read, write等函数, 详情可以查询linux
api帮助文档;
pwrite和pread可以指定偏移写内容与读内容, 是为了解决多线程同时操作的问题;
posix标准里返回值小于0就是失败, 大于等于0就是成功, 由于返回值是标准那么小于0时,就可以使用以下函数来获取错误信息, 也可以写成宏使用;
perror(), 打印错误信息
strerror(), 获得错误信息字符串
文件权限
每个App都有一个单独的系统账户, 每个用户都有单独的权限,
安卓是以这样的方式来区分权限的;
权限由xrw标识, 程序与目录都有权限, 目录的权限与普通文件的权限是不同的;
程序权限:
x代表可以被执行
r代表可以被读取数据
w代表可以被写入数据
目录权限:
x 可访问目录中的文件
r 通过opendir()函数读取目录,进而可以通过readdir()函数获得目录内容,即目录下的文件列表
w 写权限代表的是可在目录内创建、删除文件,而不是指的写目录本身
不同ID的区分
实际用户 ID、实际组 ID
有效用户 ID、有效组 ID
设置用户 ID、设置组 ID
实际用户ID(uid)和实际用户组ID(gid):标识我是谁。也就是登录用户的uid和gid,比如我的Linux以allen登录,在linux运行的所有的命令的实际用户ID都是allen的uid,实际用户组ID都是allen的gid
有效用户ID(euid)和有效用户组ID(egid):进程**用来决定我们对资源的访问权限**。一般情况下,有效用户ID等于实际用户ID,有效用户组ID等于实际用户组ID。**当设置-用户-ID(SUID)位设置,则有效用户ID等于文件的所有者的uid,而不是实际用户ID**;同样,如果设置了设置-用户组-ID(SGID)位,则有效用户组ID等于文件所有者的gid,而不是实际用户组ID。
假设当前实际用户是 allen,你执行的文件su的所有者是
root,这时候你在执行这条命令的时候 ,实际用户是 allen,有效用户也是 allen;
如果su这个文件设置用户 ID 标志(suid)打开,那么执行 su 的时候,实际用户是 allen,有效用户是 root, 这也是root的原理
获取linux文件详细信息
获取文件信息函数:
int stat(const char *filename, struct stat *buf);
第二个参数stat结构体
1 | struct stat { |
成员里最重要的成员就是 st_mode, 该成员描述了文件的类型和权限两个属性。
st_mode是个32位的整型变量, 不过现在的Linux操作系统只用了低16位;
Permission属性区域的bit0~bit8, 也即st_mode字段的最低9位,
它标识了文件所有者(owner)、组用户(group)、其他用户(other)的读(r)、写(w)、执行(x)权限。
Permission属性区域的bit9 ~bit11,代表文件的特殊属性,分别为set-user-ID位、set-group-ID位和sticky位;
当set-user-ID位被置1时, 那么该程序就拥有root权限;
当set-user-ID未被置1前, User的文件属性的标识为rwx, 而被置1后就会变成rws
Root的原理
谷歌的android系统管理员用户就叫做root, 该用户拥有操作任何目录与程序的权限,
而一般手机上的操作系统是禁止root用户登陆的;
Root的过程其实就是把一个shell文件放到/system/bin/ 设置set uid和set gid的权限。具体为什么设置了uid就可以拥有root权限可以参考上面ID的说明;
一般在root的过程中,还会给系统装一个程序,用来作为运行提示,由用户来决定,是否给予最高权限。比如程序的名字叫做Superuser.apk。当某些程序执行su指令想取得系统最高权限的时候,Superuser就会自动启动,拦截该动作并作出询问,当用户认为该程序可以安全使用的时候,那么我们就选择允许,否则,可以禁止该程序继续取得最高权限。