Linux学习:文件一些特征或特性更改/获得-----01

1:首先、我简单介绍一下这节的内容。

    
这节主要是讲解如何修改或获取文件一些特性或者其他特征。

2:接下来介绍三个stat函数和他们返回的信息。


    函数原型:int stat(const char *restrict pathname, struct stat *restrict buf);
                                            int fstat(int fiedes, struct stat *buf);
                                            int lstat(const char* restrict pathname, struct stat *restrict buf);
    这三个函数的区别:第一个函数:给出路径名,第二个参数就会返回与这个路径名相关的信息。第二个函数返回与文件描述符相关的文件信息。第三个函数与第一个函数类似,但是如果文件
    是一个符号链接的情况下、那么就会返回这个符号链接有关的信息。
    第二个结构是一个结构体,结构体成员如下。
    struct stat
    {
        mode_t st_mode;        /*文件类型和文件的权限*/
        ino_t st_ino;                  /*i节点号*/
        dev_t st_dev;                 /*设备号*/
        dev_t st_rdev;              /*指定文件的设备号*/
        nlink_t st_nlink;            /*链接号*/
        uid_t st_uid;                     /*用户ID*/
        gid_t st_gid;                      /*组ID*/
        off_t st_size;                      /*有关文件大小*/
        time_t st_atime;               /*最后访问时间*/
        time_t st_mtime;               /*最后更改时间*/
        time_t st_ctime                  /*最后文件状态改变时间*/
        blksize_t st_blksize           /*给出文件块的大小,单位是字节,通常是512字节*/
        blkcnt_t st_blocs;              /*这个字段给出文件系统给该文件分配内存的块数*/
        
    }
    

3:文件类型


前面我们说文件类型,这里就不一一介绍了。
结合2-3我们在这里写一个程序,去读取从终端输入文件名,然后我们根据这个文件名输出该文件的状态。
实例:
#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{
        int         i;
        struct stat buf;
        char*       ptr;

        for(int i = 1; i < argc; i++)
        {
                printf("%s:", argv[i]);
                if(lstat(argv[i],  &buf) < 0)
                {
                        printf("\n");
                        continue;
                }
                if(S_ISREG(buf.st_mode))
                {
                        ptr = "regular";
                }else if(S_ISDIR(buf.st_mode))
                {
                        ptr = "directory";
                }else if(S_ISCHR(buf.st_mode))
                {
                        ptr = "character special";
                }else if(S_ISBLK(buf.st_mode))
                {
                        ptr = "block special";
                }else if(S_ISFIFO(buf.st_mode))
                {
                        ptr = "fifo";
                }else if(S_ISLNK(buf.st_mode))
                {
                        ptr = "symblock link";
                }else if(S_ISSOCK(buf.st_mode))
                {
                        ptr = "socket";
                }else
                {
                        ptr = "unkonw mode";
                }
                printf("%s\n", ptr);
        }

        return 0;
}

4:设置用户ID和组ID

        
    关于用户ID有及部分:实际用户ID、实际组ID,有效用户ID、有效组ID、附加组ID,保存设置用户ID、保存设置组ID。
    实际用户ID和组ID是在登录时取得。
    有效的用户ID、组ID、附加组ID决定我们关于文件的访问权限。
    保存用户ID、组ID是我们在执行exec时候保存有效用户ID和组ID的一个副本。
    
    在我们执行程序的时候,进程的有效用户ID就是实际用户ID、有效组ID就是实际组ID。但是我们能能设置st_mode一个特殊的位,那么在执行该程序的时候,进程的有效用户ID就是文件的有效用户ID、进程的有效组ID就是文件的有效组ID。这样做实际例子(当我们执行一个文件的时候,这个文件设置这样的ID。那么我们在执行这个文件的时候,我们都将该文件所有者和所属组的权限)
    关于文件的实际用户ID和实际组ID与有效用户ID和有效组ID。其实实际用户ID和组ID就是在我们登录系统是从口令文件中取得,我们所说的有效用户ID和组ID就是我们文件实际用户和组ID。他们
    之间是不相互干扰的。
    

5:文件访问权限


