Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/lib/api/fd/array.c
26292 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* Copyright (C) 2014, Red Hat Inc, Arnaldo Carvalho de Melo <[email protected]>
4
*/
5
#include "array.h"
6
#include <errno.h>
7
#include <fcntl.h>
8
#include <poll.h>
9
#include <stdlib.h>
10
#include <unistd.h>
11
#include <string.h>
12
13
void fdarray__init(struct fdarray *fda, int nr_autogrow)
14
{
15
fda->entries = NULL;
16
fda->priv = NULL;
17
fda->nr = fda->nr_alloc = 0;
18
fda->nr_autogrow = nr_autogrow;
19
}
20
21
int fdarray__grow(struct fdarray *fda, int nr)
22
{
23
struct priv *priv;
24
int nr_alloc = fda->nr_alloc + nr;
25
size_t psize = sizeof(fda->priv[0]) * nr_alloc;
26
size_t size = sizeof(struct pollfd) * nr_alloc;
27
struct pollfd *entries = realloc(fda->entries, size);
28
29
if (entries == NULL)
30
return -ENOMEM;
31
32
priv = realloc(fda->priv, psize);
33
if (priv == NULL) {
34
free(entries);
35
return -ENOMEM;
36
}
37
38
memset(&entries[fda->nr_alloc], 0, sizeof(struct pollfd) * nr);
39
memset(&priv[fda->nr_alloc], 0, sizeof(fda->priv[0]) * nr);
40
41
fda->nr_alloc = nr_alloc;
42
fda->entries = entries;
43
fda->priv = priv;
44
return 0;
45
}
46
47
struct fdarray *fdarray__new(int nr_alloc, int nr_autogrow)
48
{
49
struct fdarray *fda = calloc(1, sizeof(*fda));
50
51
if (fda != NULL) {
52
if (fdarray__grow(fda, nr_alloc)) {
53
free(fda);
54
fda = NULL;
55
} else {
56
fda->nr_autogrow = nr_autogrow;
57
}
58
}
59
60
return fda;
61
}
62
63
void fdarray__exit(struct fdarray *fda)
64
{
65
free(fda->entries);
66
free(fda->priv);
67
fdarray__init(fda, 0);
68
}
69
70
void fdarray__delete(struct fdarray *fda)
71
{
72
fdarray__exit(fda);
73
free(fda);
74
}
75
76
int fdarray__add(struct fdarray *fda, int fd, short revents, enum fdarray_flags flags)
77
{
78
int pos = fda->nr;
79
80
if (fda->nr == fda->nr_alloc &&
81
fdarray__grow(fda, fda->nr_autogrow) < 0)
82
return -ENOMEM;
83
84
fda->entries[fda->nr].fd = fd;
85
fda->entries[fda->nr].events = revents;
86
fda->priv[fda->nr].flags = flags;
87
fda->nr++;
88
return pos;
89
}
90
91
int fdarray__dup_entry_from(struct fdarray *fda, int pos, struct fdarray *from)
92
{
93
struct pollfd *entry;
94
int npos;
95
96
if (pos >= from->nr)
97
return -EINVAL;
98
99
entry = &from->entries[pos];
100
101
npos = fdarray__add(fda, entry->fd, entry->events, from->priv[pos].flags);
102
if (npos >= 0)
103
fda->priv[npos] = from->priv[pos];
104
105
return npos;
106
}
107
108
int fdarray__filter(struct fdarray *fda, short revents,
109
void (*entry_destructor)(struct fdarray *fda, int fd, void *arg),
110
void *arg)
111
{
112
int fd, nr = 0;
113
114
if (fda->nr == 0)
115
return 0;
116
117
for (fd = 0; fd < fda->nr; ++fd) {
118
if (!fda->entries[fd].events)
119
continue;
120
121
if (fda->entries[fd].revents & revents) {
122
if (entry_destructor)
123
entry_destructor(fda, fd, arg);
124
125
fda->entries[fd].revents = fda->entries[fd].events = 0;
126
continue;
127
}
128
129
if (!(fda->priv[fd].flags & fdarray_flag__nonfilterable))
130
++nr;
131
}
132
133
return nr;
134
}
135
136
int fdarray__poll(struct fdarray *fda, int timeout)
137
{
138
return poll(fda->entries, fda->nr, timeout);
139
}
140
141
int fdarray__fprintf(struct fdarray *fda, FILE *fp)
142
{
143
int fd, printed = fprintf(fp, "%d [ ", fda->nr);
144
145
for (fd = 0; fd < fda->nr; ++fd)
146
printed += fprintf(fp, "%s%d", fd ? ", " : "", fda->entries[fd].fd);
147
148
return printed + fprintf(fp, " ]");
149
}
150
151