zoukankan      html  css  js  c++  java
  • APUE-文件和目录(三)函数chown 和lchown

    下面的几个chown函数可用于更改文件的用户ID和组ID。如果两个参数owner或group中的任意一个是-1,则对应的ID不变。

    #include<unistd.h>
    int chown(const char *pathname,uid_t owner,gid_t group);
    int fchown(int fd,uid_t owner,gid_t group);
    int fchownat(int fd,const char *pathname,uid_t owner,gid_t group,int flag);
    int lchown(const char *pathname,uid_t owner,gid_t group);
    若成功返回0;若出错返回-1
    

    在符号链接下,lchown和fchownat(设置了AT_SYMLINK_NOFOLLOW标志)更改符号链接本身的所有者,而不是该符号链接所指向的文件的所有者。

    看下面的例子:

    #include <unistd.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <errno.h>
    #define RWRWRW  (S_IRUSR |S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
    //#define  _POSIX_CHOWN_RESTRICTED -1
    
    int main(void)
    {
        umask(0);//remove the mask
        int rv = creat("source.txt",RWRWRW);//creat a file whose mode is -rw-rw-rw-
        system("ln -s source.txt source_l.txt");//create a soft link to "source.txt" whose mode is lrwxrwxrwx
        rv = lchown("source_l.txt",0,0);//update the user ID and group ID to 0
        printf("rv:%d
    ",rv);
        printf("errno:%d
    ",errno);
        return 0;
    }
    

    首先创建一个文件source.txt,然后创建一个符号链接source_1.txt,最后修改此符号链接的所有者和所属组。

    harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ gcc 4-11.c
    harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ./a.out          
    rv:-1                                                                      
    errno:1                                                                    
    harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ll               
    总用量 29                                                                     
    -rw-r----- 1 harlan harlan  282  6月  5 22:52 4-10.c                        
    -rw-rw-r-- 1 harlan harlan  516  6月  6 21:51 4-11.c                        
    -rw-rw-r-- 1 harlan harlan  290  6月  1 22:13 4-7.c                         
    -rw-rw-r-- 1 harlan harlan 1168  6月  5 22:15 4-9.c                         
    -rw-rw-r-- 1 harlan harlan 4950  6月  1 09:07 4.c                           
    -rwxrwxr-x 1 harlan harlan 8788  6月  6 21:51 a.out                         
    lrwxrwxrwx 1 harlan harlan   10  6月  6 22:00 source_l.txt -> source.txt    
    -rw-rw-rw- 1 harlan harlan    0  6月  6 22:00 source.txt                    
    

    在harlan用户下生成可执行文件,并执行,文件和符号链接生成成功,但是lchown执行失败,errno为1,表示“Operation not permitted”。

    原因因为如下:

    基于BSD的系统一直规定只有超级用户才能更改一个文件的所有者。

    切换到root用户下执行,最后成功:

    harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ su
    密码:
    root@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples# rm source*
    root@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples# ./a.out
    rv:0
    errno:0
    root@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples# ll
    总用量 37
    drwxrwsr-t 2 harlan harlan    0  6月  6 22:03 ./
    drwxrwxrwx 2 harlan harlan    0  5月 18 21:16 ../
    -rw-r----- 1 harlan harlan  282  6月  5 22:52 4-10.c
    -rw-rw-r-- 1 harlan harlan  516  6月  6 21:51 4-11.c
    -rw-rw-r-- 1 harlan harlan  290  6月  1 22:13 4-7.c
    -rw-rw-r-- 1 harlan harlan 1168  6月  5 22:15 4-9.c
    -rw-rw-r-- 1 harlan harlan 4950  6月  1 09:07 4.c
    -rwxrwxr-x 1 harlan harlan 8788  6月  6 21:51 a.out*
    lrwxrwxrwx 1 root   root     10  6月  6 22:03 source_l.txt -> source.txt
    -rw-rw-rw- 1 root   harlan    0  6月  6 22:03 source.txt
    

    接下来看一下怎么才能修改文件的组,满足如下条件就能够修改文件的组:
    如果进程拥有此文件(有效用户ID等于该文件的用户ID),参数owner等于-1或文件的用户ID,并且参数group等于进程的有效组ID或进程的附属组ID之一,那么一个非超级用户进程可以更改该文件的组ID。
    看下面的例子:

    首先我们为当前用户harlan添加一个附属组ID,改之前:

    harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ id harlan
    uid=1000(harlan) gid=1000(harlan) group=1000(harlan)
    

    改之后:

    harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ sudo usermod -G zexu harlan   
    [sudo] password for harlan:
    harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ id harlan
    uid=1000(harlan) gid=1000(harlan) group=1000(harlan),1001(zexu)
    

    为了是当前设置生效,执行如下命令:

    harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ newgrp zexu
    

    最后看下面的代码:

    #include <unistd.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <errno.h>
    #define RWRWRW  (S_IRUSR |S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
    void test_chownGID()
    {
        int rv = creat("testGID.txt",RWRWRW);
        if(rv<0)
        {
            printf("create file error!
    ");
        }
        struct stat statbuf;
        if(stat("testGID.txt",&statbuf)<0)
        {
            printf("stat error!
    ");
        }
        else
        {
            printf("The current user's group ID is %d
    ",statbuf.st_gid);
        }
        rv = chown("testGID.txt",-1,1001);
        printf("rv:%d
    ",rv);
        if(stat("testGID.txt",&statbuf)<0)
        {
            printf("stat error!
    ");
        }
        else
        {
            printf("After chown,the user's group ID is %d
    ",statbuf.st_gid);
        }
    }
    int main(void)
    {    
        test_chownGID();
        return 0;
    }
    

    执行结果:

    harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ./a.out
    The current user's group ID is 1000
    rv:0
    After chown,the user's group ID is 1001
    
  • 相关阅读:
    js对象数组(JSON) 根据某个共同字段 分组
    一个 函数 用来转化esSearch 的range 条件
    关于 vuex 报错 Do not mutate vuex store state outside mutation handlers.
    android listview 重用view导致的选择混乱问题
    android SDK和ADT的更新
    Android中adb push和adb install的使用区别
    pycharm中添加扩展工具pylint
    su Authentication failure解决
    Putty以及adb网络调试
    有关android源码编译的几个问题
  • 原文地址:https://www.cnblogs.com/harlanc/p/6964786.html
Copyright © 2011-2022 走看看