关于文件和目录的简单操作(二)

图片来自:Unix Linux编程实践教程


readdir 返回的struct dirent类型结构体

struct dirent{
ino_t     d_ino;   //索引号%ld
off_t     d_off;//在目录文件中的偏移量 %ld
unsigned  short d_reclen;//这个记录的长度%u
unsigned char  d_type;//文件的类型;不受所有文件系统的支持;%u
char           d_name[256]; /文件名
           };

利用 ls -l查看出来的文件所包含的信息


模式     每行的第一个字符表示文件类型。最常用的两个为:“-”代表普通文件,“d”代表目录,

     接下来的9个字符表示文件访问权限,分别为,读、写、执行权限,9个字符分成三组,                        针对三个对象、用户、同组用户  和其他用户

链接数 链接数指的是该文件被引用的次数。

文件所有者  文件所有者的用户名

  文件所有者所在的组

大小      显示文件的大小(所有目录的大小相等,都是1024字节,因为目录所占的空间的分配是以块为单位的,每个块       512字节。所以目录的大小经常是相等的,如果是一般文件,size会显示出文件中数据的实际字节数)

最后修改时间       文件的最后修改时间,如果是较新的文件,会列出月、日、时刻,较老的文件只能列出月日年

文件名 文件名


stat将文件fname的信息复制到指针所指的结构中

struct stat {
               dev_t     st_dev;         //文件的ID
               ino_t     st_ino;         //inode号码
               mode_t    st_mode;        //文件类型和许可 
               nlink_t   st_nlink;       //硬链接数量               
               uid_t     st_uid;         //所有者的用户ID
               gid_t     st_gid;         //所有者的组ID
               dev_t     st_rdev;        //设备号               
               off_t     st_size;        //以字节为单位的总大小
               blksize_t st_blksize;     //文件系统I / O块大小
               blkcnt_t  st_blocks;      //分配的512B块的数量
               struct timespec st_atim;  //最后访问时间
               struct timespec st_mtim;  //最后修改的时间
               struct timespec st_ctim;  //最后状态更改的时间

#define st_atime st_atim.tv_sec      //向后兼容
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};


关于权限的图解:


八进制数字和rwx权限之间的转换:


 八进制100664转换为二进制为1000 000 110 110 100

 其中前四位为文件类型在这儿是8,表示是文件类型是普通的文件类型,再往后面是三种特殊属性,为1时是具有属性,0是没有,在后面没三位是一种一种用户的权限,1代表拥有这种权限,0代表没有

S_IFMT是一个掩码,它的值是0170000,可以用来过滤出前四位表示的文件类型

if((info.st_mode&0170000) == 0040000)
printf("this is directory!");

还可以用(sys/stat.h)中的宏来替代上述代码

 

#define S_ISFIFO(m) (((m)&(0170000)) ==(0010000))
#define S_ISDIR(m)  (((m)&(0170000)) ==(0040000))
#define S_ISCHR(m)  (((m)&(0170000)) ==(0020000))
#define S_ISBLK(m)  (((m)&(0170000)) ==(0060000))
#define S_ISREG(m)  (((m)&(0170000)) ==(0100000))
#define S_ISLINK(m) (((m)&(0170000)) ==(0120000))
可以这样使用宏:

if(S_ISDIR(info.st_mode))
printf("this is directory");
 struct passwd *getpwuid(uid_t uid);

getpwuid()函数返回一个指向包含密码数据库中与用户标识uid匹配的记录的中断字段的结构的指针。

struct passwd
{
   char * pw_name;//用户名
   char * pw_passwd;//密码
   _uid_t pw_uid;//用户ID
   _git_t pw_gid;//组ID
   char * pw_gecos;//全名
   char * pw_dir;//家目录
   char * pw_shell;//Shell
}
在Linux中,如果加入的新用户的UID与已经删除的老用户UID相同,老用户留下来的文件会被新用户所拥有,新用户对这些文件具有所有的权限。

 类似的函数有:

struct group *getgrgid(gid_t gid);

getgrgid()函数返回一个结构指针,该结构包含组数据库中与组ID相匹配的记录的中断字段。

 

struct group {
               char   *gr_name;        
               char   *gr_passwd;
     gid_t   gr_gid;         
               char  **gr_mem;        //以NULL结尾的指向组成员名称的指针数组 
           };



可以这样得到组名:

 getgrgid(gid)->gr_name;

文件中的三个特殊属性:

1、SUID(set-user-id)位

一个程序拥有SUID位之后,可以别的程序通过此权限可以执行它,执行时执行的用户被当作程序的拥有者,但是不是程序拥有者的用户不能修改此程序,因为运行的程序可以通过getuid来得到用户的ID。

可以通过<sys/stat.h>中定义的掩码来检验某一个程序是否由SUID位:

#define S_ISUID 0004000

它正好是二进制数字中权限为的三个特殊属性的第一位 

2、SGID(set-group-id)位

SGID和SUID属性类似,但是是位于组上的,一个程序有SGID属性时,这个程序被运行时,就好像他被所属组中的某一个用户运行一样,SGID位给程序某一个组的访问权限。

它的掩码为:

#define S_ISGID 0002000

3、sticky位

对于文件来说,早期的UNIX系统经常要在有限的内存中运行很多程序,它使用到交换技术。在硬盘上,有一个叫交换空间的分区,当某一个程序暂时不运行时,它会被放在交换分区上,当它要运行时,它会被内核装载到内存中,从交换空间到内存,要比从硬盘到内存快,在非交换空间的硬盘上,程序可能被分成好多块分别存放在不同地方,交换空间上的文件是不分块。一些经常用到的程序,如果位于交换空间,那么装载的速度就会快很多。sticky位告诉内核即使没有人在使用,也要把它放在交换空间中,程序粘在交换空间中。现在交换技术已经不像以前那么重要了,取而代之的是虚拟内存技术,虚拟内存使得可以以更小的单位,进行交换。

 对于目录而言,有些目录被设计用来存放临时文件,如/tmp,谁都可以往这里创建/删除文件,sticky使得目录里的文件只能被创建者删除。

下面两句相等,还可以通过umask来修改权限掩码的。

chmod("test",04764);
chmod("test",S_ISUID|S_IRWXU|S_IRWXU|S_IWGRP|SIROTH);


<sys/stat.h>定义的宏:



利用ls 查看文件属性时,文件所有者的可执行权限x被替换为s代表SUID被设置,文件所属组的可执行权限x被s替换代表SGID被设置,其他用户的可执行权限x被替换为t代表sticky被设置。

××

 创建新文件

所有者:用户通过creat函数创建文件时,内核把文件所属有者设为运行程序的用户,但是如果程序具有SUID位的时候,那么新文件的所有者就是程序的文件所有者。

 组:通常情况下新文件的组被设为执行创建动作的用户所在组,在有些情况下,组会被设为与父目录的组相同。

时间:

 文件由三个时间,分别是最后修改时间(mtime),最后访问时间(atime),和属性最后修改时间(ctime),当文件被操作的时,内核会自动的修改这些时间。

 

utime是一个系统调用,可以用来设置最后修改时间和最后访问时间。

struct utimbuf {
               time_t actime;       /* access time */
               time_t modtime;      /* modification time */
           };

结构体成员分别存放要更新的最后访问时间和最后的修改时间。

修改/移动 文件/目录 名/位置

两个参数分别存放原文件名和新文件名




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值