2011-11-23 3 views
13

Ho bisogno di ottenere il nome di un file da un determinato descrittore di file, all'interno di un piccolo modulo del kernel linux che ho scritto. Ho provato la soluzione fornita a Getting Filename from file descriptor in C, ma per qualche ragione, stampa i valori obsoleti (sull'uso di readlink su /proc/self/fd/NNN come menzionato nella soluzione). Come posso farlo?Come posso ottenere un nome file da un descrittore di file all'interno di un modulo del kernel?

+0

possibile duplicato di [sys_readlink non riuscito EFAULT - alternativa] (http://stackoverflow.com/questions/8216871/sys-readlink-fails-efault-alternative) – ephemient

risposta

21

Non chiamare SYS_readlink - utilizzare lo stesso metodo utilizzato da procfs quando viene letto uno di questi collegamenti. Inizia con il codice proc_pid_readlink() e proc_fd_link() in fs/proc/base.c.

In generale, dato un int fd e un struct files_struct *files dal compito che ti interessa (che avete preso un riferimento a), si vuole fare:

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

Se il codice è in esecuzione in processo- contesto (ad esempio invocato tramite syscall) e il descrittore di file proviene dal processo corrente, quindi è possibile utilizzare current->files per l'attività corrente struct files_struct *.

+0

Nice. Ha funzionato. Grazie! Domanda veloce però. Quale scopo servono le chiamate 'path_get' e' path_put' (perché la loro rimozione non ha molto effetto sul mio programma)? Inoltre, qualche idea sul perché 'sys_readlink' non funzioni? – Siddhant

+1

@Siddhant: le chiamate 'path_get()' e 'path_put()' sono richieste per la correttezza, perché appuntano il percorso in modo che non vada via mentre stai provando a lavorare con esso (tutto il 'struct path' contiene una coppia di puntatori, a 'struct vfsmount' e a' struct dentry'). – caf

+0

Aha. Grazie ancora! – Siddhant