Fix: cppcheck linter cleanups
[lttng-tools.git] / src / common / compat / compat-poll.c
... / ...
CommitLineData
1/*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2 only,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
18#define _GNU_SOURCE
19#include <stdlib.h>
20#include <sys/resource.h>
21#include <sys/time.h>
22
23#include <common/defaults.h>
24#include <common/error.h>
25
26#include "poll.h"
27
28unsigned int poll_max_size;
29
30/*
31 * Create pollfd data structure.
32 */
33int compat_poll_create(struct lttng_poll_event *events, int size)
34{
35 if (events == NULL || size <= 0) {
36 ERR("Wrong arguments for poll create");
37 goto error;
38 }
39
40 /* Don't bust the limit here */
41 if (size > poll_max_size) {
42 size = poll_max_size;
43 }
44
45 /* This *must* be freed by using lttng_poll_free() */
46 events->events = zmalloc(size * sizeof(struct pollfd));
47 if (events->events == NULL) {
48 perror("zmalloc struct pollfd");
49 goto error;
50 }
51
52 events->events_size = size;
53 events->nb_fd = 0;
54
55 return 0;
56
57error:
58 return -1;
59}
60
61/*
62 * Add fd to pollfd data structure with requested events.
63 */
64int compat_poll_add(struct lttng_poll_event *events, int fd,
65 uint32_t req_events)
66{
67 int new_size;
68 struct pollfd *ptr;
69
70 if (events == NULL || events->events == NULL || fd < 0) {
71 ERR("Bad compat poll add arguments");
72 goto error;
73 }
74
75 /* Reallocate pollfd structure by a factor of 2 if needed. */
76 if (events->nb_fd >= events->events_size) {
77 new_size = 2 * events->events_size;
78 ptr = realloc(events->events, new_size * sizeof(struct pollfd));
79 if (ptr == NULL) {
80 perror("realloc poll add");
81 goto error;
82 }
83 events->events = ptr;
84 events->events_size = new_size;
85 }
86
87 events->events[events->nb_fd].fd = fd;
88 events->events[events->nb_fd].events = req_events;
89 events->nb_fd++;
90
91 DBG("fd %d of %d added to pollfd", fd, events->nb_fd);
92
93 return 0;
94
95error:
96 return -1;
97}
98
99/*
100 * Remove a fd from the pollfd structure.
101 */
102int compat_poll_del(struct lttng_poll_event *events, int fd)
103{
104 int new_size, i, count = 0;
105 struct pollfd *old = NULL, *new = NULL;
106
107 if (events == NULL || events->events == NULL || fd < 0) {
108 ERR("Wrong arguments for poll del");
109 goto error;
110 }
111
112 old = events->events;
113 new_size = events->events_size - 1;
114
115 /* Safety check on size */
116 if (new_size > poll_max_size) {
117 new_size = poll_max_size;
118 }
119
120 new = zmalloc(new_size * sizeof(struct pollfd));
121 if (new == NULL) {
122 perror("zmalloc poll del");
123 goto error;
124 }
125
126 for (i = 0; i < events->events_size; i++) {
127 /* Don't put back the fd we want to delete */
128 if (old[i].fd != fd) {
129 new[count].fd = old[i].fd;
130 new[count].events = old[i].events;
131 count++;
132 }
133 }
134
135 events->events_size = new_size;
136 events->events = new;
137 events->nb_fd--;
138
139 free(old);
140
141 return 0;
142
143error:
144 return -1;
145}
146
147/*
148 * Wait on poll() with timeout. Blocking call.
149 */
150int compat_poll_wait(struct lttng_poll_event *events, int timeout)
151{
152 int ret;
153
154 if (events == NULL || events->events == NULL ||
155 events->events_size < events->nb_fd) {
156 ERR("poll wait arguments error");
157 goto error;
158 }
159
160 ret = poll(events->events, events->nb_fd, timeout);
161 if (ret < 0) {
162 /* At this point, every error is fatal */
163 perror("poll wait");
164 goto error;
165 }
166
167 /*
168 * poll() should always iterate on all FDs since we handle the pollset in
169 * user space and after poll returns, we have to try every fd for a match.
170 */
171 return events->nb_fd;
172
173error:
174 return -1;
175}
176
177/*
178 * Setup poll set maximum size.
179 */
180void compat_poll_set_max_size(void)
181{
182 int ret;
183 struct rlimit lim;
184
185 /* Default value */
186 poll_max_size = DEFAULT_POLL_SIZE;
187
188 ret = getrlimit(RLIMIT_NOFILE, &lim);
189 if (ret < 0) {
190 perror("getrlimit poll RLIMIT_NOFILE");
191 return;
192 }
193
194 poll_max_size = lim.rlim_cur;
195 if (poll_max_size <= 0) {
196 /* Extra precaution */
197 poll_max_size = DEFAULT_POLL_SIZE;
198 }
199
200 DBG("poll set max size set to %u", poll_max_size);
201}
This page took 0.02273 seconds and 4 git commands to generate.