{"id":907,"date":"2021-12-19T01:11:59","date_gmt":"2021-12-18T17:11:59","guid":{"rendered":"https:\/\/blog.cauchyschwarz.com\/?p=907"},"modified":"2021-12-19T01:12:02","modified_gmt":"2021-12-18T17:12:02","slug":"unix%e5%9f%9f%e5%a5%97%e6%8e%a5%e5%ad%97","status":"publish","type":"post","link":"https:\/\/blog.cauchyschwarz.com\/?p=907","title":{"rendered":"UNIX\u57df\u5957\u63a5\u5b57"},"content":{"rendered":"\n<p>UNIX\u57df\u5957\u63a5\u5b57\u662f\u540c\u673a\u5668\u4e0aIPC\u901a\u4fe1\u65b9\u5f0f\u4e4b\u4e00\uff0c\u8fd9\u4e2a\u673a\u5236\u7684\u51e0\u70b9\u7279\u6027\u5982\u4e0b\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>\u5177\u6709\u548c\u7f51\u7edc\u5957\u63a5\u5b57\u4e00\u6837\u7684API\uff0c\u4f46\u662f\u76f8\u6bd4\u7f51\u7edc\u5957\u63a5\u5b57\u66f4\u9ad8\u6548\uff0c\u56e0\u4e3a\u5b83\u53ea\u62f7\u8d1d\u6570\u636e\uff0c\u6ca1\u6709\u7f51\u7edc\u534f\u8bae\u6808\uff1b<\/li><li><em>SOCK_DGRAM<\/em>\u7c7b\u578b\u7684UNIX\u57df\u5957\u63a5\u5b57\u548c<em>SOCK_STREAM<\/em>\u7c7b\u578b\u5957\u63a5\u5b57\u4e00\u6837\u7684\u53ef\u9760\uff0c\u6ca1\u6709\u4e22\u5305\u3001\u4e71\u5e8f\uff1b<\/li><li>\u53ef\u4ee5\u7528\u6765\u4f20\u9012\u6587\u4ef6\u63cf\u8ff0\u7b26\uff1b<\/li><\/ul>\n\n\n\n<p>\u548cUNIX\u57df\u5957\u63a5\u5b57\u76f8\u5173\u7684\u51e0\u4e2aAPI\uff1a<\/p>\n\n\n\n<p><em>socketpair<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">#include &lt;sys\/socket.h&gt;\nint socketpair(int domain, int type, int protocol, int sockfd[2]);\n<\/code><\/pre>\n\n\n\n<p>\u8fd9\u4e2aAPI\u521b\u5efa\u4e86\u4e00\u5bf9\u53ef\u4ee5\u5168\u53cc\u5de5\u901a\u4fe1\u7684\u65e0\u540dUNIX\u57df\u5957\u63a5\u5b57(\u5b9e\u9645\u4e0a\u6709\u4e9b\u57fa\u4e8eBSD\u7684\u7cfb\u7edf\u5c31\u662f\u7528UNIX\u57df\u5957\u63a5\u5b57\u6765\u5b9e\u73b0pipe\u7684\uff0c\u5c31\u662f\u8c03\u7528<em>socketpair<\/em>\u51fd\u6570\u540e\uff0c\u628a\u8fd4\u56de\u7684\u7b2c\u4e00\u4e2a\u63cf\u8ff0\u7b26\u7684\u5199\u5173\u95ed\uff0c\u628a\u8fd4\u56de\u7684\u7b2c\u4e8c\u4e2a\u63cf\u8ff0\u7b26\u7684\u8bfb\u5173\u95ed)\u3002<\/p>\n\n\n\n<p>\u548cUNIX\u57df\u5957\u63a5\u5b57\u76f8\u5173\u7684\u5b9a\u4e49\uff1a<\/p>\n\n\n\n<p>Linux 3.2.0\u548cSolaris 10\u4e2d<em>sockaddr_un<\/em>\u7684\u5b9a\u4e49\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">struct sockaddr_un {\n\tsa_family_t sun_family;\t\t<em>\/*AF_UNIX*\/<\/em>\n\tchar\tsun_path[108];\t\t<em>\/*pathname*\/<\/em>\n};\n<\/code><\/pre>\n\n\n\n<p>FreeBSD 8.0\u548cMac OS X 10.6.8\u4e2d\u7684\u5b9a\u4e49\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">struct sockaddr_un {\n\tunsigned char sun_len;\t\t<em>\/*sockaddr length*\/<\/em>\n\tsa_family_t\tsun_family;\t<em>\/*AF_UNIX*\/<\/em>\n\tchar\t\tsun_path[104];\t<em>\/*pathname*\/<\/em>\n};\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>TCP\/IP\u534f\u8bae\u901a\u8fc7<em>sockaddr_in<\/em>\u6307\u5b9aIP\u5730\u5740\u548c\u7aef\u53e3\uff0c\u800cUNIX\u57df\u5957\u63a5\u5b57\u901a\u8fc7<em>sockaddr_un<\/em>\u6307\u5b9a\u5730\u5740\uff1b<\/li><li><em>sun_path<\/em>\u6307\u5b9a\u4e86\u4ee3\u8868\u8be5UNIX\u57df\u5957\u63a5\u5b57\u7684\u4e00\u4e2a<strong>S_IFSOCK<\/strong>\u7c7b\u578b\u6587\u4ef6\u7684\u4f4d\u7f6e\uff0c\u5f53\u6211\u4eec\u8bd5\u56fe\u5c06\u4e00\u4e2a\u5957\u63a5\u5b57bind\u5230\u6307\u5b9a<em>sun_path<\/em>\u65f6\uff0c\u5982\u679c\u8be5\u4f4d\u7f6e\u5df2\u7ecf\u5b58\u5728\u4e86\u4e00\u4e2a\u6587\u4ef6\uff0c\u90a3\u4e48\u7ed1\u5b9a\u5c31\u4f1a\u5931\u8d25\u3002\u5728\u5957\u63a5\u5b57\u88ab\u5173\u95ed\u540e\uff0c\u8be5<strong>S_IFSOCK<\/strong>\u7c7b\u578b\u6587\u4ef6\u5e76\u4e0d\u4f1a\u88ab\u81ea\u52a8\u79fb\u9664\uff0c\u9700\u8981\u6211\u4eec\u663e\u793a\u6267\u884cunlink\u624d\u884c\uff1b<\/li><li>\u4f7f\u7528UNIX\u57df\u5957\u63a5\u5b57\u7684\u5ba2\u6237\u7aef\u5982\u679c\u4e0d\u663e\u793abind\u4e00\u4e2a\u5730\u5740\u7684\u8bdd\uff0c\u90a3\u4e48\u670d\u52a1\u7aef\u83b7\u53d6\u5230\u7684\u5ba2\u6237\u7aef\u7684\u5730\u5740\u7684<em>sun_path<\/em>\u662f\u7a7a\u7684\uff0c\u8fd9\u548cTCP\/IP\u534f\u8bae\u4f1a\u7ed9\u5ba2\u6237\u7aef\u81ea\u52a8\u5206\u914d\u7aef\u53e3\u662f\u4e0d\u540c\u7684\uff1b<\/li><li><em>sun_path<\/em>\u53ef\u4ee5\u8bbe\u7f6e\u4e3a\u7edd\u5bf9\u8def\u5f84\u6216\u8005\u76f8\u5bf9\u8def\u5f84\uff0c\u6240\u4ee5\u5ba2\u6237\u7aef\u5728\u8fde\u63a5\u670d\u52a1\u7aef\u65f6\u8981\u786e\u8ba4\u5b83\u6240\u8fde\u63a5\u7684\u5730\u5740\u662f\u5426\u548c\u670d\u52a1\u7aefbind\u7684\u662f\u540c\u4e00\u4e2a\u5730\u5740\uff0c\u800c\u4e0d\u53ea\u662f\u5b57\u9762\u4e0a\u7684<em>sun_path<\/em>\u76f8\u540c\uff1b<\/li><li>\u7531\u4e8e<em>sockaddr_un<\/em>\u5728\u4e0d\u540c\u7cfb\u7edf\u4e2d\u5b9a\u4e49\u53ef\u80fd\u4e0d\u540c\uff0c\u6240\u4ee5bind\u5730\u5740\u65f6\u7684\u4ee3\u7801\u6700\u597d\u6309\u5982\u4e0b\u6240\u793a\u4e66\u5199\uff1a<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">\tsize = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);\n\tif (bind(fd, (struct sockaddr *)&amp;un, size) &lt; 0)\n\t\terr_sys(\"bind failed\");\n<\/code><\/pre>\n\n\n\n<p>\u8fd9\u91cc\u4e3b\u8981\u4f7f\u7528\u4e86<em>offsetof<\/em>\u8fd9\u4e2a\u6765\u81ea\u4e8estddef.h\u7684\u5b8f\uff1a<code>#define offsetof(TYPE, MEMBER) ((int)&amp;((TYPE *)0)-&gt;MEMBER)<\/code>\u3002<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>\u6211\u4eec\u5728\u8bbe\u7f6eUNIX\u57df\u5957\u63a5\u5b57\u7684\u5730\u5740\u65f6\uff0c\u662f\u4e0d\u9700\u8981\u586b\u5145<em>sun_len<\/em>\u8fd9\u4e2a\u5b57\u6bb5\u7684(\u524d\u63d0\u662f\u5982\u679c\u8fd9\u4e2a\u5b57\u6bb5\u771f\u7684\u5b58\u5728\u7684\u8bdd)\uff0c\u7cfb\u7edf\u4f1a\u6839\u636e\u6211\u4eec\u8c03\u7528bind\u53c2\u6570\u65f6\u586b\u7684size\u53c2\u6570\u53bb\u63a8\u5bfc\u586b\u5145\u8fd9\u4e2a\u5b57\u6bb5\uff1b<\/li><li><em>bind<\/em>\u7684\u6700\u540e\u4e00\u4e2a\u53c2\u6570\u662f\u4e0d\u5305\u542bUNIX\u57df\u5957\u63a5\u5b57\u5bf9\u5e94\u8def\u5f84\u672b\u5c3e\u8868\u793a\u5b57\u7b26\u4e32\u7ed3\u675f\u76840\u7684\uff1b\u5f53<em>accept<\/em>\u63a5\u53d7\u5ba2\u6237\u7aef\u8fde\u63a5\u7684\u65f6\u5019\uff0c\u5176\u6700\u540e\u4e00\u4e2a\u53c2\u6570\u8fd4\u56de\u7684\u503c\u4e5f\u662f\u6ca1\u6709\u5305\u542b\u672b\u5c3e\u76840\u7684(\u56e0\u4e3a\u6211\u4eec<em>bind<\/em>\u7684\u65f6\u5019\u5c31\u6ca1\u6709\u628a\u672b\u5c3e\u90a3\u4e2a0\u5b57\u8282\u7ed9\u62f7\u8d1d\u8fdb\u53bb)\uff0c\u6240\u4ee5\u5bf9\u4e8e\u8fd4\u56de\u7684\u5ba2\u6237\u7aef<em>sun_path<\/em>\u8981\u6ce8\u610f\u5728\u5176\u540e\u9762\u6dfb\u52a00\u5b57\u8282\u4f7f\u7528\uff1b<\/li><\/ul>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"%E4%BD%BF%E7%94%A8unix%E5%A5%97%E6%8E%A5%E5%AD%97%E4%BC%A0%E9%80%92%E6%96%87%E4%BB%B6%E6%8F%8F%E8%BF%B0%E7%AC%A6\">\u4f7f\u7528UNIX\u5957\u63a5\u5b57\u4f20\u9012\u6587\u4ef6\u63cf\u8ff0\u7b26<\/h1>\n\n\n\n<p>UNIX\u5957\u63a5\u5b57\u7684\u4e00\u4e2a\u7279\u6b8a\u4e4b\u5904\u5728\u4e8e\u53ef\u4ee5\u7528\u5b83\u4f20\u9012\u6587\u4ef6\u63cf\u8ff0\u7b26\uff0c\u8fd9\u4e2a\u4f20\u9012\u6587\u4ef6\u63cf\u8ff0\u7b26\u5e76\u4e0d\u662f\u4f20\u9012\u6587\u4ef6\u63cf\u8ff0\u7b26\u8fd9\u4e2a\u6570\u5b57\uff0c\u800c\u662f\u8bf4\u63a5\u6536\u6587\u4ef6\u63cf\u8ff0\u7b26\u7684\u4e00\u65b9\u4f1a\u4f7f\u7528\u5176\u53ef\u7528\u7684\u6700\u5c0f\u6587\u4ef6\u63cf\u8ff0\u7b26\u6765\u6307\u5411\u53d1\u9001\u65b9\u4f20\u9012\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\u5bf9\u5e94\u7684<strong>file table entry<\/strong>\u3002<br>UNIX\u5957\u63a5\u5b57\u4f20\u9012\u6587\u4ef6\u63cf\u8ff0\u7b26\u7684\u529f\u80fd\u662f\u901a\u8fc7<em>CMSG<\/em>\u7684\u5f62\u5f0f\u63d0\u4f9b\u7ed9\u5e94\u7528\u7a0b\u5e8f\u7684\uff0c\u4e3a\u6b64\u6211\u4eec\u9700\u8981\u719f\u6089\u4ee5\u4e0bapi\u548c\u76f8\u5173\u5b9a\u4e49\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);\n\nstruct msghdr {\n\tvoid\t*msg_name;\t<em>\/* optional address *\/<\/em>\n\tsocklen_t msg_namelen;\t<em>\/* address size in bytes *\/<\/em>\n\tstruct iovec *msg_iov;\t<em>\/* array of I\/O buffers *\/<\/em>\n\tint\tmsg_iovlen;\t<em>\/* number of elements in array *\/<\/em>\n\tvoid \t*msg_control;\t<em>\/* ancillary data *\/<\/em>\n\tsocklen_t msg_controllen;\t<em>\/* number of ancillary bytes *\/<\/em>\n\tint \tmsg_flags;\t<em>\/* flags for received message *\/<\/em>\n};\n\nstruct cmsghdr {\n\tsocklen_t\tcmsg_len;\t<em>\/* data byte count, including header *\/<\/em>\n\tint\t\tcmsg_level;\t<em>\/* originating protocol\t*\/<\/em>\n\tint\t\tcmgs_type;\t<em>\/* protocol-specific type *\/<\/em>\n\t<em>\/* followed by the actual control message data *\/<\/em>\n};\n\n<em>\/* \u548cCMSG\u76f8\u5173\u7684\u51e0\u4e2a\u5b8f *\/<\/em>\n\n#include &lt;sys\/socket.h&gt;\n\n<em>\/\/ \u8fd4\u56decmsghdr\u7ed3\u6784\u4f53cp\u4e2d\u6570\u636e\u7684\u4f4d\u7f6e<\/em>\n<em>\/\/ Returns: pointer to data associated with cmsghdr structure<\/em>\nunsigned char *CMSG_DATA(struct cmsghdr *cp);\n\n<em>\/\/ \u8fd4\u56de\u548cmsghdr\u7ed3\u6784\u4f53mp\u5173\u8054\u7684\u7b2c\u4e00\u4e2acmsghdr<\/em>\n<em>\/\/ Returns: pointer to the first cmsghdr structure associated with the msghdr <\/em>\n<em>\/\/ structure, or NULL if none exists<\/em>\nstruct cmsghdr *CMSG_FIRSTHDR(struct msghdr *mp);\n\n<em>\/\/ \u8fd4\u56de\u548cmsghdr\u7ed3\u6784\u4f53mp\u5173\u8054\u7684\u3001\u4e14\u4f4d\u4e8emp\u7ed3\u6784\u4f53\u4e4b\u540e\u7684cmsghdr\u7ed3\u6784\u4f53\u7684\u4f4d\u7f6e<\/em>\n<em>\/\/ Returns: pointer to the next cmsghdr structure associated with the msghdr <\/em>\n<em>\/\/ structure given the current cmsghdr structure, or NULL if we're at the last one<\/em>\nstruct cmsghdr *CMSG_NXTHDR(struct msghdr *mp, struct cmsghdr *cp);\n\n<em>\/\/ \u7528\u4e8e\u8ba1\u7b97\u60f3\u8981\u5728cmsghdr\u7ed3\u6784\u4f53\u4e2d\u5b58\u50a8n\u4e2a\u5b57\u8282\u7684\u6570\u636e\u9700\u8981\u4e3a\u8fd9\u4e2a\u7ed3\u6784\u4f53\u5f00\u8f9f\u591a\u5c11\u5b57\u8282\u7684\u5185\u5b58\u7a7a\u95f4<\/em>\n<em>\/\/ Returns: size to allocate for data object nbytes large<\/em>\nunsigned int CMSG_LEN(unsigned int nbytes);\n<\/code><\/pre>\n\n\n\n<p>\u5bf9\u4e8e\u53d1\u9001\u6587\u4ef6\u63cf\u8ff0\u7b26\u7684\u4e00\u65b9\u6765\u8bf4\uff0c\u9700\u8981\u505a\u7684\u4e8b\u60c5\u6709\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>\u5c06\u6587\u4ef6\u63cf\u8ff0\u7b26\u5b58\u5230cmsghdr\u7684data\u5b57\u6bb5\u91cc\uff0c\u7528int\u7c7b\u578b\u5b58\uff1b<\/li><li>\u8bbe\u7f6e<em>cmsghdr<\/em>\u7684<em>cmsg_level<\/em>\u4e3a<em>SOL_SOCKET<\/em>\uff1b<\/li><li>\u8bbe\u7f6e<em>cmsghdr<\/em>\u7684<em>cmsg_type<\/em>\u4e3a<em>SCM_RIGHTS<\/em>\uff1b<\/li><li>\u8bbe\u7f6e<em>cmsghdr<\/em>\u7684<em>cmsg_len<\/em>\u4e3aint\u7c7b\u578b\u957f\u5ea6\uff1b<\/li><li>\u5c06cmsg\u7528sendmsg\u65b9\u6cd5\u53d1\u9001\uff1b<\/li><\/ul>\n\n\n\n<p>\u53ef\u4ee5\u53c2\u8003apiue\u4e2d\u53d1\u9001\u6587\u4ef6\u63cf\u8ff0\u7b26\u7684\u793a\u4f8b\u4ee3\u7801\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">#include \"apue.h\"\n#include &lt;sys\/socket.h&gt;\n\n<em>\/* size of control buffer to send\/recv one file descriptor *\/<\/em>\n#define\tCONTROLLEN\tCMSG_LEN(sizeof(int))\n\nstatic struct cmsghdr\t*cmptr = NULL;\t<em>\/* malloc'ed first time *\/<\/em>\n\n<em>\/*\n * Pass a file descriptor to another process.\n * If fd&lt;0, then -fd is sent back instead as the error status.\n *\/<\/em>\nint\nsend_fd(int fd, int fd_to_send)\n{\n\tstruct iovec\tiov[1];\n\tstruct msghdr\tmsg;\n\tchar\t\t\tbuf[2];\t<em>\/* send_fd()\/recv_fd() 2-byte protocol *\/<\/em>\n\n\tiov[0].iov_base = buf;\n\tiov[0].iov_len  = 2;\n\tmsg.msg_iov     = iov;\n\tmsg.msg_iovlen  = 1;\n\tmsg.msg_name    = NULL;\n\tmsg.msg_namelen = 0;\n\n\tif (fd_to_send &lt; 0) {\n\t\tmsg.msg_control    = NULL;\n\t\tmsg.msg_controllen = 0;\n\t\tbuf[1] = -fd_to_send;\t<em>\/* nonzero status means error *\/<\/em>\n\t\tif (buf[1] == 0)\n\t\t\tbuf[1] = 1;\t<em>\/* -256, etc. would screw up protocol *\/<\/em>\n\t} else {\n\t\tif (cmptr == NULL &amp;&amp; (cmptr = malloc(CONTROLLEN)) == NULL)\n\t\t\treturn(-1);\n\t\tcmptr-&gt;cmsg_level  = SOL_SOCKET;\n\t\tcmptr-&gt;cmsg_type   = SCM_RIGHTS;\n\t\tcmptr-&gt;cmsg_len    = CONTROLLEN;\n\t\tmsg.msg_control    = cmptr;\n\t\tmsg.msg_controllen = CONTROLLEN;\n\t\t*(int *)CMSG_DATA(cmptr) = fd_to_send;\t\t<em>\/* the fd to pass *\/<\/em>\n\t\tbuf[1] = 0;\t\t<em>\/* zero status means OK *\/<\/em>\n\t}\n\n\tbuf[0] = 0;\t\t\t<em>\/* null byte flag to recv_fd() *\/<\/em>\n\tif (sendmsg(fd, &amp;msg, 0) != 2)\n\t\treturn(-1);\n\treturn(0);\n}\n<\/code><\/pre>\n\n\n\n<p>\u5bf9\u4e8e\u63a5\u6536\u6587\u4ef6\u63cf\u8ff0\u7b26\u7684\u4e00\u65b9\u6765\u8bf4\uff0c\u9700\u8981\u505a\u7684\u4e8b\u60c5\u6709\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>\u4f7f\u7528recvmsg\u63a5\u6536\u6570\u636e\uff0c\u5e76\u4e14\u68c0\u67e5\u662f\u5426\u6709\u6536\u5230cmsg\u6570\u636e\uff0c\u68c0\u67e5\u8be5cmsg\u6570\u636e\u7684<em>cmsg_level<\/em>\uff0c<em>cmsg_type<\/em>\uff0c\u662f\u5426\u5c31\u662f<em>SOL_SOCKET<\/em>\u548c<em>SCM_RIGHTS<\/em>\uff1b<\/li><li>\u9700\u8981\u6ce8\u610f\u7684\u4e00\u70b9\u662frecvmsg\u5728\u63a5\u6536\u65f6\u9700\u8981\u63d0\u524d\u7533\u8bf7\u597d\u7528\u4e8e\u4fdd\u5b58<em>cmsg<\/em>\u7684\u7a7a\u95f4\uff0c\u5e76\u4e14\u9700\u8981\u5c06<em>msg_control<\/em>\u6307\u5411\u8be5\u7a7a\u95f4\u548c\u8bbe\u7f6e<em>msg_controllen<\/em>\u7684\u503c\uff1b<\/li><\/ul>\n\n\n\n<p>\u53c2\u8003apiue\u4e2d\u7684\u793a\u4f8b\u4ee3\u7801\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">#include \"apue.h\"\n#include &lt;sys\/socket.h&gt;\t\t\/* struct msghdr *\/\n\n<em>\/* size of control buffer to send\/recv one file descriptor *\/<\/em>\n#define\tCONTROLLEN\tCMSG_LEN(sizeof(int))\n\n#ifdef LINUX\n#define RELOP &lt;\n#else\n#define RELOP !=\n#endif\n\nstatic struct cmsghdr\t*cmptr = NULL;\t\t<em>\/* malloc'ed first time *\/<\/em>\n\n<em>\/*\n * Receive a file descriptor from a server process.  Also, any data\n * received is passed to (*userfunc)(STDERR_FILENO, buf, nbytes).\n * We have a 2-byte protocol for receiving the fd from send_fd().\n *\/<\/em>\nint\nrecv_fd(int fd, ssize_t (*userfunc)(int, const void *, size_t))\n{\n\tint\t\t\t\tnewfd, nr, status;\n\tchar\t\t\t*ptr;\n\tchar\t\t\tbuf[MAXLINE];\n\tstruct iovec\tiov[1];\n\tstruct msghdr\tmsg;\n\n\tstatus = -1;\n\tfor ( ; ; ) {\n\t\tiov[0].iov_base = buf;\n\t\tiov[0].iov_len  = sizeof(buf);\n\t\tmsg.msg_iov     = iov;\n\t\tmsg.msg_iovlen  = 1;\n\t\tmsg.msg_name    = NULL;\n\t\tmsg.msg_namelen = 0;\n\t\tif (cmptr == NULL &amp;&amp; (cmptr = malloc(CONTROLLEN)) == NULL)\n\t\t\treturn(-1);\n\t\tmsg.msg_control    = cmptr;\n\t\tmsg.msg_controllen = CONTROLLEN;\n\t\tif ((nr = recvmsg(fd, &amp;msg, 0)) &lt; 0) {\n\t\t\terr_ret(\"recvmsg error\");\n\t\t\treturn(-1);\n\t\t} else if (nr == 0) {\n\t\t\terr_ret(\"connection closed by server\");\n\t\t\treturn(-1);\n\t\t}\n\n\t\t<em>\/*\n\t\t * See if this is the final data with null &amp; status.  Null\n\t\t * is next to last byte of buffer; status byte is last byte.\n\t\t * Zero status means there is a file descriptor to receive.\n\t\t *\/<\/em>\n\t\tfor (ptr = buf; ptr &lt; &amp;buf[nr]; ) {\n\t\t\tif (*ptr++ == 0) {\n\t\t\t\tif (ptr != &amp;buf[nr-1])\n\t\t\t\t\terr_dump(\"message format error\");\n \t\t\t\tstatus = *ptr &amp; 0xFF;\t<em>\/* prevent sign extension *\/<\/em>\n \t\t\t\tif (status == 0) {\n\t\t\t\t\tif (msg.msg_controllen RELOP CONTROLLEN)\n\t\t\t\t\t\terr_dump(\"status = 0 but no fd\");\n\t\t\t\t\tnewfd = *(int *)CMSG_DATA(cmptr);\n\t\t\t\t} else {\n\t\t\t\t\tnewfd = -status;\n\t\t\t\t}\n\t\t\t\tnr -= 2;\n\t\t\t}\n\t\t}\n\t\tif (nr &gt; 0 &amp;&amp; (*userfunc)(STDERR_FILENO, buf, nr) != nr)\n\t\t\treturn(-1);\n\t\tif (status &gt;= 0)\t<em>\/* final data has arrived *\/<\/em>\n\t\t\treturn(newfd);\t<em>\/* descriptor, or -status *\/<\/em>\n\t}\n}\n<\/code><\/pre>\n\n\n\n<p>\u5728Linux\u4e2d\uff0c\u8fd8\u53ef\u4ee5\u7528UNIX\u57df\u5957\u63a5\u5b57\u6765\u4f20\u9012credentials\uff0c\u76f8\u5e94\u7684<em>cmsg_type<\/em>\u4e3a<strong>SCM_CREDENTIALS<\/strong>\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">struct ucred {\n\tpid_t\tpid;\t<em>\/* sender's process ID *\/<\/em>\n\tuid_t \tuid;\t<em>\/* sender's user ID *\/<\/em>\n\tgid_t\tgid;\t<em>\/* sender's group ID *\/<\/em>\n};\n<\/code><\/pre>\n\n\n\n<p>\u793a\u4f8b\u4ee3\u7801\u5c31\u4e0d\u8d34\u4e86\uff0c\u76f4\u63a5\u67e5\u9605apiue\u7684\u6e90\u7801\u5373\u53ef\uff0c\u4ece\u4e2d\u8fd8\u53ef\u4ee5\u5b66\u5230<em>CMSG_NXTHDR<\/em>\u8fd9\u4e2a\u5b8f\u7684\u7528\u6cd5\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>UNIX\u57df\u5957\u63a5\u5b57\u662f\u540c\u673a\u5668\u4e0aIPC\u901a\u4fe1\u65b9\u5f0f\u4e4b\u4e00\uff0c\u8fd9\u4e2a\u673a\u5236\u7684\u51e0\u70b9\u7279\u6027\u5982\u4e0b\uff1a \u5177\u6709\u548c\u7f51\u7edc\u5957\u63a5\u5b57\u4e00\u6837\u7684API\uff0c\u4f46\u662f\u76f8\u6bd4\u7f51\u7edc\u5957\u63a5\u5b57\u66f4\u9ad8\u6548\uff0c\u56e0\u4e3a\u5b83\u53ea\u62f7\u8d1d\u6570\u636e\uff0c\u6ca1\u6709\u7f51\u7edc\u534f\u8bae\u6808\uff1b SOCK_DGRAM\u7c7b\u578b\u7684UNIX\u57df&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[104],"class_list":["post-907","post","type-post","status-publish","format-standard","hentry","category-10","tag-ipc"],"_links":{"self":[{"href":"https:\/\/blog.cauchyschwarz.com\/index.php?rest_route=\/wp\/v2\/posts\/907","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.cauchyschwarz.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.cauchyschwarz.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.cauchyschwarz.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.cauchyschwarz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=907"}],"version-history":[{"count":1,"href":"https:\/\/blog.cauchyschwarz.com\/index.php?rest_route=\/wp\/v2\/posts\/907\/revisions"}],"predecessor-version":[{"id":908,"href":"https:\/\/blog.cauchyschwarz.com\/index.php?rest_route=\/wp\/v2\/posts\/907\/revisions\/908"}],"wp:attachment":[{"href":"https:\/\/blog.cauchyschwarz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=907"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.cauchyschwarz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=907"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.cauchyschwarz.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=907"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}