Fix: improve need root for kernel tracing error message
[lttng-tools.git] / src / common / compat / compat-poll.c
CommitLineData
5eb91c98
DG
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#include <stdlib.h>
19#include <sys/resource.h>
20#include <sys/time.h>
21
990570ed 22#include <common/defaults.h>
db758600 23#include <common/error.h>
5eb91c98
DG
24
25#include "poll.h"
26
27unsigned int poll_max_size;
28
29/*
30 * Create pollfd data structure.
31 */
32int compat_poll_create(struct lttng_poll_event *events, int size)
33{
34 if (events == NULL || size <= 0) {
35 ERR("Wrong arguments for poll create");
36 goto error;
37 }
38
39 /* Don't bust the limit here */
40 if (size > poll_max_size) {
41 size = poll_max_size;
42 }
43
44 /* This *must* be freed by using lttng_poll_free() */
45 events->events = zmalloc(size * sizeof(struct pollfd));
46 if (events->events == NULL) {
ba7f0ae5 47 perror("zmalloc struct pollfd");
5eb91c98
DG
48 goto error;
49 }
50
51 events->events_size = size;
52 events->nb_fd = 0;
53
54 return 0;
55
56error:
57 return -1;
58}
59
60/*
61 * Add fd to pollfd data structure with requested events.
62 */
63int compat_poll_add(struct lttng_poll_event *events, int fd,
64 uint32_t req_events)
65{
66 int new_size;
67 struct pollfd *ptr;
68
69 if (events == NULL || events->events == NULL || fd < 0) {
70 ERR("Bad compat poll add arguments");
71 goto error;
72 }
73
74 /* Reallocate pollfd structure by a factor of 2 if needed. */
75 if (events->nb_fd >= events->events_size) {
76 new_size = 2 * events->events_size;
77 ptr = realloc(events->events, new_size * sizeof(struct pollfd));
78 if (ptr == NULL) {
79 perror("realloc poll add");
80 goto error;
81 }
82 events->events = ptr;
83 events->events_size = new_size;
84 }
85
86 events->events[events->nb_fd].fd = fd;
87 events->events[events->nb_fd].events = req_events;
88 events->nb_fd++;
89
90 DBG("fd %d of %d added to pollfd", fd, events->nb_fd);
91
92 return 0;
93
94error:
95 return -1;
96}
97
98/*
99 * Remove a fd from the pollfd structure.
100 */
101int compat_poll_del(struct lttng_poll_event *events, int fd)
102{
103 int new_size, i, count = 0;
104 struct pollfd *old = NULL, *new = NULL;
105
106 if (events == NULL || events->events == NULL || fd < 0) {
107 ERR("Wrong arguments for poll del");
108 goto error;
109 }
110
111 old = events->events;
112 new_size = events->events_size - 1;
113
114 /* Safety check on size */
115 if (new_size > poll_max_size) {
116 new_size = poll_max_size;
117 }
118
119 new = zmalloc(new_size * sizeof(struct pollfd));
120 if (new == NULL) {
ba7f0ae5 121 perror("zmalloc poll del");
5eb91c98
DG
122 goto error;
123 }
124
125 for (i = 0; i < events->events_size; i++) {
126 /* Don't put back the fd we want to delete */
127 if (old[i].fd != fd) {
128 new[count].fd = old[i].fd;
129 new[count].events = old[i].events;
130 count++;
131 }
132 }
133
134 events->events_size = new_size;
135 events->events = new;
136 events->nb_fd--;
137
138 free(old);
139
140 return 0;
141
142error:
143 return -1;
144}
145
146/*
147 * Wait on poll() with timeout. Blocking call.
148 */
149int compat_poll_wait(struct lttng_poll_event *events, int timeout)
150{
151 int ret;
152
153 if (events == NULL || events->events == NULL ||
154 events->events_size < events->nb_fd) {
155 ERR("poll wait arguments error");
156 goto error;
157 }
158
159 ret = poll(events->events, events->nb_fd, timeout);
160 if (ret < 0) {
161 /* At this point, every error is fatal */
162 perror("poll wait");
163 goto error;
164 }
165
166 return ret;
167
168error:
169 return -1;
170}
171
172/*
173 * Setup poll set maximum size.
174 */
175void compat_poll_set_max_size(void)
176{
177 int ret;
178 struct rlimit lim;
179
180 /* Default value */
990570ed 181 poll_max_size = DEFAULT_POLL_SIZE;
5eb91c98
DG
182
183 ret = getrlimit(RLIMIT_NOFILE, &lim);
184 if (ret < 0) {
185 perror("getrlimit poll RLIMIT_NOFILE");
186 return;
187 }
188
189 poll_max_size = lim.rlim_cur;
190 if (poll_max_size <= 0) {
191 /* Extra precaution */
990570ed 192 poll_max_size = DEFAULT_POLL_SIZE;
5eb91c98
DG
193 }
194
195 DBG("poll set max size set to %u", poll_max_size);
196}
This page took 0.031766 seconds and 4 git commands to generate.