commit 42f9a2d5eed3755f3bd7d5b9b489641739fa356b
parent c4575987bbb77e7130864577cbf87ce5e6e39f1d
Author: Jan Pobrislo <ccx@te2000.cz>
Date: Mon, 29 Jul 2024 22:35:20 +0000
fdsend / fdrecvto
Diffstat:
7 files changed, 187 insertions(+), 2 deletions(-)
diff --git a/src/Makefile b/src/Makefile
@@ -1,5 +1,5 @@
-tools_simple:=argv0exec nosuid pidns_run safelink spawn-pty
+tools_simple:=argv0exec nosuid pidns_run safelink spawn-pty fdsend fdrecv fdrecvto socketpair
tools_libcap:=applyuidgid-caps
tools=$(tools_simple) $(tools_libcap)
diff --git a/src/fdrecv.c b/src/fdrecv.c
@@ -0,0 +1,47 @@
+#include <errno.h>
+#include <sys/select.h>
+
+#include <skalibs/types.h>
+#include <skalibs/strerr.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
+#include <skalibs/ancil.h>
+
+#define USAGE "fdrecv socket_fd fd_env_var prog..."
+#define PROG "fdrecv"
+
+void wait_readable(int fd) {
+ fd_set rfds, xfds;
+ int retval = 0;
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+ FD_ZERO(&xfds);
+ FD_SET(fd, &xfds);
+ while(retval < 1) {
+ retval = select(fd+1, &rfds, NULL, &xfds, NULL);
+ if (retval == -1 && errno != EINTR) {
+ strerr_dief1sys(111, "select()");
+ }
+ }
+}
+
+int main (int argc, char const *const *argv)
+{
+ unsigned int socket_fd;
+ int fd;
+ if ((argc < 4)) strerr_dieusage(100, USAGE) ;
+ if (!uint0_scan(argv[1], &socket_fd)) strerr_dieusage(100, USAGE) ;
+
+ wait_readable(socket_fd);
+ fd = ancil_recv_fd(socket_fd, 42);
+ if(fd < 0) {
+ strerr_dief1sys(111, "recvmsg()");
+ }
+
+ size_t env_size = strlen(argv[2]) + uint_fmt(0, fd) + 2;
+ char envstr[env_size];
+ char *p = stpncpy(envstr, argv[2], env_size);
+ *p++ = '=';
+ uint_fmt(p, fd);
+ xmexec_n(argv+3, envstr, env_size-1, 1);
+}
diff --git a/src/fdrecvto.c b/src/fdrecvto.c
@@ -0,0 +1,55 @@
+#include <errno.h>
+#include <unistd.h>
+#include <sys/select.h>
+
+#include <skalibs/types.h>
+#include <skalibs/strerr.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
+#include <skalibs/ancil.h>
+
+#define USAGE "fdrecv socket_fd fd_env_var prog..."
+#define PROG "fdrecv"
+
+void wait_readable(int fd) {
+ fd_set rfds, xfds;
+ int retval = 0;
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+ FD_ZERO(&xfds);
+ FD_SET(fd, &xfds);
+ while(retval < 1) {
+ retval = select(fd+1, &rfds, NULL, &xfds, NULL);
+ if (retval == -1 && errno != EINTR) {
+ strerr_dief1sys(111, "select()");
+ }
+ }
+}
+
+int main (int argc, char const *const *argv)
+{
+ unsigned int socket_fd, target_fd;
+ int fd;
+ if ((argc < 4)) strerr_dieusage(100, USAGE) ;
+ if (!uint0_scan(argv[1], &socket_fd)) strerr_dieusage(100, USAGE) ;
+ if (!uint0_scan(argv[2], &target_fd)) strerr_dieusage(100, USAGE) ;
+
+ wait_readable(socket_fd);
+ fd = ancil_recv_fd(socket_fd, 42);
+ if(fd < 0) {
+ strerr_dief1sys(111, "recvmsg()");
+ }
+ if(fd == target_fd) {
+ int tmp_fd = dup(fd);
+ if(tmp_fd < 0) {
+ strerr_dief1sys(111, "dup()");
+ }
+ close(fd);
+ fd = tmp_fd;
+ }
+ if(dup2(fd, target_fd) < 0) {
+ strerr_dief1sys(111, "dup2()");
+ }
+
+ xexec(argv+3) ;
+}
diff --git a/src/fdsend.c b/src/fdsend.c
@@ -0,0 +1,42 @@
+#include <errno.h>
+#include <sys/select.h>
+
+#include <skalibs/types.h>
+#include <skalibs/strerr.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
+#include <skalibs/ancil.h>
+
+#define USAGE "fdsend socket_fd fd_to_send prog..."
+#define PROG "fdsend"
+
+void wait_writable(int fd) {
+ fd_set wfds, xfds;
+ int retval = 0;
+ FD_ZERO(&wfds);
+ FD_SET(fd, &wfds);
+ FD_ZERO(&xfds);
+ FD_SET(fd, &xfds);
+ while(retval < 1) {
+ retval = select(fd+1, NULL, &wfds, &xfds, NULL);
+ if (retval == -1 && errno != EINTR) {
+ strerr_dief1sys(111, "select()");
+ }
+ }
+}
+
+
+int main (int argc, char const *const *argv)
+{
+ unsigned int socket_fd, fd_to_send ;
+ if ((argc < 4)) strerr_dieusage(100, USAGE) ;
+ if (!uint0_scan(argv[1], &socket_fd)) strerr_dieusage(100, USAGE) ;
+ if (!uint0_scan(argv[2], &fd_to_send)) strerr_dieusage(100, USAGE) ;
+
+ wait_writable(socket_fd);
+ if(!ancil_send_fd(socket_fd, fd_to_send, 42)) {
+ strerr_dief1sys(111, "sendmsg()");
+ }
+
+ xexec(argv+3) ;
+}
diff --git a/src/pidns_run.c b/src/pidns_run.c
@@ -74,7 +74,7 @@ int main(const int argc, const char **argv) {
if (retval == -1 && errno != EINTR) {
strerr_dief1sys(111, "select()");
}
- if(retval) {
+ if(retval > 0) {
const char term_msg[] = "pidns_run: parent died, terminating\n";
write(2, "pidns_run: parent died, terminating\n", sizeof(term_msg));
exit(111);
diff --git a/src/socketpair.c b/src/socketpair.c
@@ -0,0 +1,32 @@
+#include <unistd.h>
+
+#include <skalibs/types.h>
+#include <skalibs/strerr.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/exec.h>
+#include <skalibs/socket.h>
+
+#define USAGE "socketpair fd0 fd1 prog..."
+#define PROG "socketpair"
+
+int main (int argc, char const *const *argv)
+{
+ int fd0, fd1;
+ int sv[2];
+ if ((argc < 4)
+ || !uint0_scan(argv[1], (unsigned int *)&fd0)
+ || !uint0_scan(argv[2], (unsigned int *)&fd1)
+ || (fd0 == fd1))
+ strerr_dieusage(100, USAGE) ;
+
+ if (ipc_pair_b(sv) != 0) {
+ strerr_diefu1sys(111, "create socketpair") ;
+ }
+
+ if (sv[1] == fd0) sv[1] = dup(sv[1]) ;
+ if ((sv[1] == -1)
+ || (fd_move(fd0, sv[0]) == -1)
+ || (fd_move(fd1, sv[1]) == -1))
+ strerr_diefu1sys(111, "move fds") ;
+ xexec(argv+3) ;
+}
diff --git a/src/test-fdsend b/src/test-fdsend
@@ -0,0 +1,9 @@
+#!/bin/execlineb -P
+./socketpair 3 4
+#if { filan }
+background {
+ fdclose 4
+ redirfd -r 0 ./fdsend.c ./fdsend 3 0 true
+}
+fdclose 3
+./fdrecvto 4 0 cat