2009-06-07 192 views
0

我已經編寫了用於在使用流的無關進程之間傳遞文件描述符的代碼。 服務器應等待客戶端發送文件描述符。 這裏是服務器代碼:爲什麼ioctl()不阻塞?

#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 - 錯誤的文件描述符。

+0

您使用的是什麼操作系統?在不知道操作系統的情況下很難回答有關操作系統調用的問題。 – Dipstick 2009-06-07 20:33:47

+0

你爲什麼認爲它返回一個錯誤?該代碼甚至不檢查ioctl返回值。如果它不是-1,則errno不會更改,並且可能具有先前系統調用的值(例如,在動態加載器或啓動例程中)。 – mark4o 2009-06-07 21:42:17

回答

2

你沒有提到你正在運行的操作系統。 I_RECVFD是STREAMS擴展的一部分,通常只存在於基於System V的Unixy操作系統(例如AIX和Solaris)中。其他人,如Linux和BSD,不支持它,並且可能永遠不會,因爲Posix現在有使用sendmsg()和recvmsg()的替代方案。

恐怕我不知道爲什麼Linux有#defines I_RECVFD如果它不支持它。

0

這是實際的代碼嗎? 您無法創建或接收有效的filedescriptor。

2

注:自該答案寫入以來,該問題已被廣泛修改。


從哪裏開始?

  • main()返回int
  • pipefd未初始化。
  • 您關閉一個隨機文件描述符。
  • 您在另一個隨機文件描述符上調用recvfd()
  • 您不會從main()返回值。
  • 您不使用#define值。
  • 您不顯示進行此編譯所需的#include文件。
  • 未使用的變量fd
  • 未使用的變量statbuf
  • 未經檢查的返回值i

基本問題 - 使用未初始化的變量。

輔助問題 - 有限的錯誤檢查。


附加問題:在概念上,您需要一個可以傳遞文件描述符的服務器。您需要該服務器從文件描述符中讀取其他(不相關的)進程可以創建的文件描述符。您需要仔細查看手冊,但可能需要服務器在Unix域套接字上進行偵聽,或者可能需要在(命名的)FIFO上進行讀取。然後其他程序可以打開套接字或FIFO並將它們自己的文件描述符發送到服務器。

+0

從技術上講,可以省略main()的返回類型(但對於main _only_),在這種情況下,假定爲'int'。同樣,可以省略main(也是main _only_)中的return語句,在這種情況下存在隱式的「返回0」。儘管如此,這仍然是不好的做法。 – 2009-06-07 20:00:29

0

你永遠不會初始化pipefd!缺少一個

pipe(pipefd); 

線前close打電話...?

相關問題