Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2014, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
0004  */
0005 #include "array.h"
0006 #include <errno.h>
0007 #include <fcntl.h>
0008 #include <poll.h>
0009 #include <stdlib.h>
0010 #include <unistd.h>
0011 #include <string.h>
0012 
0013 void fdarray__init(struct fdarray *fda, int nr_autogrow)
0014 {
0015     fda->entries     = NULL;
0016     fda->priv    = NULL;
0017     fda->nr      = fda->nr_alloc = 0;
0018     fda->nr_autogrow = nr_autogrow;
0019 }
0020 
0021 int fdarray__grow(struct fdarray *fda, int nr)
0022 {
0023     struct priv *priv;
0024     int nr_alloc = fda->nr_alloc + nr;
0025     size_t psize = sizeof(fda->priv[0]) * nr_alloc;
0026     size_t size  = sizeof(struct pollfd) * nr_alloc;
0027     struct pollfd *entries = realloc(fda->entries, size);
0028 
0029     if (entries == NULL)
0030         return -ENOMEM;
0031 
0032     priv = realloc(fda->priv, psize);
0033     if (priv == NULL) {
0034         free(entries);
0035         return -ENOMEM;
0036     }
0037 
0038     memset(&entries[fda->nr_alloc], 0, sizeof(struct pollfd) * nr);
0039     memset(&priv[fda->nr_alloc], 0, sizeof(fda->priv[0]) * nr);
0040 
0041     fda->nr_alloc = nr_alloc;
0042     fda->entries  = entries;
0043     fda->priv     = priv;
0044     return 0;
0045 }
0046 
0047 struct fdarray *fdarray__new(int nr_alloc, int nr_autogrow)
0048 {
0049     struct fdarray *fda = calloc(1, sizeof(*fda));
0050 
0051     if (fda != NULL) {
0052         if (fdarray__grow(fda, nr_alloc)) {
0053             free(fda);
0054             fda = NULL;
0055         } else {
0056             fda->nr_autogrow = nr_autogrow;
0057         }
0058     }
0059 
0060     return fda;
0061 }
0062 
0063 void fdarray__exit(struct fdarray *fda)
0064 {
0065     free(fda->entries);
0066     free(fda->priv);
0067     fdarray__init(fda, 0);
0068 }
0069 
0070 void fdarray__delete(struct fdarray *fda)
0071 {
0072     fdarray__exit(fda);
0073     free(fda);
0074 }
0075 
0076 int fdarray__add(struct fdarray *fda, int fd, short revents, enum fdarray_flags flags)
0077 {
0078     int pos = fda->nr;
0079 
0080     if (fda->nr == fda->nr_alloc &&
0081         fdarray__grow(fda, fda->nr_autogrow) < 0)
0082         return -ENOMEM;
0083 
0084     fda->entries[fda->nr].fd     = fd;
0085     fda->entries[fda->nr].events = revents;
0086     fda->priv[fda->nr].flags = flags;
0087     fda->nr++;
0088     return pos;
0089 }
0090 
0091 int fdarray__dup_entry_from(struct fdarray *fda, int pos, struct fdarray *from)
0092 {
0093     struct pollfd *entry;
0094     int npos;
0095 
0096     if (pos >= from->nr)
0097         return -EINVAL;
0098 
0099     entry = &from->entries[pos];
0100 
0101     npos = fdarray__add(fda, entry->fd, entry->events, from->priv[pos].flags);
0102     if (npos >= 0)
0103         fda->priv[npos] = from->priv[pos];
0104 
0105     return npos;
0106 }
0107 
0108 int fdarray__filter(struct fdarray *fda, short revents,
0109             void (*entry_destructor)(struct fdarray *fda, int fd, void *arg),
0110             void *arg)
0111 {
0112     int fd, nr = 0;
0113 
0114     if (fda->nr == 0)
0115         return 0;
0116 
0117     for (fd = 0; fd < fda->nr; ++fd) {
0118         if (!fda->entries[fd].events)
0119             continue;
0120 
0121         if (fda->entries[fd].revents & revents) {
0122             if (entry_destructor)
0123                 entry_destructor(fda, fd, arg);
0124 
0125             fda->entries[fd].revents = fda->entries[fd].events = 0;
0126             continue;
0127         }
0128 
0129         if (!(fda->priv[fd].flags & fdarray_flag__nonfilterable))
0130             ++nr;
0131     }
0132 
0133     return nr;
0134 }
0135 
0136 int fdarray__poll(struct fdarray *fda, int timeout)
0137 {
0138     return poll(fda->entries, fda->nr, timeout);
0139 }
0140 
0141 int fdarray__fprintf(struct fdarray *fda, FILE *fp)
0142 {
0143     int fd, printed = fprintf(fp, "%d [ ", fda->nr);
0144 
0145     for (fd = 0; fd < fda->nr; ++fd)
0146         printed += fprintf(fp, "%s%d", fd ? ", " : "", fda->entries[fd].fd);
0147 
0148     return printed + fprintf(fp, " ]");
0149 }