Chinaunix首页 | 论坛 | 博客
  • 博客访问: 543044
  • 博文数量: 83
  • 博客积分: 6010
  • 博客等级: 准将
  • 技术积分: 1169
  • 用 户 组: 普通用户
  • 注册时间: 2007-04-29 22:34
文章分类

全部博文(83)

文章存档

2011年(3)

2010年(29)

2009年(30)

2008年(21)

我的朋友

分类: LINUX

2009-03-21 18:53:56

看了下apue,搜了下,发现进程间通信可以用unix-socket和sendmsg,recvmsg来做。

#include <sys/socket.h>
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include <dirent.h>
#include <sys/stat.h>
#include <signal.h>
#include <sys/wait.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

#include <stropts.h>
#define CONTROLLEN sizeof (struct cmsghdr) + sizeof (int)

int fd[2];

void child()
{
    int file;
    if ((file = open("1", O_RDONLY)) < 0) {
        perror("open file failed");
        exit(-2);
    }
    printf("fd = %d\n", file);
   
    char tmpbuf[CONTROLLEN];
     struct cmsghdr *cmptr = (struct cmsghdr *) tmpbuf;
    struct iovec iov[1];
     struct msghdr msg;
     char buf[1];
     iov[0].iov_base = buf;
    iov[0].iov_len = 1;
     msg.msg_iov = iov;
     msg.msg_iovlen = 1;
     msg.msg_name = NULL;
     msg.msg_namelen = 0;
     msg.msg_control = cmptr;
     msg.msg_controllen = CONTROLLEN;
     cmptr->cmsg_level = SOL_SOCKET;
     cmptr->cmsg_type = SCM_RIGHTS;
     cmptr->cmsg_len = CONTROLLEN;
     *(int *)CMSG_DATA (cmptr) = file;
 
      if (sendmsg(fd[1], &msg, 0) != 1) {
           perror("sendmsg failed");
        exit(-1);
     }
    exit(0);
}

int main()
{
    //int socketpair(int domain, int type, int protocol, int sockfd[2]);
    if (socketpair(AF_UNIX/* or AF_LOCAL*/, SOCK_STREAM, 0, fd) != 0) {
        perror("socketpair failed");
        return(-1);
    }
    /*if (pipe(fd) < 0) {
        perror("pipe failed");
        return -2;
    }*/

    pid_t pid;
    if ((pid = fork()) == 0 ){
        child();
    }

    char tmpbuf[CONTROLLEN];
     struct cmsghdr *cmptr = (struct cmsghdr *) tmpbuf;
     struct iovec iov[1];
     struct msghdr msg;
     char buf[1];
     iov[0].iov_base = buf;
     iov[0].iov_len = sizeof (buf);
     msg.msg_iov = iov;
     msg.msg_iovlen = 1;
     msg.msg_name = NULL;
     msg.msg_namelen = 0;
     msg.msg_control = cmptr;
     msg.msg_controllen = CONTROLLEN;

    wait(NULL);
      if (recvmsg(fd[0], &msg, 0) <= 0) {1
        perror("recvmsg failed");
        exit(-2);
    }
    int recvfd = *(int *) CMSG_DATA (cmptr);
    printf("recvfd = %d\n", recvfd);
    char tmp[256];
    u_int count;
    if ((count = read(recvfd, tmp, sizeof(tmp))) < 0) {
        perror("read failed\n");
        return -2;
    }
    tmp[count] = 0;
    printf("have read: %s\n", tmp);
    return 0;
}


apue上还说可以用ioctl(S_SENDFD)来做,不过我没试成功,代码如下:

#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include <dirent.h>
#include <sys/stat.h>
#include <signal.h>
#include <sys/wait.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

#include <stropts.h>
int fd[2];

int
s_pipe(int fd[2])
{
    return(pipe(fd));
}

void child()
{
        int sfd;
        if ((sfd = open("test.c", O_RDONLY)) < 0) {
                perror("open failed");
                exit(-1);
        }
  if (ioctl(fd[1], I_SENDFD, sfd) < 0) {
          perror("ioctl send failed");
          exit(-1);
  }
        close(sfd);
        exit(-1);
}

int main()
{

        pid_t pid;
        if (s_pipe(fd) < 0) {
                perror("pipe failed");
                exit(-1);
        }
        if ((pid = fork()) < 0) {
                perror("fork error");
                exit(-1);
  }
  else if (pid == 0) { /* child */
    close(fd[0]);
    sleep(3);
    child();
        }
  else
          close(fd[1]); /* parent */
                  
        struct strrecvfd recvfd;
        if (ioctl(fd[0], I_RECVFD, &recvfd) < 0) {
                perror("ioctl recv failed");
    return(-1);
  }
        int rfd = recvfd.fd;
        printf("rfd = %d\n", rfd);
       
        return 0;
}

阅读(1054) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~