在第一节中,我们曾经提到有关文件权限的内容.在我们使用stat系列函数的时候,能从st_mode部分得到文件的访问权限位.我们在这里详细讲解一些有关的内容.
我们首先将9个权限位分为三类.所有者,所属组,其他人.我们通常使用chmod命令更改文件有关的权限。
chmod命令介绍:
chmod [who] [+ | - | =] [mode] 文件名 
    命令中各选项的含义为: 
    操作对象who可是下述字母中的任一个或者它们的组合: 
    u 表示“用户(user)”,即文件或目录的所有者。 
    g 表示“同组(group)用户”,即与文件属主有相同组ID的所有用户。 
    o 表示“其他(others)用户”。 
    a 表示“所有(all)用户”。它是系统默认值。 
    操作符号可以是: 
    + 添加某个权限。 
    - 取消某个权限。 
    = 赋予给定权限并取消其他所有权限(如果有的话)。 
    设置mode所表示的权限可用下述字母的任意组合: 
    r 可读。 
    w 可写。 
    x 可执行。 
    X 只有目标文件对某些用户是可执行的或该目标文件是目录时才追加x 属性。 
    s 在文件执行时把进程的属主或组ID置为该文件的文件属主。方式“u+s”设置文件的用户ID位,“g+s”设置组ID位。 
    t 保存程序的文本到交换设备上。 
    u 与文件属主拥有一样的权限。 
    g 与和文件属主同组的用户拥有一样的权限。 
    o 与其他用户拥有一样的权限。
    
    同时我们也能在程序中获取文件的权限,在上述4中使用stat获取文件的一些权限。我们能够使用下图中的函数判断函数的各个访问权限位。

file


在接下来我们介绍打开文件的一些规则:
        第一个规则:当我们打开一个文件的时候,那么包含这个文件所有目录必须有执行权限。同时、当我们打开当前目录的一个文件时,当前工作目录也要有执行权限(也就是“.”)。
      第二个规则:读写权限分别定义了我们对文件的读和写权限。
        第三个规则:当我们打开一个文件有截断标志的时候,一定要有写权限。
        第四个规则:当我们在一个目录创建/删除一个文件的时候,我们需要对该目录有执行和写权限。
        第五个规则:如果函数使用exec执行一个文件的时候,必须对该文件有执行权限,并且该文件必须是一个普通文件。
        
    当我们打开、创建或删除一个文件的时候,内核都对该文件进行一些权限检查。这种权限检测可能检测进程的所有者、所属组,还有对文件的所有者和所有组,通过对比看进程是否对
    该文件有打开、创建或删除的权限。(每当我们执行向chmod rm这些命令的时候,其实他们都是一个小的程序。例如rm在/usr/bin/rm下)。通俗点来讲就是文件的用户ID和组ID还有其他人
    权限位和进程的有效用户ID,组ID进行比较。如果文件的所有者和进程的有效用户ID相同,那么进程就对该文件有文件所有者的权限。
    其他的情况也类似。
    

6:新的文件或目录所有权

    
    在我们创建文件的时候,我们可以指定文件的三类权限位,但是我们并未指明文件的有效用户ID和组ID。在我们这节我们将介绍创建一个文件的时候,文件的用户ID和组ID。
    这里我们就在这里简单介绍一下、新文件的用户ID就是进程的有效用户ID。新文件的组ID可以是进程的有效组ID、同时它也可以是文件所在目录的组ID。
    

7:access函数:此函数的作用是以进程的实际用户ID和组ID去访问文件。

函数原型:int access(const char* pathname, int mode);
mode:F_OK(测试文件是否存在),X_OK,W_OK,R_OK分别测试文件有执行、写和读权限。

8:umask函数


此函数设置文件模式创建屏蔽字。
函数原型:mode_t umask(mode_t cmask);
例子:如果我们想要任何用户都能读文件的时候,我们应当将进程umask设置位0。否则、我们运行进程的时候、某些权限位可能就会关闭。
在这里、我举一个简单的例子,如果你的用户当前权限位是002,那么你创建文件的时候其他人写权限将会被关闭,因此其他人无法写你的文件。

9:chmod和fchmod:更改现有文件的访问权限。


函数原型:int chmod(const char* pathname, mode_t mode);
                                         int fchmod(filed, mode_t mode);
改变权限位是有条件的:进程是超级用户/进程有效用户ID是文件所有者ID。
mode的设置有如下多种

file

10:chown、fchown、lchown函数:更改文件的所有者,其中lchown函数在文件是符号链接的时候,更改的是文件本身的所有者、而不是符号链接本身的所有者。


函数原型:int chown(const char* pathnane, uid_t owner, gid_T group);
                                         int fchown(int fd, uid_t owner, gid_t group);
                                         int lchown(const char* pathname, uid_t owner, gid_t group);

    

你可能感兴趣的:(c)