【Linux系统调用API】四、与权限有关的函数

2024-08-08 17:08:23 浏览数 (2)

1. access函数

  • 包含头文件
代码语言:javascript复制
#include <unistd.h>
  • 函数原型
代码语言:javascript复制
int access(const char *pathname, int mode);
  • 函数功能 判断文件权限以及文件是否存在。access() checks whether the calling process can access the file pathname. If pathname is a symbolic link, it is dereferenced.
  • 函数参数
    • pathname:文件名(及路径)
    • mode:要判断的选项
      • R_OK:是否有读权限
      • W_OK:是否有写权限
      • X_OK:是否有执行权限
      • F_OK:是否存在
  • 函数返回值
    • 成功返回0(有对应权限或文件存在)。On success (all requested permissions granted), zero is returned.
    • 失败返回-1并设置errno。On error (at least one bit in mode asked for a permission that is denied, or some other error occurred), -1 is returned, and errno is set appropriately.

下面通过一个例子演示access函数的用法。

代码语言:javascript复制
/************************************************************
  >File Name  : access_test.c
  >Author     : QQ
  >Company    : QQ
  >Create Time: 2022年05月15日 星期日 21时23分19秒
************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char* argv[])
{
    if(argc < 2)
    {
        printf("not found filenamen");
        return -1;
    }   
    
    if(access(argv[1], F_OK) == 0)
    {
        printf("%s: F_OKn", argv[1]);  
    }
    else
    {
        printf("no file name is %sn", argv[1]);
        return 0;
    }
    
    if(access(argv[1], R_OK) == 0)
    {
        printf("%s: R_OKn", argv[1]);  
    }
    else
    {
        printf("can not read %sn", argv[1]);   
    }
    
    if(access(argv[1], W_OK) == 0)
    {
        printf("%s: W_OKn", argv[1]);  
    }
    else
    {
        printf("can not write %sn", argv[1]);  
    }
    
    if(access(argv[1], X_OK) == 0)
    {
        printf("%s: X_OKn", argv[1]);  
    }
    else
    {
        printf("can not execution %sn", argv[1]);  
    }
    return 0;
}

下面测试一下代码,来说明access函数的作用,首先我们在普通用户下测试该函数

现在我们切换到root用户,或者在普通用户下使用sudo命令,再运行一下该函数

对比上面两次测试结果,这时候我们发现一个奇怪的现象,同一个文件1.txt在qq用户下使用access函数返回的是无写权限,但是在root用户下使用access函数返回的是有写权限,这是为什么呢?首先,我们通过 ls -l 命令来查看并分析一下文件1.txt的权限位。首先可以看到,文件归属于root用户,并且该文件对归属用户的权限位是 rw- ,有写权限,对其它用户的权限位是 r-- ,无写权限。也就是说,这个文件1.txt对root用户有写权限,对其他用户比如qq无写权限。现在原因就比较清晰了,access函数在判断权限的时候是判断有效用户的权限,比如说有一个文件对usr1无权限,我们使用access函数获取时确实没有执行权限,但是如果用sudo去执行的话(或者在root用户下执行),就相当于判断这个文件对root用户的权限。也就是说,access函数是判断一个文件相对于某个用户的权限,而不是说文件本身的权限,access函数返回的是文件对某一用户的权限。

2. chmod函数

  • 包含头文件
代码语言:javascript复制
#include <sys/stat.h>
  • 函数原型
代码语言:javascript复制
int chmod(const char *path, mode_t mode);
int fchmod(int fd, mode_t mode);
  • 函数功能 修改某文件的权限,对应于命令chmod是在shell命令行修改权限,使用该函数可以在文件中修改另一文件的权限。These system calls change the permissions of a file.
  • 函数参数
    • path:文件名(路径)
    • mode:文件的权限,可以通过与运算设定多个权限。The new file permissions are specified in mode, which is a bit mask created by ORing together zero or more of the following: S_ISUID, S_ISGID, S_ISVTX, etc. 更多的参数请见man手册。
  • 函数返回值
    • 成功返回0。On success, zero is returned.
    • 失败返回-1并设置errno。On error, -1 is returned, and errno is set appropriately.

3. chown函数

  • 包含头文件
代码语言:javascript复制
#include <unistd.h>
  • 函数原型
代码语言:javascript复制
int chown(const char *path, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
int lchown(const char *path, uid_t owner, gid_t group);
  • 函数功能 These system calls change the owner and group of a file. 改变用户和用户组。
  • 函数参数
    • path:文件名及路径
    • owner:用户ID,uid_t类型,可以在/etc/passwd查看,或使用stat函数获取st_uid
    • group:组ID,gid_t类型,可以在/etc/group查看,或使用stat函数获取st_gid
  • 函数返回值
    • 成功返回0。On success, zero is returned.
    • 失败返回-1并设置errno。On error, -1 is returned, and errno is set appropriately.

注意,在查看man手册的时候,如果直接使用 man chown 的话,假如有同名命令会显示同名命令。所以,如果你查看man手册如果发现没有函数原型,说明该函数有同名命令,需要加上章节才能查看函数的帮助手册 man 2 chown,系统调用都在第2章节。

4. rename函数

  • 包含头文件
代码语言:javascript复制
#include <stdio.h>
  • 函数原型
代码语言:javascript复制
int rename(const char *oldpath, const char *newpath);
  • 函数功能 rename() renames a file, moving it between directories if required. 重命名文件(也可重命名目录,目录也是文件)。
  • 函数参数
    • oldpath:旧的文件名(或路径)
    • newpath:新的文件名(或路径)
  • 函数返回值
    • 成功返回0。On success, zero is returned.
    • 失败返回-1并设置errno。On error, -1 is returned, and errno is set appropriately.

示例分析

代码语言:javascript复制
/************************************************************
  >File Name  : rename_test.c
  >Author     : QQ
  >Company    : QQ
  >Create Time: 2022年05月17日 星期二 11时44分22秒
************************************************************/
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
    if(argc < 3)
    {
        printf("not found oldpathname & newpathnamen");
        return -1;  
    }
    rename(argv[1], argv[2]);
    return 0;
}

