Example.No.1:
通过socketpair打开两个连接起来的Unix套接字,一个用于进程本身读取内容,并输出到进程本身的标准输出,另一个则用于子进程传递通过Unix套接字发送excel的一个进程打开的文件描述符,通过sendmsg的辅助数据传递
进程本身代码:
#include <stdio.h>@H_301_7@
#include <stdlib.h>@H_301_7@
#include <sys/socket.h>@H_301_7@
#include <unistd.h>@H_301_7@
#include <string.h>@H_301_7@
#include <errno.h>@H_301_7@
#include <sys/wait.h>@H_301_7@
#include <fcntl.h>@H_301_7@
#define BUFSIZE 4096@H_301_7@
int@H_301_7@ read_fd(int@H_301_7@ fd,void@H_301_7@* ptr,size_t nbytes,int@H_301_7@* recvfd ) {
struct@H_301_7@ msghdr msg;
struct@H_301_7@ iovec iov[1@H_301_7@];
ssize_t n;
union@H_301_7@ {
struct@H_301_7@ cmsghdr cm;
char@H_301_7@ control[CMSG_SPACE(sizeof@H_301_7@(int@H_301_7@))];
}control_un;
msg.msg_control = control_un.control;
msg.msg_controllen = sizeof@H_301_7@(control_un.control);
msg.msg_name = NULL;
msg.msg_namelen = 0@H_301_7@;
iov[0@H_301_7@].iov_base = ptr;
iov[0@H_301_7@].iov_len = nbytes;
msg.msg_iov = iov;
msg.msg_iovlen = 1@H_301_7@;
if@H_301_7@ ((n = recvmsg(fd,&msg,0@H_301_7@)) <= 0@H_301_7@) {
return@H_301_7@ n;
}
struct@H_301_7@ cmsghdr* cmptr;
if@H_301_7@ ((cmptr = CMSG_FIRSTHDR(&msg)) != NULL && cmptr->cmsg_len == CMSG_LEN(sizeof@H_301_7@(int@H_301_7@))) {
if@H_301_7@ (cmptr->cmsg_level != SOL_SOCKET) {
printf@H_301_7@("control level != SOL_SOCKET\n"@H_301_7@);
exit@H_301_7@(1@H_301_7@);
}
if@H_301_7@ (cmptr->cmsg_type != SCM_RIGHTS) {
printf@H_301_7@("control level != SCM_RIGHTS\n"@H_301_7@);
exit@H_301_7@(1@H_301_7@);
}
*recvfd = *(int@H_301_7@*)CMSG_DATA(cmptr);
}else@H_301_7@ {
*recvfd = -1@H_301_7@;
}
}
int@H_301_7@ my_open(char@H_301_7@* pathname,int@H_301_7@ mode) {
int@H_301_7@ fd,sockfd[2@H_301_7@],status;
char@H_301_7@ c;
if@H_301_7@ (socketpair(AF_LOCAL,SOCK_STREAM,0@H_301_7@,sockfd) < 0@H_301_7@) {
printf@H_301_7@("setsockpair error: %s\n"@H_301_7@,strerror(errno));
exit@H_301_7@(1@H_301_7@);
}
int@H_301_7@ childpid;
if@H_301_7@ ((childpid = fork()) < 0@H_301_7@) {
printf@H_301_7@("fork error: %s\n"@H_301_7@,strerror(errno));
exit@H_301_7@(1@H_301_7@);
}else@H_301_7@ if@H_301_7@ (childpid == 0@H_301_7@) {
char@H_301_7@ argsockfd[10@H_301_7@],argmode[10@H_301_7@];
snprintf@H_301_7@(argsockfd,sizeof@H_301_7@(argsockfd),"%d"@H_301_7@,sockfd[1@H_301_7@]);
snprintf@H_301_7@(argmode,sizeof@H_301_7@(argmode),mode);
execl("./openfile"@H_301_7@,"openfile"@H_301_7@,argsockfd,pathname,argmode,(char@H_301_7@*)NULL);
}
close(sockfd[1@H_301_7@]);
if@H_301_7@ (waitpid(childpid,&status,0@H_301_7@) < 0@H_301_7@) {
printf@H_301_7@("waitpid error: %s\n"@H_301_7@,strerror(errno));
exit@H_301_7@(1@H_301_7@);
}
if@H_301_7@ (WIFEXITED(status) == 0@H_301_7@) {
printf@H_301_7@("child process did not terminate\n"@H_301_7@);
exit@H_301_7@(1@H_301_7@);
}
if@H_301_7@ ((status = WEXITSTATUS(status)) == 0@H_301_7@) {
if@H_301_7@ (read_fd(sockfd[0@H_301_7@],&c,1@H_301_7@,&fd) < 0@H_301_7@) {
printf@H_301_7@("read_fd error\n"@H_301_7@);
exit@H_301_7@(1@H_301_7@);
}
}else@H_301_7@ {
errno = status;
fd = -1@H_301_7@;
}
close(sockfd[0@H_301_7@]);
return@H_301_7@ fd;
}
int@H_301_7@ main(int@H_301_7@ argc,char@H_301_7@** argv) {
if@H_301_7@ (argc != 2@H_301_7@) {
printf@H_301_7@("please add <pathname>\n"@H_301_7@);
exit@H_301_7@(1@H_301_7@);
}
int@H_301_7@ fd;
if@H_301_7@ ((fd = my_open(argv[1@H_301_7@],O_RDONLY)) < 0@H_301_7@) {
printf@H_301_7@("can't open %s\n"@H_301_7@,argv[1@H_301_7@]);
exit@H_301_7@(1@H_301_7@);
}
char@H_301_7@ buf[BUFSIZE];
int@H_301_7@ n;
while@H_301_7@ ((n = read(fd,buf,BUFSIZE)) > 0@H_301_7@) {
if@H_301_7@ (write(STDOUT_FILENO,n) != n) {
printf@H_301_7@("write error: %s\n"@H_301_7@,strerror(errno));
exit@H_301_7@(1@H_301_7@);
}
}
return@H_301_7@ 0@H_301_7@;
}
openfile进程代码:
#include <stdio.h>@H_301_7@
#include <stdlib.h>@H_301_7@
#include <unistd.h>@H_301_7@
#include <sys/socket.h>@H_301_7@
#include <fcntl.h>@H_301_7@
#include <string.h>@H_301_7@
#include <errno.h>@H_301_7@
int@H_301_7@ write_fd(int@H_301_7@ fd,int@H_301_7@ sendfd) {
struct@H_301_7@ msghdr msg;
struct@H_301_7@ iovec iov[1@H_301_7@];
union@H_301_7@ {
struct@H_301_7@ cmsghdr cmsg;
char@H_301_7@ controls[CMSG_SPACE(sizeof@H_301_7@(int@H_301_7@))];
}control_un;
msg.msg_name = NULL;
msg.msg_namelen = 0@H_301_7@;
msg.msg_control = control_un.controls;
msg.msg_controllen = sizeof@H_301_7@(control_un.controls);
struct@H_301_7@ cmsghdr* cmptr;
cmptr = CMSG_FIRSTHDR(&msg);
cmptr->cmsg_len = CMSG_LEN(sizeof@H_301_7@(int@H_301_7@));
cmptr->cmsg_level = SOL_SOCKET;
cmptr->cmsg_type = SCM_RIGHTS;
*(int@H_301_7@*)(CMSG_DATA(cmptr)) = sendfd;
iov[0@H_301_7@].iov_base = ptr;
iov[0@H_301_7@].iov_len = nbytes;
msg.msg_iov = iov;
msg.msg_iovlen = 1@H_301_7@;
return@H_301_7@ sendmsg(fd,0@H_301_7@);
}
int@H_301_7@ main(int@H_301_7@ argc,char@H_301_7@** argv) {
if@H_301_7@ (argc != 4@H_301_7@) {
printf@H_301_7@("please check your input-arguments\n"@H_301_7@);
exit@H_301_7@(1@H_301_7@);
}
int@H_301_7@ fd;
if@H_301_7@ ((fd = open(argv[2@H_301_7@],atoi(argv[3@H_301_7@]))) < 0@H_301_7@) {
printf@H_301_7@("open %s fail: error reason: %s\n"@H_301_7@,argv[2@H_301_7@],strerror(errno));
exit@H_301_7@(1@H_301_7@);
}
int@H_301_7@ n;
if@H_301_7@ ((n = write_fd(atoi(argv[1@H_301_7@]),""@H_301_7@,fd)) < 0@H_301_7@) {
exit@H_301_7@(n);
}
exit@H_301_7@(0@H_301_7@);
}