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