Почему ioctl () не блокируется? - PullRequest
0 голосов
/ 07 июня 2009

Я написал код для передачи файловых дескрипторов между несвязанными процессами с использованием потоков. Сервер должен ждать, пока клиент отправит дескриптор файла. Вот код сервера:

#include <sys/types.h>   
#include <sys/stat.h>  
#include <fcntl.h>  
#include <stropts.h>  
#include <stdio.h>  
#include <errno.h>  
#include <unistd.h>  

int  main(int argc, char *argv[])
{  
    int fd;  
    int pipefd[2];  
    pipe(pipefd);  
    close(pipefd[1]);  
    recvfd(pipefd[0]);  
    return 0;
}

void recvfd(int p)  
{
    struct strrecvfd rfdbuf;  
    struct stat statbuf;   
    int i;  
    i=ioctl(p, I_RECVFD, &rfdbuf);  
    printf("errno=%d\n",errno);  
    printf("recvfd=%d\n", rfdbuf.fd);  
}

Но я получаю ошибку № 9 - Неверный дескриптор файла.

Ответы [ 4 ]

2 голосов
/ 08 июня 2009

Вы не упоминаете, какую ОС вы используете. I_RECVFD является частью расширений STREAMS, которые обычно присутствуют только в операционных системах Unixy на основе System V (например, AIX и Solaris). Другие, такие как Linux и BSD, не поддерживают его и, вероятно, никогда не поддержат, поскольку у Posix теперь есть альтернатива с использованием sendmsg () и recvmsg ().

Боюсь, я не знаю, почему в Linux есть #defines I_RECVFD, если он не поддерживает его.

2 голосов
/ 07 июня 2009

Примечание: вопрос был значительно изменен с момента написания этого ответа.


С чего начать?

  • main() возвращает int.
  • pipefd не инициализирован.
  • Вы закрываете случайный файловый дескриптор.
  • Вы вызываете recvfd() для другого случайного файлового дескриптора.
  • Вы не возвращаете значение из main().
  • Вы не используете значение #define.
  • Вы не показываете #include файлы, необходимые для компиляции.
  • Неиспользуемая переменная fd.
  • Неиспользуемая переменная statbuf.
  • Не проверяемое возвращаемое значение i.

Основная проблема - использование неинициализированных переменных.

Дополнительная проблема - ограниченная проверка ошибок.


Дополнительная проблема: концептуально вам нужен сервер, которому можно передать дескриптор файла. Вам нужен этот сервер для чтения из файлового дескриптора, который могут создавать другие (не связанные) процессы. Вам нужно будет внимательно изучить руководства, но, возможно, потребуется сервер, прослушивающий сокет домена Unix или, возможно, читающий (именованный) FIFO. Затем другие программы могут открыть сокет или FIFO и отправить собственный дескриптор файла на сервер.

0 голосов
/ 07 июня 2009

Вы никогда не инициализируете pipefd! Отсутствует

pipe(pipefd);

линия до close вызова ...?

0 голосов
/ 07 июня 2009

Это действительный код? Потому что нигде вы не создаете и не получаете действительный дескриптор файла.

...