2013-01-25 28 views
9

Giả sử hệ điều hành là Linux. Giả sử tôi mở một tập tin để viết và nhận được một bộ mô tả tập tin fdw. Có thể lấy một bộ mô tả tập tin khác fdr, với quyền truy cập chỉ đọc vào tệp mà không cần gọi lại open nữa không? Lý do tôi không muốn gọi open là tệp cơ bản có thể đã bị di chuyển hoặc thậm chí không được liên kết trong hệ thống tệp bằng các quy trình khác, vì vậy việc sử dụng lại cùng một tên tệp không đáng tin cậy đối với các tác vụ đó. Vì vậy, câu hỏi của tôi là: là có anyway để mở một mô tả tập tin với quyền truy cập khác nhau nếu chỉ được đưa ra một bộ mô tả tập tin? dup hoặc dup2 không thay đổi quyền truy cập, tôi nghĩ vậy.Mở lại bộ mô tả tệp bằng quyền truy cập khác?

Trả lời

9

Có! Bí quyết là truy cập tệp đã xóa qua /proc/self/fd/n. Đó là một thủ thuật chỉ có Linux, theo như tôi biết.

Chạy chương trình này:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int main() { 
    FILE* out_file; 
    FILE* in_file; 
    char* dev_fd_path; 
    char buffer[128]; 

    /* Write “hi!” to test.txt */ 
    out_file = fopen("test.txt", "w"); 
    fputs("hi!\n", out_file); 
    fflush(out_file); 

    /* Delete the file */ 
    unlink("test.txt"); 

    /* Verify that the file is gone */ 
    system("ls test.txt"); 

    /* Reopen the filehandle in read-mode from /proc */ 
    asprintf(&dev_fd_path, "/proc/self/fd/%d", fileno(out_file)); 
    in_file = fopen(dev_fd_path, "r"); 
    if (!in_file) { 
     perror("in_file is NULL"); 
     exit(1); 
    } 
    printf("%s", fgets(buffer, sizeof(buffer), in_file)); 

    return 0; 
} 

Nó viết một số văn bản vào một tập tin, xóa nó, nhưng giữ cho bộ mô tả tập tin mở và và sau đó mở lại nó thông qua một con đường khác. Tệp không thực sự bị xóa cho đến khi quá trình cuối cùng giữ bộ mô tả tệp cuối cùng đóng và cho đến khi đó, bạn có thể xem nội dung tệp qua /proc.


Nhờ ông chủ cũ của tôi Anatoly đã dạy tôi mẹo này khi tôi xóa một số tệp quan trọng may mắn vẫn được nối thêm bởi một quy trình khác!

+0

Đó là gian lận kể từ khi ông nói rõ ràng "mà không gọi mở lại" - mặc dù tôi cho rằng nếu bạn thực sự muốn làm điều đó, đó là một hạn chế mà bạn sẽ thư giãn. Và anh ta có thể có nghĩa là "dù không gọi mở với cùng một con đường". – tvanfosson

+0

Cảm ơn. Câu trả lời tốt. –

+0

Có gì '/ dev/proc/fd/n', đó là lỗi đánh máy? Nó có vẻ là '/ proc/self/fd /% d' theo mã của bạn. – Mehrdad

5

Không, cuộc gọi fcntl sẽ không cho phép bạn đặt bit đọc/ghi trên bộ mô tả tệp mở và cách duy nhất để có bộ mô tả tệp mới từ bộ mô tả hiện có là sử dụng chức năng trùng lặp. Các cuộc gọi đến dup/dup2/dup3 (và fcntl) không cho phép bạn thay đổi chế độ truy cập tệp.

LƯU Ý: điều này đúng với Linux, nhưng không đúng đối với các Unix khác nói chung. Trong HP-UX, ví dụ: [xem (1)(2)] bạn có thể thay đổi bit đọc/ghi với fcntl bằng F_SETFL trên bộ mô tả tệp đang mở. Vì các bộ mô tả tệp được tạo bởi dup có cùng các cờ trạng thái, tuy nhiên, việc thay đổi chế độ truy cập cho một người nhất thiết sẽ thay đổi nó cho người khác.

+0

Cũng lưu ý rằng 'freopen' có chức năng tương tự cho các dòng' FILE * ', trong đó các chế độ truy cập có thể thay đổi hay không phụ thuộc vào việc triển khai hệ điều hành. – CMCDragonkai

Các vấn đề liên quan