s6

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

ftrigw_notifyb_nosig.c (1643B)


      1 /* ISC license. */
      2 
      3 #include <string.h>
      4 #include <unistd.h>
      5 #include <errno.h>
      6 
      7 #include <skalibs/posixplz.h>
      8 #include <skalibs/direntry.h>
      9 #include <skalibs/allreadwrite.h>
     10 #include <skalibs/djbunix.h>
     11 
     12 #include <s6/ftrigw.h>
     13 #include "ftrig1.h"
     14 
     15 int ftrigw_notifyb_nosig (char const *path, char const *s, size_t len)
     16 {
     17   unsigned int i = 0 ;
     18   DIR *dir = opendir(path) ;
     19   if (!dir) return -1 ;
     20   {
     21     size_t pathlen = strlen(path) ;
     22     char tmp[pathlen + FTRIG1_PREFIXLEN + 35] ;
     23     memcpy(tmp, path, pathlen) ;
     24     tmp[pathlen] = '/' ;
     25     tmp[pathlen + FTRIG1_PREFIXLEN + 34] = 0 ;
     26     for (;;)
     27     {
     28       direntry *d ;
     29       int fd ;
     30       errno = 0 ;
     31       d = readdir(dir) ;
     32       if (!d) break ;
     33       if (strncmp(d->d_name, FTRIG1_PREFIX ":@", FTRIG1_PREFIXLEN + 2)) continue ;
     34       if (strlen(d->d_name) != FTRIG1_PREFIXLEN + 33) continue ;
     35       memcpy(tmp + pathlen + 1, d->d_name, FTRIG1_PREFIXLEN + 33) ;
     36       fd = open_write(tmp) ;
     37       if (fd == -1)
     38       {
     39         if (errno == ENXIO) unlink_void(tmp) ;
     40       }
     41       else
     42       {
     43         ssize_t r = fd_write(fd, s, len) ;
     44         if ((r < 0) || (size_t)r < len)
     45         {
     46           if (errno == EPIPE) unlink_void(tmp) ;
     47            /* what to do if EAGAIN ? full fifo -> fix the reader !
     48               There's a race condition in extreme cases though ;
     49               but it's still better to be nonblocking - the writer
     50               shouldn't get in trouble because of a bad reader. */
     51           fd_close(fd) ;
     52         }
     53         else
     54         {
     55           fd_close(fd) ;
     56           i++ ;
     57         }
     58       }
     59     }
     60   }
     61   dir_close(dir) ;
     62   return errno ? -1 : (int)i ;
     63 }