common: uuid: add `uuid_to_str` which returns an std::string
[lttng-tools.git] / src / common / pipe.cpp
1 /*
2 * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #define _LGPL_SOURCE
9 #include <fcntl.h>
10 #include <unistd.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13
14 #include <common/common.hpp>
15
16 #include "pipe.hpp"
17
18 /*
19 * Lock read side of a pipe.
20 */
21 static void lock_read_side(struct lttng_pipe *pipe)
22 {
23 pthread_mutex_lock(&pipe->read_mutex);
24 }
25
26 /*
27 * Unlock read side of a pipe.
28 */
29 static void unlock_read_side(struct lttng_pipe *pipe)
30 {
31 pthread_mutex_unlock(&pipe->read_mutex);
32 }
33
34 /*
35 * Lock write side of a pipe.
36 */
37 static void lock_write_side(struct lttng_pipe *pipe)
38 {
39 pthread_mutex_lock(&pipe->write_mutex);
40 }
41
42 /*
43 * Unlock write side of a pipe.
44 */
45 static void unlock_write_side(struct lttng_pipe *pipe)
46 {
47 pthread_mutex_unlock(&pipe->write_mutex);
48 }
49
50 /*
51 * Internal function. Close read side of pipe WITHOUT locking the mutex.
52 *
53 * Return 0 on success else a negative errno from close(2).
54 */
55 static int _pipe_read_close(struct lttng_pipe *pipe)
56 {
57 int ret, ret_val = 0;
58
59 LTTNG_ASSERT(pipe);
60
61 if (!lttng_pipe_is_read_open(pipe)) {
62 goto end;
63 }
64
65 do {
66 ret = close(pipe->fd[0]);
67 } while (ret < 0 && errno == EINTR);
68 if (ret < 0) {
69 PERROR("close lttng read pipe");
70 ret_val = -errno;
71 }
72 pipe->r_state = LTTNG_PIPE_STATE_CLOSED;
73
74 end:
75 return ret_val;
76 }
77
78 /*
79 * Internal function. Close write side of pipe WITHOUT locking the mutex.
80 *
81 * Return 0 on success else a negative errno from close(2).
82 */
83 static int _pipe_write_close(struct lttng_pipe *pipe)
84 {
85 int ret, ret_val = 0;
86
87 LTTNG_ASSERT(pipe);
88
89 if (!lttng_pipe_is_write_open(pipe)) {
90 goto end;
91 }
92
93 do {
94 ret = close(pipe->fd[1]);
95 } while (ret < 0 && errno == EINTR);
96 if (ret < 0) {
97 PERROR("close lttng write pipe");
98 ret_val = -errno;
99 }
100 pipe->w_state = LTTNG_PIPE_STATE_CLOSED;
101
102 end:
103 return ret_val;
104 }
105
106 static struct lttng_pipe *_pipe_create(void)
107 {
108 int ret;
109 struct lttng_pipe *p;
110
111 p = zmalloc<lttng_pipe>();
112 if (!p) {
113 PERROR("zmalloc pipe create");
114 goto end;
115 }
116 p->fd[0] = p->fd[1] = -1;
117
118 ret = pthread_mutex_init(&p->read_mutex, NULL);
119 if (ret) {
120 PERROR("pthread_mutex_init read lock pipe create");
121 goto error_destroy;
122 }
123 ret = pthread_mutex_init(&p->write_mutex, NULL);
124 if (ret) {
125 PERROR("pthread_mutex_init write lock pipe create");
126 goto error_destroy_rmutex;
127 }
128 end:
129 return p;
130 error_destroy_rmutex:
131 (void) pthread_mutex_destroy(&p->read_mutex);
132 error_destroy:
133 free(p);
134 return NULL;
135 }
136
137 static int _pipe_set_flags(struct lttng_pipe *pipe, int flags)
138 {
139 int i, ret = 0;
140
141 if (!flags) {
142 goto end;
143 }
144
145 for (i = 0; i < 2; i++) {
146 if (flags & O_NONBLOCK) {
147 ret = fcntl(pipe->fd[i], F_SETFL, O_NONBLOCK);
148 if (ret < 0) {
149 PERROR("fcntl lttng pipe %d", flags);
150 goto end;
151 }
152 }
153 if (flags & FD_CLOEXEC) {
154 ret = fcntl(pipe->fd[i], F_SETFD, FD_CLOEXEC);
155 if (ret < 0) {
156 PERROR("fcntl lttng pipe %d", flags);
157 goto end;
158 }
159 }
160 /*
161 * We only check for O_NONBLOCK or FD_CLOEXEC, if another flag is
162 * needed, we can add it, but for now just make sure we don't make
163 * mistakes with the parameters we pass.
164 */
165 if (!(flags & O_NONBLOCK) && !(flags & FD_CLOEXEC)) {
166 fprintf(stderr, "Unsupported flag\n");
167 ret = -1;
168 goto end;
169 }
170 }
171 end:
172 return ret;
173 }
174
175 /*
176 * Open a new lttng pipe and set flags using fcntl().
177 *
178 * Return a newly allocated lttng pipe on success or else NULL.
179 */
180 struct lttng_pipe *lttng_pipe_open(int flags)
181 {
182 int ret;
183 struct lttng_pipe *p;
184
185 p = _pipe_create();
186 if (!p) {
187 goto error;
188 }
189
190 ret = pipe(p->fd);
191 if (ret < 0) {
192 PERROR("lttng pipe");
193 goto error;
194 }
195 p->r_state = LTTNG_PIPE_STATE_OPENED;
196 p->w_state = LTTNG_PIPE_STATE_OPENED;
197
198 ret = _pipe_set_flags(p, flags);
199 if (ret) {
200 goto error;
201 }
202
203 p->flags = flags;
204
205 return p;
206 error:
207 lttng_pipe_destroy(p);
208 return NULL;
209 }
210
211 /*
212 * Open a new lttng pipe at path and set flags using fcntl().
213 *
214 * Return a newly allocated lttng pipe on success or else NULL.
215 */
216 struct lttng_pipe *lttng_pipe_named_open(const char *path, mode_t mode,
217 int flags)
218 {
219 int ret, fd_r, fd_w;
220 struct lttng_pipe *pipe;
221
222 pipe = _pipe_create();
223 if (!pipe) {
224 goto error;
225 }
226
227 ret = mkfifo(path, mode);
228 if (ret) {
229 PERROR("mkfifo");
230 goto error;
231 }
232
233 fd_r = open(path, O_RDONLY | O_NONBLOCK);
234 if (fd_r < 0) {
235 PERROR("open fifo");
236 goto error;
237 }
238 pipe->fd[0] = fd_r;
239 pipe->r_state = LTTNG_PIPE_STATE_OPENED;
240
241 fd_w = open(path, O_WRONLY | O_NONBLOCK);
242 if (fd_w < 0) {
243 PERROR("open fifo");
244 goto error;
245 }
246 pipe->fd[1] = fd_w;
247 pipe->w_state = LTTNG_PIPE_STATE_OPENED;
248
249 ret = _pipe_set_flags(pipe, flags);
250 if (ret) {
251 goto error;
252 }
253 pipe->flags = flags;
254
255 return pipe;
256 error:
257 lttng_pipe_destroy(pipe);
258 return NULL;
259 }
260
261 /*
262 * Close read side of a lttng pipe.
263 *
264 * Return 0 on success else a negative value.
265 */
266 int lttng_pipe_read_close(struct lttng_pipe *pipe)
267 {
268 int ret;
269
270 LTTNG_ASSERT(pipe);
271
272 /* Handle read side first. */
273 lock_read_side(pipe);
274 ret = _pipe_read_close(pipe);
275 unlock_read_side(pipe);
276
277 return ret;
278 }
279
280 /*
281 * Close write side of a lttng pipe.
282 *
283 * Return 0 on success else a negative value.
284 */
285 int lttng_pipe_write_close(struct lttng_pipe *pipe)
286 {
287 int ret;
288
289 LTTNG_ASSERT(pipe);
290
291 lock_write_side(pipe);
292 ret = _pipe_write_close(pipe);
293 unlock_write_side(pipe);
294
295 return ret;
296 }
297
298 /*
299 * Close both read and write side of a lttng pipe.
300 *
301 * Return 0 on success else a negative value.
302 */
303 int lttng_pipe_close(struct lttng_pipe *pipe)
304 {
305 int ret, ret_val = 0;
306
307 LTTNG_ASSERT(pipe);
308
309 ret = lttng_pipe_read_close(pipe);
310 if (ret < 0) {
311 ret_val = ret;
312 }
313
314 ret = lttng_pipe_write_close(pipe);
315 if (ret < 0) {
316 ret_val = ret;
317 }
318
319 return ret_val;
320 }
321
322 /*
323 * Close and destroy a lttng pipe object. Finally, pipe is freed.
324 */
325 void lttng_pipe_destroy(struct lttng_pipe *pipe)
326 {
327 int ret;
328
329 if (!pipe) {
330 return;
331 }
332
333 /*
334 * Destroy should *never* be called with a locked mutex. These must always
335 * succeed so we unlock them after the close pipe below.
336 */
337 ret = pthread_mutex_trylock(&pipe->read_mutex);
338 LTTNG_ASSERT(!ret);
339 ret = pthread_mutex_trylock(&pipe->write_mutex);
340 LTTNG_ASSERT(!ret);
341
342 /* Close pipes WITHOUT trying to lock the pipes. */
343 (void) _pipe_read_close(pipe);
344 (void) _pipe_write_close(pipe);
345
346 unlock_read_side(pipe);
347 unlock_write_side(pipe);
348
349 (void) pthread_mutex_destroy(&pipe->read_mutex);
350 (void) pthread_mutex_destroy(&pipe->write_mutex);
351
352 free(pipe);
353 }
354
355 /*
356 * Read on a lttng pipe and put the data in buf of at least size count.
357 *
358 * Return "count" on success. Return < count on error. errno can be used
359 * to check the actual error.
360 */
361 ssize_t lttng_pipe_read(struct lttng_pipe *pipe, void *buf, size_t count)
362 {
363 ssize_t ret;
364
365 LTTNG_ASSERT(pipe);
366 LTTNG_ASSERT(buf);
367
368 lock_read_side(pipe);
369 if (!lttng_pipe_is_read_open(pipe)) {
370 ret = -1;
371 errno = EBADF;
372 goto error;
373 }
374 ret = lttng_read(pipe->fd[0], buf, count);
375 error:
376 unlock_read_side(pipe);
377 return ret;
378 }
379
380 /*
381 * Write on a lttng pipe using the data in buf and size of count.
382 *
383 * Return "count" on success. Return < count on error. errno can be used
384 * to check the actual error.
385 */
386 ssize_t lttng_pipe_write(struct lttng_pipe *pipe, const void *buf,
387 size_t count)
388 {
389 ssize_t ret;
390
391 LTTNG_ASSERT(pipe);
392 LTTNG_ASSERT(buf);
393
394 lock_write_side(pipe);
395 if (!lttng_pipe_is_write_open(pipe)) {
396 ret = -1;
397 errno = EBADF;
398 goto error;
399 }
400 ret = lttng_write(pipe->fd[1], buf, count);
401 error:
402 unlock_write_side(pipe);
403 return ret;
404 }
405
406 /*
407 * Return and release the read end of the pipe.
408 *
409 * This call transfers the ownership of the read fd of the underlying pipe
410 * to the caller if it is still open.
411 *
412 * Returns the fd of the read end of the pipe, or -1 if it was already closed or
413 * released.
414 */
415 int lttng_pipe_release_readfd(struct lttng_pipe *pipe)
416 {
417 int ret;
418
419 if (!pipe) {
420 ret = -1;
421 goto end;
422 }
423
424 lock_read_side(pipe);
425 if (!lttng_pipe_is_read_open(pipe)) {
426 ret = -1;
427 goto end_unlock;
428 }
429 ret = pipe->fd[0];
430 pipe->fd[0] = -1;
431 pipe->r_state = LTTNG_PIPE_STATE_CLOSED;
432 end_unlock:
433 unlock_read_side(pipe);
434 end:
435 return ret;
436 }
437
438 /*
439 * Return and release the write end of the pipe.
440 *
441 * This call transfers the ownership of the write fd of the underlying pipe
442 * to the caller if it is still open.
443 *
444 * Returns the fd of the write end of the pipe, or -1 if it was alwritey closed
445 * or released.
446 */
447 int lttng_pipe_release_writefd(struct lttng_pipe *pipe)
448 {
449 int ret;
450
451 if (!pipe) {
452 ret = -1;
453 goto end;
454 }
455
456 lock_write_side(pipe);
457 if (!lttng_pipe_is_write_open(pipe)) {
458 ret = -1;
459 goto end_unlock;
460 }
461 ret = pipe->fd[1];
462 pipe->fd[1] = -1;
463 pipe->w_state = LTTNG_PIPE_STATE_CLOSED;
464 end_unlock:
465 unlock_write_side(pipe);
466 end:
467 return ret;
468 }
This page took 0.038619 seconds and 4 git commands to generate.