rename函数可以为文件或目录重命名

rename函数在重命名时也可以改变文件的路径,相当于移动且重命名

5. truncate函数

  • 包含头文件
代码语言:javascript复制
#include <unistd.h>
#include <sys/types.h>
  • 函数原型
代码语言:javascript复制
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);
  • 函数功能 截断文件,将文件截断为指定大小。The truncate() and ftruncate() functions cause the regular file named by path or referenced by fd to be truncated to a size of precisely length bytes.
  • 函数参数
    • path:文件名(路径),必须存在,只有是已经存在的文件才能去截断。
    • length:指定截断后的长度,如果这个长度length小于文件大小,那么就会把文件截断为指定大小;如果length大于文件本身长度,那么就会填充文件直到文件达到length指定的长度(用^@填充)。If the file previously was larger than this size, the extra data is lost. If the file previously was shorter, it is extended, and the extended part reads as null bytes ('').
  • 函数返回值
    • 成功返回0。On success, zero is returned.
    • 失败返回-1并设置errno。On error, -1 is returned, and errno is set appropriately.

下面通过一个例子来说明truncate函数的用法。

代码语言:javascript复制
/************************************************************
  >File Name  : truncate_test.c
  >Author     : QQ
  >Company    : QQ
  >Create Time: 2022年05月15日 星期日 22时13分45秒
************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char* argv[])
{
    if(argc < 3)
    {
        printf("not found filenamen");
        return -1;  
    }
    printf("file %s truncate : 1024 byten", argv[1]);
    truncate(argv[1], 1024);
    printf("file %s truncate : 4 byten", argv[2]);
    truncate(argv[2], 4);
    return 0;
}

运行函数,查看测试结果

使用vim编辑器打开可以看到被扩展的文件中填充了很多@字符(其实都是空字节 只不过在不同平台上显示出来不一样而已)。

0 人点赞