Why is ioctl() not blocking?
Question
I have written code for passing file descriptors between unrelated processes using streams. The server should wait for the client to send a file descriptor. Here is the server code:
#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);
}
But I receive the error number 9 - Bad file descriptor.
Solution
You don't mention what OS you are running. I_RECVFD is part of the STREAMS extensions which are normally only present in System V based Unixy operating systems (AIX and Solaris for example). Others, like Linux and BSD, do not support it and probably never will as Posix now has an alternative using sendmsg() and recvmsg().
I'm afraid that I don't know why Linux has #defines I_RECVFD if it does not support it.
OTHER TIPS
NB: the question has been extensively modified since this answer was written.
Where to begin?
main()
returns anint
.pipefd
is not initialized.- You close a random file descriptor.
- You call
recvfd()
on another random file descriptor. - You don't return a value from
main()
. - You don't use the
#define
value. - You don't show the
#include
files needed to make this compile. - Unused variable
fd
. - Unused variable
statbuf
. - Unchecked return value
i
.
Basic problem - use of uninitialized variables.
Subsidiary problem - limited error checking.
Additional problem: conceptually, you want a server that can be passed a file descriptor. You need that server to be reading from a file descriptor that other (unrelated) processes can create. You will need to look at the manuals rather carefully, but will probably need the server listening on a Unix-domain socket, or perhaps reading on a (named) FIFO. Other programs can then open the socket or FIFO and send their own file descriptor to the server.
Is this the actual code ? Cause nowhere do you create or receive a valid filedescriptor.
You never initialize pipefd
! Missing a
pipe(pipefd);
line before the close
call...?