ccx-utils

Miscellaneous utilities written in C
git clone https://ccx.te2000.cz/git/ccx-utils
Log | Files | Refs

fdrecv.c (1376B)


      1 #include <errno.h>
      2 #include <fcntl.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;
     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 
     36   while(fd < 0) {
     37     wait_readable(socket_fd);
     38     fd = ancil_recv_fd(socket_fd, 42);
     39     if(fd < 0 && errno != EAGAIN) {
     40 	strerr_dief1sys(111, "recvmsg()");
     41     }
     42   }
     43 
     44   /* disable close-on-exec flag if present on fd */
     45   if(fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, NULL) & ~FD_CLOEXEC) == -1) {
     46       strerr_dief1sys(111, "fcntl() disabling FD_CLOEXEC");
     47   }
     48 
     49   size_t env_size = strlen(argv[2]) + uint_fmt(0, fd) + 2;
     50   char envstr[env_size];
     51   char *p = stpncpy(envstr, argv[2], env_size);
     52   *p++ = '=';
     53   uint_fmt(p, fd);
     54   xmexec_n(argv+3, envstr, env_size-1, 1);
     55 }