UNIX域协议之描述符传递
一、mycat程序
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h> #define BUFFSIZE 4096 int my_open(const char *, int);
void err_sys(const char *, ...);
void err_quit(const char *, ...); int main(int argc, char **argv)
{
int fd, n;
char buff[BUFFSIZE]; if (argc != ) {
err_quit("usage: mycat <pathname>");
} if ( (fd = my_open(argv[], O_RDONLY)) < ) {
err_sys("cannot open %s", argv[]);
} while ( (n = read(fd, buff, BUFFSIZE)) > ) {
write(STDOUT_FILENO, buff, n);
} exit();
}
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/socket.h> void err_sys(const char *, ...);
void err_quit(const char *, ...);
ssize_t Read_fd(int, void *, size_t, int *); int my_open(const char *pathname, int mode)
{
int fd, sockfd[], status;
pid_t childpid;
char c, argsockfd[], argmode[]; socketpair:
if (socketpair(AF_LOCAL, SOCK_STREAM, , sockfd) == -) {
if (errno == EINTR) {
goto socketpair;
} else {
err_quit("socketpair failed to create stream pipe");
}
} if ( (childpid = fork()) == ) { /* child process */
close(sockfd[]);
snprintf(argsockfd, sizeof(argsockfd), "%d", sockfd[]);
snprintf(argmode, sizeof(argmode), "%d", mode);
execl("../openfile/openfile", "openfile", argsockfd,
pathname, argmode,(char *) NULL);
err_sys("execl error");
} close(sockfd[]); /* close the end we don't use */ waitpid(childpid, &status, ); if (WIFEXITED(status) == ) {
err_quit("child did not terminate");
}
if ( (status = WEXITSTATUS(status)) == ) {
Read_fd(sockfd[], &c, , &fd);
} else {
errno = status; /* set errno value from child's status */
fd = -;
} close(sockfd[]);
return (fd);
}
#include <stddef.h>
#include <sys/socket.h> void err_sys(const char *, ...);
void err_quit(const char *, ...); ssize_t read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)
{
struct msghdr msg;
struct iovec iov[];
ssize_t n; union {
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof(int))];
} control_un;
struct cmsghdr *cmptr; msg.msg_control = control_un.control;
msg.msg_controllen = sizeof(control_un.control); msg.msg_name = NULL;
msg.msg_namelen = ; iov[].iov_base = ptr;
iov[].iov_len = nbytes;
msg.msg_iov = iov;
msg.msg_iovlen = ; if ( (n = recvmsg(fd, &msg, )) <= ) {
return (n);
} if ( (cmptr = CMSG_FIRSTHDR(&msg)) != NULL &&
cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
if (cmptr->cmsg_level != SOL_SOCKET) {
err_quit("control level != SOL_SOCKET");
}
if (cmptr->cmsg_type != SCM_RIGHTS) {
err_quit("control type != SCM_RIGHTS");
}
*recvfd = *((int *) CMSG_DATA(cmptr));
} else {
*recvfd = -; /* descriptor was not passed */
} return(n);
} ssize_t Read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)
{
ssize_t n; if ( (n = read_fd(fd, ptr, nbytes, recvfd)) < ) {
err_sys("read_fd error");
} return (n);
}
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h> /* ANSI C header file */
#include <syslog.h> /* for syslog() */ #define MAXLINE 4096 int daemon_proc; /* set nonzero by daemon_init() */ static void err_doit(int, int, const char *, va_list); /* Nonfatal error related to system call
* Print message and return */ void err_ret(const char *fmt, ...) { va_list ap; va_start(ap, fmt);
err_doit(, LOG_INFO, fmt, ap);
va_end(ap);
return;
} /* Fatal error related to system call
* Print message and terminate */ void err_sys(const char *fmt, ...) { va_list ap; va_start(ap, fmt);
err_doit(, LOG_ERR, fmt, ap);
va_end(ap);
exit();
} /* Fatal error related to system call
* Print message, dump core, and terminate */ void err_dump(const char *fmt, ...) {
va_list ap; va_start(ap, fmt);
err_doit(, LOG_ERR, fmt, ap);
va_end(ap);
abort(); /* dump core and terminate */
exit(); /* shouldn't get here */
} /* Nonfatal error unrelated to system call
* Print message and return */ void err_msg(const char *fmt, ...) { va_list ap; va_start(ap, fmt);
err_doit(, LOG_INFO, fmt, ap);
va_end(ap);
return;
} /* Fatal error unrelated to system call
* Print message and terminate */ void err_quit(const char *fmt, ...) { va_list ap; va_start(ap, fmt);
err_doit(, LOG_ERR, fmt, ap);
va_end(ap);
exit();
} /* Print message and return to caller
* Caller specifies "errnoflag" and "level" */ static void err_doit(int errnoflag, int level, const char *fmt, va_list ap) { int errno_save, n;
char buf[MAXLINE + ]; errno_save = errno; /* value caller might want printed */
#ifdef HAVE_VSNPRINTF
vsnprintf(buf, MAXLINE, fmt, ap); /* safe */
#else
vsprintf(buf, fmt, ap); /* not safe */
#endif
n = strlen(buf);
if (errnoflag)
snprintf(buf + n, MAXLINE - n, ": %s", strerror(errno_save));
strcat(buf, "\n"); if (daemon_proc) {
syslog(level, buf);
} else {
fflush(stdout); /* in case stdout and stderr are the same */
fputs(buf, stderr);
fflush(stderr);
}
return;
}
二、openfile程序
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h> void err_quit(const char *, ...);
ssize_t Write_fd(int, void *, size_t, int); int main(int argc, char **argv)
{
int fd; if (argc != ) {
err_quit("openfile <sockfd> <filename> <mode>");
} if ( (fd = open(argv[], atoi(argv[]))) < ) {
exit( (errno > ) ? errno : );
} if (Write_fd(atoi(argv[]), "", , fd) < ) {
exit( (errno > ) ? errno : );
} exit();
}
#include <stddef.h>
#include <sys/socket.h> void err_sys(const char *, ...); ssize_t write_fd(int fd, void *ptr, size_t nbytes, int sendfd)
{
struct msghdr msg;
struct iovec iov[]; union {
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof(int))];
} control_un;
struct cmsghdr *cmptr; msg.msg_control = control_un.control;
msg.msg_controllen = sizeof(control_un.control); cmptr = CMSG_FIRSTHDR(&msg);
cmptr->cmsg_len = CMSG_LEN(sizeof(int));
cmptr->cmsg_level = SOL_SOCKET;
cmptr->cmsg_type = SCM_RIGHTS;
*((int *) CMSG_DATA(cmptr)) = sendfd; msg.msg_name = NULL;
msg.msg_namelen = ; iov[].iov_base = ptr;
iov[].iov_len = nbytes;
msg.msg_iov = iov;
msg.msg_iovlen = ; return (sendmsg(fd, &msg, ));
} ssize_t Write_fd(int fd, void *ptr, size_t nbytes, int sendfd)
{
ssize_t n; if ( (n = write_fd(fd, ptr, nbytes, sendfd)) < ) {
err_sys("write_fd error");
} return (n);
}
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h> /* ANSI C header file */
#include <syslog.h> /* for syslog() */ #define MAXLINE 4096 int daemon_proc; /* set nonzero by daemon_init() */ static void err_doit(int, int, const char *, va_list); /* Nonfatal error related to system call
* Print message and return */ void err_ret(const char *fmt, ...) { va_list ap; va_start(ap, fmt);
err_doit(, LOG_INFO, fmt, ap);
va_end(ap);
return;
} /* Fatal error related to system call
* Print message and terminate */ void err_sys(const char *fmt, ...) { va_list ap; va_start(ap, fmt);
err_doit(, LOG_ERR, fmt, ap);
va_end(ap);
exit();
} /* Fatal error related to system call
* Print message, dump core, and terminate */ void err_dump(const char *fmt, ...) {
va_list ap; va_start(ap, fmt);
err_doit(, LOG_ERR, fmt, ap);
va_end(ap);
abort(); /* dump core and terminate */
exit(); /* shouldn't get here */
} /* Nonfatal error unrelated to system call
* Print message and return */ void err_msg(const char *fmt, ...) { va_list ap; va_start(ap, fmt);
err_doit(, LOG_INFO, fmt, ap);
va_end(ap);
return;
} /* Fatal error unrelated to system call
* Print message and terminate */ void err_quit(const char *fmt, ...) { va_list ap; va_start(ap, fmt);
err_doit(, LOG_ERR, fmt, ap);
va_end(ap);
exit();
} /* Print message and return to caller
* Caller specifies "errnoflag" and "level" */ static void err_doit(int errnoflag, int level, const char *fmt, va_list ap) { int errno_save, n;
char buf[MAXLINE + ]; errno_save = errno; /* value caller might want printed */
#ifdef HAVE_VSNPRINTF
vsnprintf(buf, MAXLINE, fmt, ap); /* safe */
#else
vsprintf(buf, fmt, ap); /* not safe */
#endif
n = strlen(buf);
if (errnoflag)
snprintf(buf + n, MAXLINE - n, ": %s", strerror(errno_save));
strcat(buf, "\n"); if (daemon_proc) {
syslog(level, buf);
} else {
fflush(stdout); /* in case stdout and stderr are the same */
fputs(buf, stderr);
fflush(stderr);
}
return;
}
UNIX域协议之描述符传递的更多相关文章
- 《TCP-IP详解卷3:TCP 事务协议、HTTP、NNTP和UNIX域协议》【PDF】下载
TCP-IP详解卷3:TCP 事务协议.HTTP.NNTP和UNIX域协议>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062539 ...
- UNIX域协议(命名套接字)
这里主要介绍命名UNIX域套接字 1.什么是UNIX域套接字Unix域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务通信的一种方式.是进程间通信(IPC)的一种方式.它提供了两类套接字:字 ...
- Socket编程实践(13) --UNIX域协议
UNIX域协议 UNIX域套接字与TCP相比, 在同一台主机上, UNIX域套接字更有效率, 几乎是TCP的两倍(由于UNIX域套接字不需要经过网络协议栈,不需要打包/拆包,计算校验和,维护序号和应答 ...
- UNP学习笔记(第十五章 UNIX域协议)
UNIX域协议是在单个主机上执行客户/服务器通信的一种方法 使用UNIX域套接字有以下3个理由: 1.UNIX域套接字往往比通信两端位于同一个主机的TCP套接字快出一倍 2.UNIX域套接字可用于在同 ...
- UNP学习 Unix域协议
Unix域协议并不是一个实际的协议族,它只是在同一台主机上进行客户-服务器通信时,使用与在不同主机上的客户和服务器间通信时相同的API的一种方法. 当客户和服务器在同一台主机上时,Unix域协议是这套 ...
- 《Unix 网络编程》15:Unix 域协议
Unix 域协议 ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ 本 ...
- UNIX网络编程读书笔记:UNIX域协议
概述 UNIX域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务器通信的一种方法,所用API与在不同主机上执行客户/服务器通信所用的API(套接口API)相同.UNIX域协议可视为进程间通信 ...
- NDK开发之获得域和方法描述符
在NDK开发之调用方法和NDK开发之访问域两篇博客中,我们在获得域ID和方法ID时都需要一个叫做描述符的参数,那么在实际开发中我们怎么知道我们要调用的域或者方法的描述符呢? 一个简单的方法就是使用Ja ...
- UNIX域协议(无名套接字)
关于什么是UNIX域套接字可以参考:http://www.cnblogs.com/xcywt/p/8185597.html这里主要介绍非命名的UNIX域套接字的用法.1.socketpair函数先看m ...
随机推荐
- Bootstrap table 行编辑导航
/*开启表格编辑方向键导航 方向键(←): VK_LEFT (37) 方向键(↑): VK_UP (38) 方向键(→): VK_RIGHT (39) 方向键(↓): VK_DOWN (40) */ ...
- bash: lspci: command not found解决方法
在CentOS虚拟机使得lspci查看硬件信息.使用时,提示bash: lspci: command not found,大多使用/sbin/lspci即可,我发现我的系统中/sbin下也没有.使用y ...
- [解读REST] 3.基于网络应用的架构
链接上文[解读REST] 2.REST用来干什么的?,上文中解释到什么是架构风格和应该以怎样的视角来理解REST(Web的架构风格).本篇来介绍一组自洽的术语,用它来描述和解释软件架构:以及列举下对于 ...
- python基础 常见用法
1.python计时器timeit模块 1)timeit 模块定义了接收两个参数的Timer类,两个参数都是字符串. 参数1:要计时的语句或者函数 参数2:为参数1构建环境的导入语句 2)Timer对 ...
- 关于H5从PC端切换到移动端,屏幕显示内容由横向转为竖向的研究!
1.前言: 在项目中,我们常会遇见在手机端需要横屏观看的效果,而在pc端则默认切换到竖屏的样式. 或者是,UI提供的图是一个长图,但是在移动端我们需要让这个图在手机横屏时显示. 以上两个都需要我们实行 ...
- [题解]NOIP2018(普及组)T1标题统计(title)
NOIP2018(普及组)T1标题统计(title) 题解 [代码(AC)] #include <iostream> #include <cstdio> #include &l ...
- Python并发式编程
目录 进程 线程 GIL(Global Interpreter Lock) 线程的调用方式 直接调用 继承调用 join&Daemon方法 Daemon(True) 同步锁 死锁 递归锁 同步 ...
- 转:eclipse 设置Java快捷键补全
1.打开Eclipse,点击" Window - Preferences"; 2. 在目录树上选择"Java——Editor——Content Assist", ...
- Linux(Ubuntu)使用日记------markdown文件与pdf,doc,docx文件的相互转化(pandoc使用)
安装: sudo apt-get install pandoc 使用: man pandoc 查看帮助文档 直接转换,命令如下: pandoc -f markdown -t docx ./test ...
- plus webview关闭事件监听
plus.webview.currentWebview().addEventListener("close",function(){ },false);