1*1b85337dSArnaldo Carvalho de Melo /* 2*1b85337dSArnaldo Carvalho de Melo * Copyright (C) 2014, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 3*1b85337dSArnaldo Carvalho de Melo * 4*1b85337dSArnaldo Carvalho de Melo * Released under the GPL v2. (and only v2, not any later version) 5*1b85337dSArnaldo Carvalho de Melo */ 6*1b85337dSArnaldo Carvalho de Melo #include "array.h" 7*1b85337dSArnaldo Carvalho de Melo #include <errno.h> 8*1b85337dSArnaldo Carvalho de Melo #include <fcntl.h> 9*1b85337dSArnaldo Carvalho de Melo #include <poll.h> 10*1b85337dSArnaldo Carvalho de Melo #include <stdlib.h> 11*1b85337dSArnaldo Carvalho de Melo #include <unistd.h> 12*1b85337dSArnaldo Carvalho de Melo 13*1b85337dSArnaldo Carvalho de Melo void fdarray__init(struct fdarray *fda, int nr_autogrow) 14*1b85337dSArnaldo Carvalho de Melo { 15*1b85337dSArnaldo Carvalho de Melo fda->entries = NULL; 16*1b85337dSArnaldo Carvalho de Melo fda->nr = fda->nr_alloc = 0; 17*1b85337dSArnaldo Carvalho de Melo fda->nr_autogrow = nr_autogrow; 18*1b85337dSArnaldo Carvalho de Melo } 19*1b85337dSArnaldo Carvalho de Melo 20*1b85337dSArnaldo Carvalho de Melo int fdarray__grow(struct fdarray *fda, int nr) 21*1b85337dSArnaldo Carvalho de Melo { 22*1b85337dSArnaldo Carvalho de Melo int nr_alloc = fda->nr_alloc + nr; 23*1b85337dSArnaldo Carvalho de Melo size_t size = sizeof(struct pollfd) * nr_alloc; 24*1b85337dSArnaldo Carvalho de Melo struct pollfd *entries = realloc(fda->entries, size); 25*1b85337dSArnaldo Carvalho de Melo 26*1b85337dSArnaldo Carvalho de Melo if (entries == NULL) 27*1b85337dSArnaldo Carvalho de Melo return -ENOMEM; 28*1b85337dSArnaldo Carvalho de Melo 29*1b85337dSArnaldo Carvalho de Melo fda->nr_alloc = nr_alloc; 30*1b85337dSArnaldo Carvalho de Melo fda->entries = entries; 31*1b85337dSArnaldo Carvalho de Melo return 0; 32*1b85337dSArnaldo Carvalho de Melo } 33*1b85337dSArnaldo Carvalho de Melo 34*1b85337dSArnaldo Carvalho de Melo struct fdarray *fdarray__new(int nr_alloc, int nr_autogrow) 35*1b85337dSArnaldo Carvalho de Melo { 36*1b85337dSArnaldo Carvalho de Melo struct fdarray *fda = calloc(1, sizeof(*fda)); 37*1b85337dSArnaldo Carvalho de Melo 38*1b85337dSArnaldo Carvalho de Melo if (fda != NULL) { 39*1b85337dSArnaldo Carvalho de Melo if (fdarray__grow(fda, nr_alloc)) { 40*1b85337dSArnaldo Carvalho de Melo free(fda); 41*1b85337dSArnaldo Carvalho de Melo fda = NULL; 42*1b85337dSArnaldo Carvalho de Melo } else { 43*1b85337dSArnaldo Carvalho de Melo fda->nr_autogrow = nr_autogrow; 44*1b85337dSArnaldo Carvalho de Melo } 45*1b85337dSArnaldo Carvalho de Melo } 46*1b85337dSArnaldo Carvalho de Melo 47*1b85337dSArnaldo Carvalho de Melo return fda; 48*1b85337dSArnaldo Carvalho de Melo } 49*1b85337dSArnaldo Carvalho de Melo 50*1b85337dSArnaldo Carvalho de Melo void fdarray__exit(struct fdarray *fda) 51*1b85337dSArnaldo Carvalho de Melo { 52*1b85337dSArnaldo Carvalho de Melo free(fda->entries); 53*1b85337dSArnaldo Carvalho de Melo fdarray__init(fda, 0); 54*1b85337dSArnaldo Carvalho de Melo } 55*1b85337dSArnaldo Carvalho de Melo 56*1b85337dSArnaldo Carvalho de Melo void fdarray__delete(struct fdarray *fda) 57*1b85337dSArnaldo Carvalho de Melo { 58*1b85337dSArnaldo Carvalho de Melo fdarray__exit(fda); 59*1b85337dSArnaldo Carvalho de Melo free(fda); 60*1b85337dSArnaldo Carvalho de Melo } 61*1b85337dSArnaldo Carvalho de Melo 62*1b85337dSArnaldo Carvalho de Melo int fdarray__add(struct fdarray *fda, int fd, short revents) 63*1b85337dSArnaldo Carvalho de Melo { 64*1b85337dSArnaldo Carvalho de Melo if (fda->nr == fda->nr_alloc && 65*1b85337dSArnaldo Carvalho de Melo fdarray__grow(fda, fda->nr_autogrow) < 0) 66*1b85337dSArnaldo Carvalho de Melo return -ENOMEM; 67*1b85337dSArnaldo Carvalho de Melo 68*1b85337dSArnaldo Carvalho de Melo fda->entries[fda->nr].fd = fd; 69*1b85337dSArnaldo Carvalho de Melo fda->entries[fda->nr].events = revents; 70*1b85337dSArnaldo Carvalho de Melo fda->nr++; 71*1b85337dSArnaldo Carvalho de Melo return 0; 72*1b85337dSArnaldo Carvalho de Melo } 73*1b85337dSArnaldo Carvalho de Melo 74*1b85337dSArnaldo Carvalho de Melo int fdarray__filter(struct fdarray *fda, short revents) 75*1b85337dSArnaldo Carvalho de Melo { 76*1b85337dSArnaldo Carvalho de Melo int fd, nr = 0; 77*1b85337dSArnaldo Carvalho de Melo 78*1b85337dSArnaldo Carvalho de Melo if (fda->nr == 0) 79*1b85337dSArnaldo Carvalho de Melo return 0; 80*1b85337dSArnaldo Carvalho de Melo 81*1b85337dSArnaldo Carvalho de Melo for (fd = 0; fd < fda->nr; ++fd) { 82*1b85337dSArnaldo Carvalho de Melo if (fda->entries[fd].revents & revents) 83*1b85337dSArnaldo Carvalho de Melo continue; 84*1b85337dSArnaldo Carvalho de Melo 85*1b85337dSArnaldo Carvalho de Melo if (fd != nr) 86*1b85337dSArnaldo Carvalho de Melo fda->entries[nr] = fda->entries[fd]; 87*1b85337dSArnaldo Carvalho de Melo 88*1b85337dSArnaldo Carvalho de Melo ++nr; 89*1b85337dSArnaldo Carvalho de Melo } 90*1b85337dSArnaldo Carvalho de Melo 91*1b85337dSArnaldo Carvalho de Melo return fda->nr = nr; 92*1b85337dSArnaldo Carvalho de Melo } 93*1b85337dSArnaldo Carvalho de Melo 94*1b85337dSArnaldo Carvalho de Melo int fdarray__poll(struct fdarray *fda, int timeout) 95*1b85337dSArnaldo Carvalho de Melo { 96*1b85337dSArnaldo Carvalho de Melo return poll(fda->entries, fda->nr, timeout); 97*1b85337dSArnaldo Carvalho de Melo } 98*1b85337dSArnaldo Carvalho de Melo 99*1b85337dSArnaldo Carvalho de Melo int fdarray__fprintf(struct fdarray *fda, FILE *fp) 100*1b85337dSArnaldo Carvalho de Melo { 101*1b85337dSArnaldo Carvalho de Melo int fd, printed = fprintf(fp, "%d [ ", fda->nr); 102*1b85337dSArnaldo Carvalho de Melo 103*1b85337dSArnaldo Carvalho de Melo for (fd = 0; fd < fda->nr; ++fd) 104*1b85337dSArnaldo Carvalho de Melo printed += fprintf(fp, "%s%d", fd ? ", " : "", fda->entries[fd].fd); 105*1b85337dSArnaldo Carvalho de Melo 106*1b85337dSArnaldo Carvalho de Melo return printed + fprintf(fp, " ]"); 107*1b85337dSArnaldo Carvalho de Melo } 108