在C中使用ioctl()设置不可变标志
我试图创建一个创建文件的脚本,然后将其设置为不可变的,类似于linux的chattr +i
命令。 脚本编译 (使用gcc), 运行并创建文件 。 但是文件本身不是不可变的,可以使用简单的rm -f
删除 。 我试图在chattr
调用chattr
地方找到一个名为ioctl
的函数。 然后,我使用了我可以收集的一些小信息,并提出了我在下面的内容。 我从ext2_fs.h
缩小了它,但它似乎不起作用。 我显然忽视了一些事情。
对上一个条目的更新 : 编译但在ioctl()函数上返回-1 。 perror()显示错误的地址 。
#include #include #include #include #include int main() { FILE *fp; char shovel[16] = "I have a shovel!"; fp = fopen("/shovel.txt", "w+"); fwrite(shovel, sizeof(shovel[0]), sizeof(shovel)/sizeof(shovel[0]), fp); ioctl(fileno(fp), FS_IOC_SETFLAGS, 0x00000010); fclose(fp); }
任何帮助赞赏。
主要问题是ioctl
想要一个指向掩码的指针 ,而不是直接常量。 您必须定义一个int变量,将掩码( 0x10
)存储在其中并将其地址作为ioctl
第三个参数传递。
另外,我会添加一些提示:
- 其他更改属性的程序用于直接使用低级I / O(打开,关闭…)。 此外,该文件通常使用
O_RDONLY
打开。 - 使用
FS_IMMUTABLE_FL
不是原始常量。 - 首先获取当前属性掩码(
FS_IOC_SETFLAGS
)并使用新标志对其进行掩码,以便服务不会丢失其他设置。
您正在使用正确的ioctl命令,但是您传递了错误的参数。
ioctl_list(2)
的联机帮助页显示FS_IOC_SETFLAGS
期望接收指向int
( int *
)的指针,但是您传递的是整数文字(因此是Bad Address错误)。
你不做任何错误检查的事实也没有帮助。
传递给FS_IOC_SETFLAGS
的正确标志是一个保存值EXT2_IMMUTABLE_FL
的指针,该值在ext2fs/ext2_fs.h
定义(一些较旧/不同的Linux发行版似乎在linux/ext2_fs.h
),所以你需要#include
。 确保安装e2fslibs-dev
(可能你也需要linux-headers)。
这段代码有效:
#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; }
记得以root身份运行它。
更新 :
正如Giuseppe Guerrini在他的回答中建议的那样,您可能想要使用FS_IMMUTABLE_FL
,而您不需要包含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; }