Für jeden Prozess gibt es eine Tabelle von Datei-Deskriptoren, die Dateideskriptoren struct file
Objekte abbildet. Sie können mit der Funktion iterate_fd()
über diese Tabelle iterieren.
Für jede struct file
können Sie bestimmen, welches struct sock
Objekt entspricht sock_from_file()
Funktion entspricht.
Insgesamt:
/*
* Callback for iterate_fd().
*
* If given file corresponds to the given socket, return fd + 1.
* Otherwise return 0.
*
* Note, that returning 0 is needed for continue the search.
*/
static int check_file_is_sock(void* s, struct file* f, int fd)
{
int err;
struct sock* real_sock = sock_from_file(f, &err);
if(real_sock == s)
return fd + 1;
else
return 0;
}
// Return file descriptor for given socket in given process.
int get_fd_for_sock(struct sock* s, struct task* p)
{
int search_res;
task_lock(p);
// This returns either (fd + 1) or 0 if not found.
search_res = iterate_fd(p->files, 0, &check_file_is_sock, s);
task_unlock(p);
if(search_res)
return search_res - 1;
else
return -1; // Not found
}
fd Zahlen existieren auf Basis pro Prozess nur, so ist es unklar, was tun müssen, wenn Sie nach einem fd im Kernel zu fragen. – Martin
@Martin, danke für einen Kommentar. Wenn ich ein 'struct sock'-Objekt habe, möchte ich wissen, welchem 'fd' im Userspace es entspricht. – Mark
Ich meine, du musst wahrscheinlich anders herum anfangen. Nehmen Sie die Dateideskriptortabelle eines bestimmten Prozesses, durchlaufen Sie sie und prüfen Sie, ob einige Datensätze auf den betreffenden Socket zeigen. Ein und derselbe Socket kann durch mehr fds in einer oder mehreren Benutzerraumaufgaben bezeichnet werden. (Sorry, keine detaillierte Antwort, wie ich es gerade jetzt machen könnte, da ich einige Details überprüfen müsste und jetzt keine Zeit mehr hätte, vielleicht später, wenn niemand schneller antworten wird.) – Martin