Re: [PATCH x86_64] Live Patching Function on 2.6.11.7

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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);
}

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux