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