最近linux老师布置了让实现ls -l命令,stat结构的st_mode成员是存储文件类型、文件权限的int型数,存储权限用的是低9位,这九位的前三位是用户的读写执行权限(rwx),中三位是组的读写执行权限,最后三位是其他的读写执行权限。rwx r-- -wx就表示为111 100 011。
stat.h里面提供的宏定义只能判断用户/组/其他 对某个文件是否仅拥有一个权限,如只能识别100 000 000或者是000 100 000诸如此类这九位当中只有一位是1,其他是0的情况(如果我漏看了,存在其他便捷的宏勿喷)。思路主要是通过掩码,将三者权限分别判断,并通过移位来判断某人具体有哪种权限来实现。下面是根据st_mode获得这三者权限的代码:
#include<sys/stat.h>
//以下三行是对st_mode掩码并移位,使它只有低三位有用。
unsigned short usr_permi=((st_mode&S_IRWXU)>>6);
unsigned short grp_permi=((st_mode&S_IRWXG)>>3);
unsigned short oth_permi=st_mode&S_IRWXO;
static inline void PrintPermission(const unsigned short masked_code){//经过掩码并移位后只剩用户/组/其他三者其一的三位,即0000 0000 0000 0xxx(假设short为16位)
if((unsigned short)(masked_code>>2))putchar('r');
else putchar('-');
if((unsigned short)((masked_code>>1)<<(sizeof(short)*8-1)))putchar('w');
else putchar('-');
if((unsigned short)(masked_code<<(sizeof(short)*8-1)))putchar('x');
else putchar('-');
}
需要注意的是要用无符号类型,作为条件判断等表达式的时候记得加上强制类型转换,不然会自动类型提升为int溢出导致结果不如预期,换成unsigned int也是可以的,unsigned short省点空间。