Run clang-format on the whole tree
[lttng-tools.git] / src / common / pipe.cpp
CommitLineData
9fd92637 1/*
ab5be9fa 2 * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
9fd92637 3 *
ab5be9fa 4 * SPDX-License-Identifier: GPL-2.0-only
9fd92637 5 *
9fd92637
DG
6 */
7
6c1c0768 8#define _LGPL_SOURCE
28ab034a 9#include "pipe.hpp"
9fd92637 10
c9e313bc 11#include <common/common.hpp>
9fd92637 12
28ab034a
JG
13#include <fcntl.h>
14#include <sys/stat.h>
15#include <sys/types.h>
16#include <unistd.h>
9fd92637
DG
17
18/*
19 * Lock read side of a pipe.
20 */
21static 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 */
29static 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 */
37static 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 */
45static 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 */
55static int _pipe_read_close(struct lttng_pipe *pipe)
56{
57 int ret, ret_val = 0;
58
a0377dfe 59 LTTNG_ASSERT(pipe);
9fd92637
DG
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
74end:
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 */
83static int _pipe_write_close(struct lttng_pipe *pipe)
84{
85 int ret, ret_val = 0;
86
a0377dfe 87 LTTNG_ASSERT(pipe);
9fd92637
DG
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
102end:
103 return ret_val;
104}
105
9c2bd8db
JG
106static struct lttng_pipe *_pipe_create(void)
107{
108 int ret;
109 struct lttng_pipe *p;
110
64803277 111 p = zmalloc<lttng_pipe>();
9c2bd8db
JG
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 }
128end:
129 return p;
130error_destroy_rmutex:
131 (void) pthread_mutex_destroy(&p->read_mutex);
132error_destroy:
133 free(p);
134 return NULL;
135}
136
137static 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++) {
699f8738
JD
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;
9c2bd8db
JG
168 goto end;
169 }
170 }
171end:
172 return ret;
173}
9fd92637
DG
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 */
180struct lttng_pipe *lttng_pipe_open(int flags)
181{
182 int ret;
183 struct lttng_pipe *p;
184
9c2bd8db 185 p = _pipe_create();
9fd92637 186 if (!p) {
9fd92637
DG
187 goto error;
188 }
189
190 ret = pipe(p->fd);
191 if (ret < 0) {
192 PERROR("lttng pipe");
193 goto error;
194 }
9c2bd8db
JG
195 p->r_state = LTTNG_PIPE_STATE_OPENED;
196 p->w_state = LTTNG_PIPE_STATE_OPENED;
9fd92637 197
9c2bd8db
JG
198 ret = _pipe_set_flags(p, flags);
199 if (ret) {
200 goto error;
9fd92637
DG
201 }
202
9fd92637
DG
203 p->flags = flags;
204
205 return p;
9fd92637
DG
206error:
207 lttng_pipe_destroy(p);
208 return NULL;
209}
210
9c2bd8db
JG
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 */
28ab034a 216struct lttng_pipe *lttng_pipe_named_open(const char *path, mode_t mode, int flags)
9c2bd8db
JG
217{
218 int ret, fd_r, fd_w;
219 struct lttng_pipe *pipe;
220
221 pipe = _pipe_create();
222 if (!pipe) {
223 goto error;
224 }
225
226 ret = mkfifo(path, mode);
227 if (ret) {
228 PERROR("mkfifo");
229 goto error;
230 }
231
232 fd_r = open(path, O_RDONLY | O_NONBLOCK);
233 if (fd_r < 0) {
234 PERROR("open fifo");
9c2bd8db
JG
235 goto error;
236 }
237 pipe->fd[0] = fd_r;
238 pipe->r_state = LTTNG_PIPE_STATE_OPENED;
239
240 fd_w = open(path, O_WRONLY | O_NONBLOCK);
241 if (fd_w < 0) {
242 PERROR("open fifo");
9c2bd8db
JG
243 goto error;
244 }
245 pipe->fd[1] = fd_w;
246 pipe->w_state = LTTNG_PIPE_STATE_OPENED;
247
248 ret = _pipe_set_flags(pipe, flags);
249 if (ret) {
250 goto error;
251 }
252 pipe->flags = flags;
253
254 return pipe;
255error:
256 lttng_pipe_destroy(pipe);
257 return NULL;
258}
259
9fd92637
DG
260/*
261 * Close read side of a lttng pipe.
262 *
263 * Return 0 on success else a negative value.
264 */
265int lttng_pipe_read_close(struct lttng_pipe *pipe)
266{
267 int ret;
268
a0377dfe 269 LTTNG_ASSERT(pipe);
9fd92637
DG
270
271 /* Handle read side first. */
272 lock_read_side(pipe);
273 ret = _pipe_read_close(pipe);
274 unlock_read_side(pipe);
275
276 return ret;
277}
278
279/*
280 * Close write side of a lttng pipe.
281 *
282 * Return 0 on success else a negative value.
283 */
284int lttng_pipe_write_close(struct lttng_pipe *pipe)
285{
286 int ret;
287
a0377dfe 288 LTTNG_ASSERT(pipe);
9fd92637
DG
289
290 lock_write_side(pipe);
291 ret = _pipe_write_close(pipe);
292 unlock_write_side(pipe);
293
294 return ret;
295}
296
297/*
298 * Close both read and write side of a lttng pipe.
299 *
300 * Return 0 on success else a negative value.
301 */
302int lttng_pipe_close(struct lttng_pipe *pipe)
303{
304 int ret, ret_val = 0;
305
a0377dfe 306 LTTNG_ASSERT(pipe);
9fd92637
DG
307
308 ret = lttng_pipe_read_close(pipe);
309 if (ret < 0) {
310 ret_val = ret;
311 }
312
313 ret = lttng_pipe_write_close(pipe);
314 if (ret < 0) {
315 ret_val = ret;
316 }
317
318 return ret_val;
319}
320
321/*
322 * Close and destroy a lttng pipe object. Finally, pipe is freed.
323 */
324void lttng_pipe_destroy(struct lttng_pipe *pipe)
325{
326 int ret;
327
328 if (!pipe) {
329 return;
330 }
331
332 /*
333 * Destroy should *never* be called with a locked mutex. These must always
334 * succeed so we unlock them after the close pipe below.
335 */
336 ret = pthread_mutex_trylock(&pipe->read_mutex);
a0377dfe 337 LTTNG_ASSERT(!ret);
9fd92637 338 ret = pthread_mutex_trylock(&pipe->write_mutex);
a0377dfe 339 LTTNG_ASSERT(!ret);
9fd92637
DG
340
341 /* Close pipes WITHOUT trying to lock the pipes. */
342 (void) _pipe_read_close(pipe);
343 (void) _pipe_write_close(pipe);
344
345 unlock_read_side(pipe);
346 unlock_write_side(pipe);
347
348 (void) pthread_mutex_destroy(&pipe->read_mutex);
349 (void) pthread_mutex_destroy(&pipe->write_mutex);
350
351 free(pipe);
352}
353
354/*
355 * Read on a lttng pipe and put the data in buf of at least size count.
356 *
6cd525e8
MD
357 * Return "count" on success. Return < count on error. errno can be used
358 * to check the actual error.
9fd92637
DG
359 */
360ssize_t lttng_pipe_read(struct lttng_pipe *pipe, void *buf, size_t count)
361{
6cd525e8 362 ssize_t ret;
9fd92637 363
a0377dfe
FD
364 LTTNG_ASSERT(pipe);
365 LTTNG_ASSERT(buf);
9fd92637
DG
366
367 lock_read_side(pipe);
9fd92637 368 if (!lttng_pipe_is_read_open(pipe)) {
6cd525e8
MD
369 ret = -1;
370 errno = EBADF;
9fd92637
DG
371 goto error;
372 }
6cd525e8 373 ret = lttng_read(pipe->fd[0], buf, count);
9fd92637
DG
374error:
375 unlock_read_side(pipe);
376 return ret;
377}
378
379/*
380 * Write on a lttng pipe using the data in buf and size of count.
381 *
6cd525e8
MD
382 * Return "count" on success. Return < count on error. errno can be used
383 * to check the actual error.
9fd92637 384 */
28ab034a 385ssize_t lttng_pipe_write(struct lttng_pipe *pipe, const void *buf, size_t count)
9fd92637 386{
6cd525e8 387 ssize_t ret;
9fd92637 388
a0377dfe
FD
389 LTTNG_ASSERT(pipe);
390 LTTNG_ASSERT(buf);
9fd92637
DG
391
392 lock_write_side(pipe);
9fd92637 393 if (!lttng_pipe_is_write_open(pipe)) {
6cd525e8
MD
394 ret = -1;
395 errno = EBADF;
9fd92637
DG
396 goto error;
397 }
6cd525e8 398 ret = lttng_write(pipe->fd[1], buf, count);
9fd92637
DG
399error:
400 unlock_write_side(pipe);
401 return ret;
402}
55dfb029
JG
403
404/*
405 * Return and release the read end of the pipe.
406 *
407 * This call transfers the ownership of the read fd of the underlying pipe
408 * to the caller if it is still open.
409 *
410 * Returns the fd of the read end of the pipe, or -1 if it was already closed or
411 * released.
412 */
55dfb029
JG
413int lttng_pipe_release_readfd(struct lttng_pipe *pipe)
414{
415 int ret;
416
417 if (!pipe) {
418 ret = -1;
419 goto end;
420 }
421
422 lock_read_side(pipe);
423 if (!lttng_pipe_is_read_open(pipe)) {
424 ret = -1;
425 goto end_unlock;
426 }
427 ret = pipe->fd[0];
428 pipe->fd[0] = -1;
429 pipe->r_state = LTTNG_PIPE_STATE_CLOSED;
430end_unlock:
431 unlock_read_side(pipe);
432end:
433 return ret;
434}
435
436/*
437 * Return and release the write end of the pipe.
438 *
439 * This call transfers the ownership of the write fd of the underlying pipe
440 * to the caller if it is still open.
441 *
442 * Returns the fd of the write end of the pipe, or -1 if it was alwritey closed
443 * or released.
444 */
55dfb029
JG
445int lttng_pipe_release_writefd(struct lttng_pipe *pipe)
446{
447 int ret;
448
449 if (!pipe) {
450 ret = -1;
451 goto end;
452 }
453
454 lock_write_side(pipe);
455 if (!lttng_pipe_is_write_open(pipe)) {
456 ret = -1;
457 goto end_unlock;
458 }
459 ret = pipe->fd[1];
460 pipe->fd[1] = -1;
461 pipe->w_state = LTTNG_PIPE_STATE_CLOSED;
462end_unlock:
463 unlock_write_side(pipe);
464end:
465 return ret;
466}
This page took 0.082625 seconds and 4 git commands to generate.