Fix missing _GNU_SOURCE define
[lttng-tools.git] / src / common / compat / compat-poll.c
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 it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; only version 2 of the License.
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 with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307, 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
28 unsigned int poll_max_size;
29
30 /*
31 * Create pollfd data structure.
32 */
33 int 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
57 error:
58 return -1;
59 }
60
61 /*
62 * Add fd to pollfd data structure with requested events.
63 */
64 int 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
95 error:
96 return -1;
97 }
98
99 /*
100 * Remove a fd from the pollfd structure.
101 */
102 int 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
143 error:
144 return -1;
145 }
146
147 /*
148 * Wait on poll() with timeout. Blocking call.
149 */
150 int 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 return ret;
168
169 error:
170 return -1;
171 }
172
173 /*
174 * Setup poll set maximum size.
175 */
176 void compat_poll_set_max_size(void)
177 {
178 int ret;
179 struct rlimit lim;
180
181 /* Default value */
182 poll_max_size = DEFAULT_POLL_SIZE;
183
184 ret = getrlimit(RLIMIT_NOFILE, &lim);
185 if (ret < 0) {
186 perror("getrlimit poll RLIMIT_NOFILE");
187 return;
188 }
189
190 poll_max_size = lim.rlim_cur;
191 if (poll_max_size <= 0) {
192 /* Extra precaution */
193 poll_max_size = DEFAULT_POLL_SIZE;
194 }
195
196 DBG("poll set max size set to %u", poll_max_size);
197 }
This page took 0.035449 seconds and 5 git commands to generate.