Я думал, что это невозможно, но на самом деле есть способ, по крайней мере для простых случаев, когда у нас нет дубликатов файловых дескрипторов для одного сокета.Я отвечаю на свой вопрос, надеясь, что это поможет людям.
int get_sockfd(struct sock *sk)
{
int sockfd;
unsigned int i;
struct files_struct *current_files;
struct fdtable *files;
struct socket *sock;
struct file *sock_filp;
sockfd = -1;
sock = sk->sk_socket;
sock_filp = sock->file;
current_files = current->files;
files = files_fdtable(current_files);
for (i = 0; files->fd[i] != NULL; i++) {
if (sock_filp == files->fd[i]) {
sockfd = i;
break;
}
}
return sockfd;
}
Вы, конечно, захотите проверить NULL-указатели, начиная с struct sock *sk
, переданного в параметре.
Итак, в принципе, идея заключается в том, что числовое значение дескриптора файла (в конце концов, sockfd - это обычный дескриптор файла) соответствует индексу соответствующей записи в таблице открытых файлов процесса.Все, что нам нужно делать, когда указатель struct sock *sk
- это цикл по таблице открытых файлов текущего процесса, пока адреса, на которые указывает sk->sk_socket->file
, не совпадут с записью в таблице.