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