lstat函数
功能
与stat几乎完全一样,都是从块设备上的inode节点空间中读取文件的属性信息。但是与stat唯一不同的是,lstat会区分链接文件。
(1)stat:当操作对象是链接文件时,stat获取的文件属性是链接文件背后所指向的文件,而不是链接文件的。
(2)lstat:当操作对象是链接文件时,lstat直接显示的是链接文件本身的文件属性。
我们进行代码演示:
我们先创建链接文件进行对比:
my_ls是 通过stat函数实现我们可以看到,使用my_ls过去的文件属性和ls -l new.txt获取的文件属性是一样,都是普通文件,也就是说通过stat函数获取的直接是链接文件所指向文件属性,而通过ls -l lnew 显示的是链接文件本身属性。
如果我们要让my_ls显示链接文件属性的只需要把代码里面是stat改成lstat即可。
我们修改之后进行验证:
这时我们可以发现,使用my_ls lnew和 ls -l lnew的结果是一样的,显示都是链接文件属性。
fstat函数
函数原型
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int fstat(int fd, struct stat *buf);
功能
和stat一样,也是用于获取文件属性。
不过与stat不同的是,fstat是使用文件描述符来操作的,当你不知道文件路径名,但是你知道指向这个文件的描述符时,就可以使用fstat来操作。
代码演示:
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
void print_error(char *str)
{
perror(str);
exit(-1);
}
int main(int argc,char **argv)
{
int ret = 0;
struct stat sta = {0};
//int stat(const char *pathname, struct stat *statbuf);
//获取文件属性
if(argc != 2)
{
printf("my_ls fileName\n\n");
exit(-1);
}
printf("argv[0] = %s,argc[1] = %s\n",argv[0],argv[1]);
int fd = open(argv[1],O_RDWR);
if(-1 == fd)
{
perror("open fail");
exit(-1);
}
ret = fstat(fd,&sta);
if(-1 == ret) print_error("stat fail");
////打印文件类型
char file_type = '0';
if(S_ISLNK(sta.st_mode)) file_type = 'l';
else if( S_ISREG(sta.st_mode)) file_type = '-';
else if( S_ISDIR(sta.st_mode)) file_type = 'd';
else if( S_ISCHR(sta.st_mode)) file_type = 'c';
else if( S_ISBLK(sta.st_mode)) file_type = 'b';
else if( S_ISFIFO(sta.st_mode)) file_type = 'p';
else if( S_ISSOCK(sta.st_mode)) file_type = 's';
printf("%c ",file_type);
//打印文件权限
char buf[10] = {0};
char tmp_buf[] = "rwxrwxrwx";
int i;
for(i = 0;i<9;i++)
{
if(sta.st_mode&(1<<(8-i))) buf [i] = tmp_buf[i];
else buf[i] = '-';
}
printf("%s",buf);
//打印文件属性
printf("%d %lu %d %d %ld %ld %s\n",sta.st_mode,sta.st_nlink,sta.st_uid,sta.st_gid,sta.st_size,sta.st_atime,argv[1]);
return 0;
}
执行结果为:
ls命令调用的是lstat,因为当ls的是链接文件时,能够单独的讲链接文件自己的属性显示出来,而不是背后所指向文件的属性。
Fstat 函数在对于链接文件处理上和stat是一样的,也就是说对于链接文件,fstat也是直接获得链接文件所指向的文件属性。
r w x的含义
r:表示文件可以被读
w:表示文件可以被写
x:表示文件可以被执行
x对于普通文件来说如果普通文件存放的只是文字编码,因为文字编码无法被cpu执行,所以普通文件的x没有太大意义,所以一般的普通文件的x权限一般都是-。
如果普通文件里面存放的是机器指令,机器指令是可以被cpu执行的,存放机器指令的文件就必须要有x权限,如果没有是无法执行的。
比如gcc编译得到的可执行文件,里面放的就是机器指令,该文件默认就有x,所以才能被执行,否者文件是无法执行的。
目录文件的x权限
我们发现目录都有x,显然目录里面放的并不是机器指令,是不能被执行的,对于目录的x来说,也被称为通过权限,也就是说,如果你的目录没有x权限,你是无法通过这个目录的。
例如:
open("/dev/input/sda.txt", …);
如果/dev/input/sda.txt路径中的某个目录没有x,就无法通过这个目录,最终找不到sda.txt文件,这个路径就是一个无用路径。
不过正常情况下,除非你自己刻意把目录的x设为-,否则创建的目录默认都有x,不会出现无法通过的情况。
x对于其它文件来说,意义不大
chown命令
功能:用于修改文件的属主
修改所属用户
chown 新的所属用户 文件
修改所属组
chown :新的组 文件
同时修改
chown 新的所属用户:新的组 文件