11b85337dSArnaldo Carvalho de Melo /* 21b85337dSArnaldo Carvalho de Melo * Copyright (C) 2014, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 31b85337dSArnaldo Carvalho de Melo * 41b85337dSArnaldo Carvalho de Melo * Released under the GPL v2. (and only v2, not any later version) 51b85337dSArnaldo Carvalho de Melo */ 61b85337dSArnaldo Carvalho de Melo #include "array.h" 71b85337dSArnaldo Carvalho de Melo #include <errno.h> 81b85337dSArnaldo Carvalho de Melo #include <fcntl.h> 91b85337dSArnaldo Carvalho de Melo #include <poll.h> 101b85337dSArnaldo Carvalho de Melo #include <stdlib.h> 111b85337dSArnaldo Carvalho de Melo #include <unistd.h> 121b85337dSArnaldo Carvalho de Melo 131b85337dSArnaldo Carvalho de Melo void fdarray__init(struct fdarray *fda, int nr_autogrow) 141b85337dSArnaldo Carvalho de Melo { 151b85337dSArnaldo Carvalho de Melo fda->entries = NULL; 16*2171a925SArnaldo Carvalho de Melo fda->priv = NULL; 171b85337dSArnaldo Carvalho de Melo fda->nr = fda->nr_alloc = 0; 181b85337dSArnaldo Carvalho de Melo fda->nr_autogrow = nr_autogrow; 191b85337dSArnaldo Carvalho de Melo } 201b85337dSArnaldo Carvalho de Melo 211b85337dSArnaldo Carvalho de Melo int fdarray__grow(struct fdarray *fda, int nr) 221b85337dSArnaldo Carvalho de Melo { 23*2171a925SArnaldo Carvalho de Melo void *priv; 241b85337dSArnaldo Carvalho de Melo int nr_alloc = fda->nr_alloc + nr; 25*2171a925SArnaldo Carvalho de Melo size_t psize = sizeof(fda->priv[0]) * nr_alloc; 261b85337dSArnaldo Carvalho de Melo size_t size = sizeof(struct pollfd) * nr_alloc; 271b85337dSArnaldo Carvalho de Melo struct pollfd *entries = realloc(fda->entries, size); 281b85337dSArnaldo Carvalho de Melo 291b85337dSArnaldo Carvalho de Melo if (entries == NULL) 301b85337dSArnaldo Carvalho de Melo return -ENOMEM; 311b85337dSArnaldo Carvalho de Melo 32*2171a925SArnaldo Carvalho de Melo priv = realloc(fda->priv, psize); 33*2171a925SArnaldo Carvalho de Melo if (priv == NULL) { 34*2171a925SArnaldo Carvalho de Melo free(entries); 35*2171a925SArnaldo Carvalho de Melo return -ENOMEM; 36*2171a925SArnaldo Carvalho de Melo } 37*2171a925SArnaldo Carvalho de Melo 381b85337dSArnaldo Carvalho de Melo fda->nr_alloc = nr_alloc; 391b85337dSArnaldo Carvalho de Melo fda->entries = entries; 40*2171a925SArnaldo Carvalho de Melo fda->priv = priv; 411b85337dSArnaldo Carvalho de Melo return 0; 421b85337dSArnaldo Carvalho de Melo } 431b85337dSArnaldo Carvalho de Melo 441b85337dSArnaldo Carvalho de Melo struct fdarray *fdarray__new(int nr_alloc, int nr_autogrow) 451b85337dSArnaldo Carvalho de Melo { 461b85337dSArnaldo Carvalho de Melo struct fdarray *fda = calloc(1, sizeof(*fda)); 471b85337dSArnaldo Carvalho de Melo 481b85337dSArnaldo Carvalho de Melo if (fda != NULL) { 491b85337dSArnaldo Carvalho de Melo if (fdarray__grow(fda, nr_alloc)) { 501b85337dSArnaldo Carvalho de Melo free(fda); 511b85337dSArnaldo Carvalho de Melo fda = NULL; 521b85337dSArnaldo Carvalho de Melo } else { 531b85337dSArnaldo Carvalho de Melo fda->nr_autogrow = nr_autogrow; 541b85337dSArnaldo Carvalho de Melo } 551b85337dSArnaldo Carvalho de Melo } 561b85337dSArnaldo Carvalho de Melo 571b85337dSArnaldo Carvalho de Melo return fda; 581b85337dSArnaldo Carvalho de Melo } 591b85337dSArnaldo Carvalho de Melo 601b85337dSArnaldo Carvalho de Melo void fdarray__exit(struct fdarray *fda) 611b85337dSArnaldo Carvalho de Melo { 621b85337dSArnaldo Carvalho de Melo free(fda->entries); 63*2171a925SArnaldo Carvalho de Melo free(fda->priv); 641b85337dSArnaldo Carvalho de Melo fdarray__init(fda, 0); 651b85337dSArnaldo Carvalho de Melo } 661b85337dSArnaldo Carvalho de Melo 671b85337dSArnaldo Carvalho de Melo void fdarray__delete(struct fdarray *fda) 681b85337dSArnaldo Carvalho de Melo { 691b85337dSArnaldo Carvalho de Melo fdarray__exit(fda); 701b85337dSArnaldo Carvalho de Melo free(fda); 711b85337dSArnaldo Carvalho de Melo } 721b85337dSArnaldo Carvalho de Melo 731b85337dSArnaldo Carvalho de Melo int fdarray__add(struct fdarray *fda, int fd, short revents) 741b85337dSArnaldo Carvalho de Melo { 75*2171a925SArnaldo Carvalho de Melo int pos = fda->nr; 76*2171a925SArnaldo Carvalho de Melo 771b85337dSArnaldo Carvalho de Melo if (fda->nr == fda->nr_alloc && 781b85337dSArnaldo Carvalho de Melo fdarray__grow(fda, fda->nr_autogrow) < 0) 791b85337dSArnaldo Carvalho de Melo return -ENOMEM; 801b85337dSArnaldo Carvalho de Melo 811b85337dSArnaldo Carvalho de Melo fda->entries[fda->nr].fd = fd; 821b85337dSArnaldo Carvalho de Melo fda->entries[fda->nr].events = revents; 831b85337dSArnaldo Carvalho de Melo fda->nr++; 84*2171a925SArnaldo Carvalho de Melo return pos; 851b85337dSArnaldo Carvalho de Melo } 861b85337dSArnaldo Carvalho de Melo 87*2171a925SArnaldo Carvalho de Melo int fdarray__filter(struct fdarray *fda, short revents, 88*2171a925SArnaldo Carvalho de Melo void (*entry_destructor)(struct fdarray *fda, int fd)) 891b85337dSArnaldo Carvalho de Melo { 901b85337dSArnaldo Carvalho de Melo int fd, nr = 0; 911b85337dSArnaldo Carvalho de Melo 921b85337dSArnaldo Carvalho de Melo if (fda->nr == 0) 931b85337dSArnaldo Carvalho de Melo return 0; 941b85337dSArnaldo Carvalho de Melo 951b85337dSArnaldo Carvalho de Melo for (fd = 0; fd < fda->nr; ++fd) { 96*2171a925SArnaldo Carvalho de Melo if (fda->entries[fd].revents & revents) { 97*2171a925SArnaldo Carvalho de Melo if (entry_destructor) 98*2171a925SArnaldo Carvalho de Melo entry_destructor(fda, fd); 991b85337dSArnaldo Carvalho de Melo 100*2171a925SArnaldo Carvalho de Melo continue; 101*2171a925SArnaldo Carvalho de Melo } 102*2171a925SArnaldo Carvalho de Melo 103*2171a925SArnaldo Carvalho de Melo if (fd != nr) { 1041b85337dSArnaldo Carvalho de Melo fda->entries[nr] = fda->entries[fd]; 105*2171a925SArnaldo Carvalho de Melo fda->priv[nr] = fda->priv[fd]; 106*2171a925SArnaldo Carvalho de Melo } 1071b85337dSArnaldo Carvalho de Melo 1081b85337dSArnaldo Carvalho de Melo ++nr; 1091b85337dSArnaldo Carvalho de Melo } 1101b85337dSArnaldo Carvalho de Melo 1111b85337dSArnaldo Carvalho de Melo return fda->nr = nr; 1121b85337dSArnaldo Carvalho de Melo } 1131b85337dSArnaldo Carvalho de Melo 1141b85337dSArnaldo Carvalho de Melo int fdarray__poll(struct fdarray *fda, int timeout) 1151b85337dSArnaldo Carvalho de Melo { 1161b85337dSArnaldo Carvalho de Melo return poll(fda->entries, fda->nr, timeout); 1171b85337dSArnaldo Carvalho de Melo } 1181b85337dSArnaldo Carvalho de Melo 1191b85337dSArnaldo Carvalho de Melo int fdarray__fprintf(struct fdarray *fda, FILE *fp) 1201b85337dSArnaldo Carvalho de Melo { 1211b85337dSArnaldo Carvalho de Melo int fd, printed = fprintf(fp, "%d [ ", fda->nr); 1221b85337dSArnaldo Carvalho de Melo 1231b85337dSArnaldo Carvalho de Melo for (fd = 0; fd < fda->nr; ++fd) 1241b85337dSArnaldo Carvalho de Melo printed += fprintf(fp, "%s%d", fd ? ", " : "", fda->entries[fd].fd); 1251b85337dSArnaldo Carvalho de Melo 1261b85337dSArnaldo Carvalho de Melo return printed + fprintf(fp, " ]"); 1271b85337dSArnaldo Carvalho de Melo } 128