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?
risposta
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 *
.
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
@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
Aha. Grazie ancora! – Siddhant
possibile duplicato di [sys_readlink non riuscito EFAULT - alternativa] (http://stackoverflow.com/questions/8216871/sys-readlink-fails-efault-alternative) – ephemient