Send socket descriptors to child processes
From: Jo (JoJoTwilligo_at_hotmail.com)
Date: 09/28/04
- Next message: Jan Engelhardt: "Re: I need help parsing dhcp.conf file"
- Previous message: Thomas Keller: "Re: Linux C++ IDE"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 27 Sep 2004 20:45:34 -0700
I'm very confused about all these routines that are supposed to be
able to pass open descriptors to other processes. I've been reading
the man pages on recvmsg, sendmsg, socketpair, cmsg(3) and unix(7),
and this is the best I've come up with:
void SendNewSocket(int desChild, int desNewSocket) {
char test[] = "this message is received; the socket is good";
write(desNewSocket, test, strlen(test)+1);
struct msghdr msg = {0}; //took this block from man 3 cmsg
struct cmsghdr *cmsg;
char buf[CMSG_SPACE(sizeof desNewSocket)]; /* ancillary data buffer
*/
int *fdptr;
msg.msg_control = buf;
msg.msg_controllen = sizeof buf;
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
/* Initialize the payload: */
fdptr = (int *)CMSG_DATA(cmsg);
memcpy(fdptr, &desNewSocket, sizeof(desNewSocket));
/* Sum of the length of all control messages in the buffer: */
msg.msg_controllen = cmsg->cmsg_len;
sendmsg(desChild, &msg, 0);
}
The only time the ancilliary descriptors are used outside of the code
here, is in select and close (which, of course, is not called before
any of this code is called). Sendmsg here always returns 0. This means
the receiving code hasn't been tested yet, but here it is anyway:
int GetNewSocket(int desAncil) {
struct msghdr msgHdr;
recvmsg(desAncil, &msgHdr, 0);
struct cmsghdr *cHdr = (struct cmsghdr *)msgHdr.msg_control;
char *pFDChar = (char *)CMSG_DATA(cHdr);
int *pFDInt = (int *)pFDChar;
return *pFDInt;
}
The creation of the ancilliary descriptors is nothing to look at, but
if you want to:
void Fork(int &desAncil) {
int desAncil[2];
socketpair(PF_UNIX, SOL_SOCKET, 0, desAncils);
pid_t nPid = fork();
switch (nPid) {
case 0: //child
close(desAncils[1]);
desAncil = desAncils[0];
default: { //parent
close(desAncils[0]);
desAncil = desAncils[1];
}
}
Is all this correct?
- Next message: Jan Engelhardt: "Re: I need help parsing dhcp.conf file"
- Previous message: Thomas Keller: "Re: Linux C++ IDE"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]