s6

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

s6-fdholder-getdump.c (2751B)


      1 /* ISC license. */
      2 
      3 #include <string.h>
      4 #include <limits.h>
      5 
      6 #include <skalibs/types.h>
      7 #include <skalibs/strerr.h>
      8 #include <skalibs/sgetopt.h>
      9 #include <skalibs/tai.h>
     10 #include <skalibs/djbunix.h>
     11 #include <skalibs/genalloc.h>
     12 #include <skalibs/exec.h>
     13 
     14 #include <s6/fdholder.h>
     15 
     16 #define USAGE "s6-fdholder-getdump [ -t timeout ] socket prog..."
     17 #define dieusage() strerr_dieusage(100, USAGE)
     18 
     19 int main (int argc, char const *const *argv, char const *const *envp)
     20 {
     21   s6_fdholder_t a = S6_FDHOLDER_ZERO ;
     22   genalloc dump = GENALLOC_ZERO ;
     23   tain deadline, halfinfinite ;
     24   PROG = "s6-fdholder-getdump" ;
     25   {
     26     unsigned int t = 0 ;
     27     subgetopt l = SUBGETOPT_ZERO ;
     28     for (;;)
     29     {
     30       int opt = subgetopt_r(argc, argv, "t:", &l) ;
     31       if (opt == -1) break ;
     32       switch (opt)
     33       {
     34         case 't' : if (!uint0_scan(l.arg, &t)) dieusage() ; break ;
     35         default : dieusage() ;
     36       }
     37     }
     38     argc -= l.ind ; argv += l.ind ;
     39     if (t) tain_from_millisecs(&deadline, t) ;
     40     else deadline = tain_infinite_relative ;
     41   }
     42   if (argc < 2) dieusage() ;
     43 
     44   tain_now_set_stopwatch_g() ;
     45   tain_add_g(&deadline, &deadline) ;
     46   if (!s6_fdholder_start_g(&a, argv[0], &deadline))
     47     strerr_diefu2sys(111, "connect to a fd-holder daemon at ", argv[0]) ;
     48   if (!s6_fdholder_getdump_g(&a, &dump, &deadline))
     49     strerr_diefu1sys(1, "get dump") ;
     50   s6_fdholder_end(&a) ;
     51   tain_half(&halfinfinite, &tain_infinite_relative) ;
     52   tain_add_g(&halfinfinite, &halfinfinite) ;
     53   {
     54     size_t n = genalloc_len(s6_fdholder_fd_t, &dump) ;
     55     size_t pos = 0 ;
     56     unsigned int i = 0 ;
     57     char modifs[7 + UINT_FMT + (25 + TIMESTAMP + 4 * UINT_FMT) * n] ;
     58     if (n > UINT_MAX) strerr_dief1x(100, "dump exceeds maximum size") ;
     59     memcpy(modifs + pos, "S6_FD#=", 7) ; pos += 7 ;
     60     pos += uint_fmt(modifs + pos, n) ;
     61     modifs[pos++] = 0 ;
     62     for (; i < n ; i++)
     63     {
     64       s6_fdholder_fd_t *p = genalloc_s(s6_fdholder_fd_t, &dump) + i ;
     65       size_t len = strlen(p->id) + 1 ;
     66       if (uncoe(p->fd) < 0) strerr_diefu1sys(111, "uncoe") ;
     67       memcpy(modifs + pos, "S6_FD_", 6) ; pos += 6 ;
     68       pos += uint_fmt(modifs + pos, i) ;
     69       modifs[pos++] = '=' ;
     70       pos += uint_fmt(modifs + pos, p->fd) ;
     71       modifs[pos++] = 0 ;
     72       memcpy(modifs + pos, "S6_FDID_", 8) ; pos += 8 ;
     73       pos += uint_fmt(modifs + pos, i) ;
     74       modifs[pos++] = '=' ;
     75       memcpy(modifs + pos, p->id, len) ;
     76       pos += len ;
     77       memcpy(modifs + pos, "S6_FDLIMIT_", 11) ; pos += 11 ;
     78       pos += uint_fmt(modifs + pos, i) ;
     79       if (tain_less(&p->limit, &halfinfinite))
     80       {
     81         modifs[pos++] = '=' ;
     82         pos += timestamp_fmt(modifs + pos, &p->limit) ;
     83       }
     84       modifs[pos++] = 0 ;
     85     }
     86     xmexec_n(argv+1, modifs, pos, 1 + 3*n) ;
     87   }
     88 }