fdrecvto.c (1300B)
1 #include <errno.h> 2 #include <unistd.h> 3 #include <sys/select.h> 4 5 #include <skalibs/types.h> 6 #include <skalibs/strerr.h> 7 #include <skalibs/djbunix.h> 8 #include <skalibs/exec.h> 9 #include <skalibs/ancil.h> 10 11 #define USAGE "fdrecv socket_fd fd_env_var prog..." 12 #define PROG "fdrecv" 13 14 void wait_readable(int fd) { 15 fd_set rfds, xfds; 16 int retval = 0; 17 FD_ZERO(&rfds); 18 FD_ZERO(&xfds); 19 while(retval < 1) { 20 FD_SET(fd, &rfds); 21 FD_SET(fd, &xfds); 22 retval = select(fd+1, &rfds, NULL, &xfds, NULL); 23 if (retval == -1 && errno != EINTR) { 24 strerr_dief1sys(111, "select()"); 25 } 26 } 27 } 28 29 int main (int argc, char const *const *argv) 30 { 31 unsigned int socket_fd, target_fd; 32 int fd = -1; 33 if ((argc < 4)) strerr_dieusage(100, USAGE) ; 34 if (!uint0_scan(argv[1], &socket_fd)) strerr_dieusage(100, USAGE) ; 35 if (!uint0_scan(argv[2], &target_fd)) strerr_dieusage(100, USAGE) ; 36 37 while(fd < 0) { 38 wait_readable(socket_fd); 39 fd = ancil_recv_fd(socket_fd, 42); 40 if(fd < 0 && errno != EAGAIN) { 41 strerr_dief1sys(111, "recvmsg()"); 42 } 43 } 44 if(fd == target_fd) { 45 int tmp_fd = dup(fd); 46 if(tmp_fd < 0) { 47 strerr_dief1sys(111, "dup()"); 48 } 49 close(fd); 50 fd = tmp_fd; 51 } 52 if(dup2(fd, target_fd) < 0) { 53 strerr_dief1sys(111, "dup2()"); 54 } 55 56 xexec(argv+3) ; 57 }