skalibs

Mirror/fork of https://skarnet.org/software/skalibs/
git clone https://ccx.te2000.cz/git/skalibs
Log | Files | Refs | README | LICENSE

child_spawn3.c (1599B)


      1 /* ISC license. */
      2 
      3 #include <unistd.h>
      4 
      5 #include <skalibs/types.h>
      6 #include <skalibs/env.h>
      7 #include <skalibs/djbunix.h>
      8 #include <skalibs/cspawn.h>
      9 
     10 pid_t child_spawn3 (char const *prog, char const *const *argv, char const *const *envp, int *fds)
     11 {
     12   pid_t pid ;
     13   int p[3][2] ;
     14 
     15   if (pipe(p[0]) == -1) return 0 ;
     16   if (ndelay_on(p[0][0]) == -1 || coe(p[0][0]) == -1 || pipe(p[1]) == -1) goto errp0 ;
     17   if (ndelay_on(p[1][1]) == -1 || coe(p[1][1]) == -1 || pipe(p[2]) == -1) goto errp1 ;
     18   if (ndelay_on(p[2][0]) == -1 || coe(p[2][0]) == -1) goto err ;
     19 
     20   {
     21     cspawn_fileaction fa[2] =
     22     {
     23       [0] = { .type = CSPAWN_FA_MOVE, .x = { .fd2 = { [0] = fds[0], [1] = p[1][0] } } },
     24       [1] = { .type = CSPAWN_FA_MOVE, .x = { .fd2 = { [0] = fds[1], [1] = p[0][1] } } }
     25     } ;
     26     size_t envlen = env_len(envp) ;
     27     size_t m = sizeof(SKALIBS_CHILD_SPAWN_FDS_ENVVAR) ;
     28     char modifs[sizeof(SKALIBS_CHILD_SPAWN_FDS_ENVVAR) + UINT_FMT] = SKALIBS_CHILD_SPAWN_FDS_ENVVAR "=" ;
     29     char const *newenv[envlen + 2] ;
     30     m += uint_fmt(modifs + sizeof(SKALIBS_CHILD_SPAWN_FDS_ENVVAR), p[2][1]) ;
     31     modifs[m++] = 0 ;
     32     env_mergen(newenv, envlen + 2, envp, envlen, modifs, m, 1) ;
     33     pid = cspawn(prog, argv, newenv, CSPAWN_FLAGS_SIGBLOCKNONE, fa, 2) ;
     34     if (!pid) goto err ;
     35   }
     36 
     37   fd_close(p[2][1]) ;
     38   fd_close(p[1][0]) ;
     39   fd_close(p[0][1]) ;
     40   fds[0] = p[0][0] ;
     41   fds[1] = p[1][1] ;
     42   fds[2] = p[2][0] ;
     43   return pid ;
     44 
     45  err:
     46   fd_close(p[2][1]) ;
     47   fd_close(p[2][0]) ;
     48  errp1:
     49   fd_close(p[1][1]) ;
     50   fd_close(p[1][0]) ;
     51  errp0:
     52   fd_close(p[0][1]) ;
     53   fd_close(p[0][0]) ;
     54   return 0 ;
     55 }