2015-09-08 73 views
2

我試圖做的是創建一個文件腳本中使用的ioctl(),然後將其設置爲不可變的類似於linux下chattr +i命令。 腳本編譯(與海灣合作委員會),運行文件被創建。然而,文件本身並不是一成不變的,可以用一個簡單的rm -f除去。我試圖堆棧跟蹤chattr被調用,並且我找到了一個叫ioctl的函數。然後,我使用了我可以收集的一些小信息,並提出了下面的內容。我從ext2_fs.h縮小了它,但它似乎並不工作。我顯然忽略了一些東西。設置不可變的標誌用C

更新一個條目編譯返回-1的ioctl()函數。 錯誤地址perror()一起顯示。

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/stat.h> 
#include <sys/ioctl.h> 
#include <linux/fs.h> 

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); 
} 

任何幫助表示讚賞。

+4

爲什麼你認爲'ioctl'成功?怎麼樣測試返回值? – Jens

+0

你是否以root身份運行? –

+0

是的,以根用戶身份運行並且返回值爲-1 – user2425108

回答

2

主要問題是ioctl想要一個指針指向的掩碼,而不是一個直接常量。您必須定義一個int變量,將掩碼(0x10)存儲在其中,並將其地址作爲ioctl的第三個參數傳遞。

另外,我想補充一些提示:

  • 其他方案,以改變屬性來使用低級別的I/O直接連接(開,關...)。此外,該文件通常以O_RDONLY打開。使用FS_IMMUTABLE_FL是原始常數。
  • 獲取當前屬性第一蔽光(FS_IOC_SETFLAGS),並與新的標誌掩蓋它,所以其他設置服務不丟失。
+0

有趣。我的印象是「EXT2_IMMUTABLE_FL」是正確的標誌,但是「FS_IMMUTABLE_FL」似乎也是正確的,並且具有不需要包括「ext2_fs.h」的好的副作用(這可能是一種痛苦,沒有安裝正確的軟件包)。很好的答案! –

+0

這個技巧。我實際上將其追溯到FS_IMMUTABLE_FL,並將其定義爲0x10。如果我更徹底地檢查了聯機幫助頁,我會注意到這一點,而不會陷入這種困境。最後可以在今晚不睡覺的情況下入睡。 – user2425108

2

您正在使用正確的ioctl命令,但是您傳遞了錯誤的參數。

ioctl_list(2)的手冊頁顯示,FS_IOC_SETFLAGS預計將收到一個指向int(一int *),但你傳遞它字面的整數(因此錯誤地址錯誤)。

事實上,你不檢查任何錯誤也沒有幫助。

正確的標誌傳遞給FS_IOC_SETFLAGS是持有價值EXT2_IMMUTABLE_FL,這是在ext2fs/ext2_fs.h定義一個指針(一些舊的/不同的Linux發行似乎有它linux/ext2_fs.h下),所以你需要#include <ext2fs/etx2_fs.h>。確保安裝了e2fslibs-dev(也許你還需要linux-headers)。

此代碼工作:

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/stat.h> 
#include <sys/ioctl.h> 
#include <linux/fs.h> 
#include <ext2fs/ext2_fs.h> 

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; 
} 

記住運行此爲根。

UPDATE

由於Giuseppe Guerrinihis answer建議,您可能需要使用FS_IMMUTABLE_FL相反,你會不會需要包括ext2_fs.h

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/stat.h> 
#include <sys/ioctl.h> 
#include <linux/fs.h> 

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; 
} 
+0

欣賞代碼庫。在這個例子中沒有錯誤處理,因爲它是我知道事先工作的更大代碼庫的一部分。我只是縮短了它,使它更容易理解我試圖完成的任務,而不用浪費人們時間的無關代碼淹沒主題。截至目前,它是完美整合和完美工作的。非常感謝。 – user2425108