commit 07ba4d7
uint
·
2026-10-31 15:27:42 +0000 UTC
parent 88634f2
Pipe: Rename pipe->conn, add replying
2 files changed,
+116,
-29
+12,
-5
1@@ -2,25 +2,32 @@
2 #define ULEUPIPE_H
3
4 #include <stddef.h>
5+#include <sys/socket.h>
6 #include <sys/un.h>
7 #include <unistd.h>
8
9 typedef struct {
10- int fd;
11+ int fd;
12+ socklen_t peer_len;
13+
14 struct sockaddr_un addr;
15+ struct sockaddr_un peer;
16 } ulepipe;
17
18 /* Open a ulepipe socket */
19-int ulepipe_open(ulepipe* pipe, const char* path);
20+int ulepipe_open(ulepipe* conn, const char* path);
21
22 /* Close a ulepipe */
23-void ulepipe_close(ulepipe* pipe);
24+void ulepipe_close(ulepipe* conn);
25
26 /* Send data to a ulepipe socket */
27-ssize_t ulepipe_send(const char* path, const void* data, size_t size);
28+ssize_t ulepipe_send(const char* path, void* data, size_t size);
29+
30+/* Reply response to connected client */
31+ssize_t ulepipe_reply(const ulepipe* conn, const void* data, size_t size);
32
33 /* Receive data from a ulepipe socket */
34-ssize_t ulepipe_receive(ulepipe* pipe, void* data, size_t size);
35+ssize_t ulepipe_receive(ulepipe* conn, void* data, size_t size);
36
37 #endif /* ULEUPIPE_H */
38
+104,
-24
1@@ -1,5 +1,9 @@
2+
3 #include <errno.h>
4+#include <stdio.h>
5 #include <sys/socket.h>
6+#include <sys/stat.h>
7+#include <sys/time.h>
8 #include <sys/un.h>
9 #include <string.h>
10 #include <unistd.h>
11@@ -7,19 +11,20 @@
12 #include "ulepipe.h"
13
14 int
15-ulepipe_open(ulepipe* pipe, const char* path)
16+ulepipe_open(ulepipe* conn, const char* path)
17 {
18 int sverrno = 0;
19 int fd = -1;
20
21- if (!pipe || !path) {
22+ if (!conn || !path) {
23 errno = EINVAL;
24 return -1;
25 }
26
27- pipe->fd = -1;
28+ conn->fd = -1;
29+ conn->peer_len = 0;
30
31- if (strlen(path) >= sizeof(pipe->addr.sun_path)) {
32+ if (strlen(path) >= sizeof(conn->addr.sun_path)) {
33 errno = ENAMETOOLONG;
34 return -1;
35 }
36@@ -28,39 +33,46 @@ ulepipe_open(ulepipe* pipe, const char* path)
37 if (fd == -1)
38 return -1;
39
40- memset(&pipe->addr, 0, sizeof(pipe->addr));
41- pipe->addr.sun_family = AF_UNIX;
42- memcpy(pipe->addr.sun_path, path, sizeof(pipe->addr.sun_path));
43+ memset(&conn->addr, 0, sizeof(conn->addr));
44+ conn->addr.sun_family = AF_UNIX;
45+ memcpy(conn->addr.sun_path, path, strlen(path) + 1);
46
47- if (bind(fd, (struct sockaddr*)&pipe->addr, sizeof(pipe->addr)) == -1) {
48+ if (bind(fd, (struct sockaddr*)&conn->addr, sizeof(conn->addr)) == -1) {
49 sverrno = errno;
50 close(fd);
51 errno = sverrno;
52 return -1;
53 }
54
55- pipe->fd = fd;
56+ conn->fd = fd;
57 return 0;
58 }
59
60 void
61-ulepipe_close(ulepipe* pipe)
62+ulepipe_close(ulepipe* conn)
63 {
64- if (!pipe || pipe->fd < 0)
65+ if (!conn || conn->fd < 0)
66 return;
67
68- close(pipe->fd);
69- unlink(pipe->addr.sun_path);
70- pipe->fd = -1;
71+ close(conn->fd);
72+ unlink(conn->addr.sun_path);
73+ conn->fd = -1;
74+ conn->peer_len = 0;
75 }
76
77 ssize_t
78-ulepipe_send(const char* path, const void* data, size_t size)
79+ulepipe_send(const char* path, void* data, size_t size)
80 {
81 struct sockaddr_un addr = { 0 };
82+ struct sockaddr_un client = { 0 };
83+ struct msghdr msg = { 0 };
84+ struct iovec iov = { 0 };
85+ struct timeval timeout = { 5, 0 };
86+ char dir[64] = { 0 };
87 int sverrno = 0;
88 ssize_t n = -1;
89 int fd = -1;
90+ unsigned int i;
91
92 if (!path || (!data && size)) {
93 errno = EINVAL;
94@@ -76,43 +88,108 @@ ulepipe_send(const char* path, const void* data, size_t size)
95 if (fd == -1)
96 return -1;
97
98+ for (i = 0; i < 1000; i++) {
99+ snprintf(dir, sizeof(dir), "/tmp/ulepipe.%ld.%u", (long)getpid(), i);
100+ if (mkdir(dir, 0700) == 0)
101+ break;
102+ if (errno != EEXIST)
103+ goto fail;
104+ }
105+ if (i == 1000) {
106+ errno = EEXIST;
107+ goto fail;
108+ }
109+
110+ client.sun_family = AF_UNIX;
111+ snprintf(client.sun_path, sizeof(client.sun_path), "%s/socket", dir);
112+ if (bind(fd, (struct sockaddr*)&client, sizeof(client)) == -1 ||
113+ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == -1)
114+ goto done;
115+
116 addr.sun_family = AF_UNIX;
117- memcpy(addr.sun_path, path, sizeof(addr.sun_path));
118+ memcpy(addr.sun_path, path, strlen(path) + 1);
119
120 do
121 n = sendto(fd, data, size, 0, (struct sockaddr*)&addr, sizeof(addr));
122 while (n == -1 && errno == EINTR);
123
124- if (n == -1) {
125- sverrno = errno;
126- close(fd);
127- errno = sverrno;
128- return -1;
129+ if (n == -1)
130+ goto done;
131+ if ((size_t)n != size) {
132+ errno = EIO;
133+ n = -1;
134+ goto done;
135+ }
136+
137+ iov.iov_base = data;
138+ iov.iov_len = size;
139+ msg.msg_iov = &iov;
140+ msg.msg_iovlen = 1;
141+
142+ do
143+ n = recvmsg(fd, &msg, 0);
144+ while (n == -1 && errno == EINTR);
145+
146+ if (n != -1 && (msg.msg_flags & MSG_TRUNC)) {
147+ errno = EMSGSIZE;
148+ n = -1;
149 }
150
151+done:
152+ sverrno = errno;
153+ close(fd);
154+ unlink(client.sun_path);
155+ rmdir(dir);
156+ errno = sverrno;
157+ return n;
158+
159+fail:
160+ sverrno = errno;
161 close(fd);
162+ errno = sverrno;
163+ return -1;
164+}
165+
166+ssize_t
167+ulepipe_reply(const ulepipe* conn, const void* data, size_t size)
168+{
169+ ssize_t n = -1;
170+
171+ if (!conn || conn->fd < 0 || !conn->peer_len || (!data && size)) {
172+ errno = EINVAL;
173+ return -1;
174+ }
175+
176+ do
177+ n = sendto(conn->fd, data, size, 0,
178+ (struct sockaddr*)&conn->peer, conn->peer_len);
179+ while (n == -1 && errno == EINTR);
180+
181 return n;
182 }
183
184 ssize_t
185-ulepipe_receive(ulepipe* pipe, void* data, size_t size)
186+ulepipe_receive(ulepipe* conn, void* data, size_t size)
187 {
188 struct msghdr msg = { 0 };
189 struct iovec iov = { 0 };
190 ssize_t n = -1;
191
192- if (!pipe || pipe->fd < 0 || (!data && size)) {
193+ if (!conn || conn->fd < 0 || (!data && size)) {
194 errno = EINVAL;
195 return -1;
196 }
197
198+ conn->peer_len = 0;
199 iov.iov_base = data;
200 iov.iov_len = size;
201 msg.msg_iov = &iov;
202 msg.msg_iovlen = 1;
203+ msg.msg_name = &conn->peer;
204+ msg.msg_namelen = sizeof(conn->peer);
205
206 do
207- n = recvmsg(pipe->fd, &msg, 0);
208+ n = recvmsg(conn->fd, &msg, 0);
209 while (n == -1 && errno == EINTR);
210
211 if (n != -1 && (msg.msg_flags & MSG_TRUNC)) {
212@@ -120,6 +197,9 @@ ulepipe_receive(ulepipe* pipe, void* data, size_t size)
213 return -1;
214 }
215
216+ if (n != -1)
217+ conn->peer_len = msg.msg_namelen;
218+
219 return n;
220 }
221