skalibs

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

gcspawn.c (1100B)


      1 /* ISC license. */
      2 
      3 #include <sys/wait.h>
      4 #include <unistd.h>
      5 #include <errno.h>
      6 
      7 #include <skalibs/types.h>
      8 #include <skalibs/allreadwrite.h>
      9 #include <skalibs/djbunix.h>
     10 #include <skalibs/cspawn.h>
     11 
     12 pid_t gcspawn (char const *prog, char const *const *argv, char const *const *envp, uint16_t flags, cspawn_fileaction const *fa, size_t n)
     13 {
     14   pid_t pid = 0 ;
     15   int wstat ;
     16   int p[2] ;
     17   char pack[PID_PACK] ;
     18   if (pipecoe(p) == -1) return 0 ;
     19   pid = fork() ;
     20   switch (pid)
     21   {
     22     case -1:
     23     {
     24       fd_close(p[1]) ;
     25       fd_close(p[0]) ;
     26       return 0 ;
     27     }
     28     case 0:
     29     {
     30       fd_close(p[0]) ;
     31       pid = cspawn(prog, argv, envp, flags, fa, n) ;
     32       if (!pid) _exit(errno) ;
     33       pid_pack_big(pack, pid) ;
     34       _exit(fd_write(p[1], pack, PID_PACK) < PID_PACK ? errno : 0) ;
     35     }
     36   }
     37   fd_close(p[1]) ;
     38   if (fd_read(p[0], pack, PID_PACK) < PID_PACK) goto err ;
     39   fd_close(p[0]) ;
     40   wait_pid(pid, &wstat) ;
     41   pid_unpack_big(pack, &pid) ;
     42   return pid ;
     43 
     44  err:
     45   fd_close(p[0]) ;
     46   wait_pid(pid, &wstat) ;
     47   return (errno = WIFSIGNALED(wstat) ? EINTR : WEXITSTATUS(wstat), 0) ;
     48 }