Setting Immutable Flag using ioctl() in C

后端 未结 2 1523
没有蜡笔的小新
没有蜡笔的小新 2020-12-11 10:28

I have attempted to make a script that creates a file and then sets it as immutable similar to the chattr +i command for linux. The script compiles

2条回答
  •  眼角桃花
    2020-12-11 11:04

    You are using the right ioctl command, but you're passing it the wrong arguments.

    The manpage for ioctl_list(2) shows that FS_IOC_SETFLAGS expects to receive a pointer to int (an int *), yet you're passing it an integer literal (hence the Bad Address error).

    The fact that you don't to any error checking whatsoever is also not helping.

    The correct flag to pass to FS_IOC_SETFLAGS is a pointer holding the value EXT2_IMMUTABLE_FL, which is defined in ext2fs/ext2_fs.h (some older / different Linux distributions seem to have it under linux/ext2_fs.h), so you'll need to #include . Make sure to install e2fslibs-dev (and probably you'll need linux-headers too).

    This code is working:

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main()
    {
        FILE *fp;
        char shovel[16] = "I have a shovel!";
    
        if ((fp = fopen("shovel.txt", "w+")) == NULL) {
            perror("fopen(3) error");
            exit(EXIT_FAILURE);
        }
    
        fwrite(shovel, sizeof(shovel[0]), sizeof(shovel)/sizeof(shovel[0]), fp);
    
        int val = EXT2_IMMUTABLE_FL;
        if (ioctl(fileno(fp), FS_IOC_SETFLAGS, &val) < 0)
            perror("ioctl(2) error");
    
        fclose(fp);
    
        return 0;
    }
    

    Remember to run this as root.

    UPDATE:

    As Giuseppe Guerrini suggests in his answer, you might want to use FS_IMMUTABLE_FL instead, and you won't need to include ext2_fs.h:

    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main()
    {
        FILE *fp;
        char shovel[16] = "I have a shovel!";
    
        if ((fp = fopen("shovel.txt", "w+")) == NULL) {
            perror("fopen(3) error");
            exit(EXIT_FAILURE);
        }
    
        fwrite(shovel, sizeof(shovel[0]), sizeof(shovel)/sizeof(shovel[0]), fp);
    
        int val = FS_IMMUTABLE_FL;
        if (ioctl(fileno(fp), FS_IOC_SETFLAGS, &val) < 0)
            perror("ioctl(2) error");
    
        fclose(fp);
    
        return 0;
    }
    

提交回复
热议问题