Re: [PATCH x86_64] Live Patching Function on 2.6.11.7
From: Chris Wedgwood
Date: Wed Apr 20 2005 - 03:28:38 EST
On Wed, Apr 20, 2005 at 04:57:31PM +0900, Takashi Ikebe wrote:
> hmm.. most internet base services will use TCPv4 TCPv6 SCTP...
> AF_UNIX can not use as inter-nodes communication.
You can send file descriptors (the actually file descriptors
themselves, not their contents) to another process over a socket.
A nearly ten-year old example is attached (ie. this isn't new or
magical or specific to Linux).
/* sendfd.c - v. crude example of passing fds */
/*
* I tested this on HPUX10 using gcc -D_XOPEN_SOURCE_EXTENDED sendfd.c -lxnet
*
* Expected output is "hello world"
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
/* Note: msg_control may be msg_accrights, etc. */
int sendfd(int conn, int fd)
{
size_t len = sizeof(struct cmsghdr) + sizeof(int);
struct cmsghdr *hdr = (struct cmsghdr *)malloc(len);
struct msghdr msg;
int rc;
hdr->cmsg_len = len;
hdr->cmsg_level = SOL_SOCKET;
hdr->cmsg_type = SCM_RIGHTS;
*(int *)CMSG_DATA(hdr) = fd;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = NULL;
msg.msg_iovlen = 0;
msg.msg_control = hdr;
msg.msg_controllen = len;
rc = sendmsg(conn, &msg, 0);
free(hdr);
return rc;
}
int recvfd(int conn)
{
size_t len = sizeof(struct cmsghdr) + sizeof(int);
struct cmsghdr *hdr = (struct cmsghdr *)malloc(len);
struct msghdr msg;
int rc;
msg.msg_iov = NULL;
msg.msg_iovlen = 0;
msg.msg_control = hdr;
msg.msg_controllen = len;
rc = recvmsg(conn, &msg, 0);
if (rc >= 0
&& hdr->cmsg_len == len
&& hdr->cmsg_level == SOL_SOCKET
&& hdr->cmsg_type == SCM_RIGHTS)
{
int fd = *(int *)CMSG_DATA(hdr);
free(hdr);
return fd;
}
free(hdr);
return -1;
}
int main()
{
int fds[2];
int fd = -1;
int rc = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
pid_t pid;
if (rc)
{
perror("socketpair");
return 1;
}
/* punt */
system("echo hello world >testfile");
switch (pid = fork())
{
case 0:
// open this in the child proc
fd = open("testfile",O_RDONLY);
if (fd < 0)
perror("open(testfile)");
rc = sendfd(fds[1], fd);
if (rc)
perror("sendfd");
_exit(0);
case -1:
perror("fork");
return 1;
default:
waitpid(pid,NULL,0);
}
fd = recvfd(fds[0]);
if (fd < 0)
{
perror("recvfd");
return 1;
}
close(fds[0]);
close(fds[1]);
dup2(fd,0);
close(fd);
execl("/bin/cat","cat",NULL);
}