Build fix: specialization of template in different namespace
[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
9fd92637
DG
9#include <fcntl.h>
10#include <unistd.h>
9c2bd8db
JG
11#include <sys/types.h>
12#include <sys/stat.h>
9fd92637 13
c9e313bc 14#include <common/common.hpp>
9fd92637 15
c9e313bc 16#include "pipe.hpp"
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 */
9c2bd8db
JG
216struct 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");
9c2bd8db
JG
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");
9c2bd8db
JG
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;
256error:
257 lttng_pipe_destroy(pipe);
258 return NULL;
259}
260
9fd92637
DG
261/*
262 * Close read side of a lttng pipe.
263 *
264 * Return 0 on success else a negative value.
265 */
266int lttng_pipe_read_close(struct lttng_pipe *pipe)
267{
268 int ret;
269
a0377dfe 270 LTTNG_ASSERT(pipe);
9fd92637
DG
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 */
285int lttng_pipe_write_close(struct lttng_pipe *pipe)
286{
287 int ret;
288
a0377dfe 289 LTTNG_ASSERT(pipe);
9fd92637
DG
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 */
303int lttng_pipe_close(struct lttng_pipe *pipe)
304{
305 int ret, ret_val = 0;
306
a0377dfe 307 LTTNG_ASSERT(pipe);
9fd92637
DG
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 */
325void 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);
a0377dfe 338 LTTNG_ASSERT(!ret);
9fd92637 339 ret = pthread_mutex_trylock(&pipe->write_mutex);
a0377dfe 340 LTTNG_ASSERT(!ret);
9fd92637
DG
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 *
6cd525e8
MD
358 * Return "count" on success. Return < count on error. errno can be used
359 * to check the actual error.
9fd92637
DG
360 */
361ssize_t lttng_pipe_read(struct lttng_pipe *pipe, void *buf, size_t count)
362{
6cd525e8 363 ssize_t ret;
9fd92637 364
a0377dfe
FD
365 LTTNG_ASSERT(pipe);
366 LTTNG_ASSERT(buf);
9fd92637
DG
367
368 lock_read_side(pipe);
9fd92637 369 if (!lttng_pipe_is_read_open(pipe)) {
6cd525e8
MD
370 ret = -1;
371 errno = EBADF;
9fd92637
DG
372 goto error;
373 }
6cd525e8 374 ret = lttng_read(pipe->fd[0], buf, count);
9fd92637
DG
375error:
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 *
6cd525e8
MD
383 * Return "count" on success. Return < count on error. errno can be used
384 * to check the actual error.
9fd92637
DG
385 */
386ssize_t lttng_pipe_write(struct lttng_pipe *pipe, const void *buf,
387 size_t count)
388{
6cd525e8 389 ssize_t ret;
9fd92637 390
a0377dfe
FD
391 LTTNG_ASSERT(pipe);
392 LTTNG_ASSERT(buf);
9fd92637
DG
393
394 lock_write_side(pipe);
9fd92637 395 if (!lttng_pipe_is_write_open(pipe)) {
6cd525e8
MD
396 ret = -1;
397 errno = EBADF;
9fd92637
DG
398 goto error;
399 }
6cd525e8 400 ret = lttng_write(pipe->fd[1], buf, count);
9fd92637
DG
401error:
402 unlock_write_side(pipe);
403 return ret;
404}
55dfb029
JG
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 */
55dfb029
JG
415int 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;
432end_unlock:
433 unlock_read_side(pipe);
434end:
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 */
55dfb029
JG
447int 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;
464end_unlock:
465 unlock_write_side(pipe);
466end:
467 return ret;
468}
This page took 0.081885 seconds and 4 git commands to generate.