2011-11-23 25 views
13

Tôi cần lấy tên của tệp từ một bộ mô tả tệp đã cho, bên trong mô-đun hạt nhân Linux nhỏ mà tôi đã viết. Tôi đã thử các giải pháp được đưa ra tại Getting Filename from file descriptor in C, nhưng vì một số lý do, nó in ra các giá trị rác (sử dụng readlink trên /proc/self/fd/NNN như đã đề cập trong giải pháp). Tôi làm nó như thế nào?Làm cách nào để lấy tên tệp từ bộ mô tả tệp bên trong mô-đun hạt nhân?

+0

có thể trùng lặp của [sys_readlink không thành công EFAULT - thay thế] (http://stackoverflow.com/questions/8216871/sys-readlink-fails-efault-alternative) – ephemient

Trả lời

21

Không gọi SYS_readlink - sử dụng cùng phương thức procfs khi nào một trong các liên kết đó được đọc. Bắt đầu bằng mã trong proc_pid_readlink()proc_fd_link() trong fs/proc/base.c.

chung, đưa ra một int fdstruct files_struct *files từ công việc bạn đang quan tâm (mà bạn đã thực hiện một tham chiếu đến), bạn muốn làm:

char *tmp; 
char *pathname; 
struct file *file; 
struct path *path; 

spin_lock(&files->file_lock); 
file = fcheck_files(files, fd); 
if (!file) { 
    spin_unlock(&files->file_lock); 
    return -ENOENT; 
} 

path = &file->f_path; 
path_get(path); 
spin_unlock(&files->file_lock); 

tmp = (char *)__get_free_page(GFP_KERNEL); 

if (!tmp) { 
    path_put(path); 
    return -ENOMEM; 
} 

pathname = d_path(path, tmp, PAGE_SIZE); 
path_put(path); 

if (IS_ERR(pathname)) { 
    free_page((unsigned long)tmp); 
    return PTR_ERR(pathname); 
} 

/* do something here with pathname */ 

free_page((unsigned long)tmp); 

Nếu mã của bạn đang chạy trong process- ngữ cảnh (ví dụ: được gọi thông qua một syscall) và bộ mô tả tập tin là từ quá trình hiện tại, sau đó bạn có thể sử dụng current->files cho nhiệm vụ hiện tại struct files_struct *.

+0

Tốt. Điều đó hiệu quả. Cảm ơn! Câu hỏi nhanh. Các cuộc gọi 'path_get' và' path_put' có mục đích gì (vì việc loại bỏ chúng không có nhiều ảnh hưởng đến chương trình của tôi)? Ngoài ra, bất kỳ ý tưởng tại sao 'sys_readlink' không hoạt động? – Siddhant

+1

@Siddhant: Các cuộc gọi 'path_get()' và 'path_put()' là bắt buộc đối với tính chính xác, vì chúng ghim đường dẫn sao cho nó không biến mất trong khi bạn đang cố gắng làm việc với nó (tất cả đường dẫn 'struct' contains là một cặp con trỏ, tới 'struct vfsmount' và' struct dentry'). – caf

+0

Aha. Cảm ơn một lần nữa! – Siddhant

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