X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Fpipe.c;h=c8f00141574c3a6f11ce278a4c4a07d9cad1fa46;hp=713db973972ab40de1b9414eebdf02b697545099;hb=9c2bd8db1c70269d37537b7d02bae41ccab29056;hpb=9fd926379bd4c6c17f2b3c39a5bbf9879bc74e14 diff --git a/src/common/pipe.c b/src/common/pipe.c index 713db9739..c8f001415 100644 --- a/src/common/pipe.c +++ b/src/common/pipe.c @@ -15,10 +15,12 @@ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define _GNU_SOURCE +#define _LGPL_SOURCE #include #include #include +#include +#include #include @@ -112,20 +114,69 @@ end: return ret_val; } +static struct lttng_pipe *_pipe_create(void) +{ + int ret; + struct lttng_pipe *p; + + p = zmalloc(sizeof(*p)); + if (!p) { + PERROR("zmalloc pipe create"); + goto end; + } + p->fd[0] = p->fd[1] = -1; + + ret = pthread_mutex_init(&p->read_mutex, NULL); + if (ret) { + PERROR("pthread_mutex_init read lock pipe create"); + goto error_destroy; + } + ret = pthread_mutex_init(&p->write_mutex, NULL); + if (ret) { + PERROR("pthread_mutex_init write lock pipe create"); + goto error_destroy_rmutex; + } +end: + return p; +error_destroy_rmutex: + (void) pthread_mutex_destroy(&p->read_mutex); +error_destroy: + free(p); + return NULL; +} + +static int _pipe_set_flags(struct lttng_pipe *pipe, int flags) +{ + int i, ret = 0; + + if (!flags) { + goto end; + } + + for (i = 0; i < 2; i++) { + ret = fcntl(pipe->fd[i], F_SETFD, flags); + if (ret < 0) { + PERROR("fcntl lttng pipe %d", flags); + goto end; + } + } +end: + return ret; +} /* * Open a new lttng pipe and set flags using fcntl(). * * Return a newly allocated lttng pipe on success or else NULL. */ +LTTNG_HIDDEN struct lttng_pipe *lttng_pipe_open(int flags) { int ret; struct lttng_pipe *p; - p = zmalloc(sizeof(*p)); + p = _pipe_create(); if (!p) { - PERROR("zmalloc pipe open"); goto error; } @@ -134,37 +185,81 @@ struct lttng_pipe *lttng_pipe_open(int flags) PERROR("lttng pipe"); goto error; } + p->r_state = LTTNG_PIPE_STATE_OPENED; + p->w_state = LTTNG_PIPE_STATE_OPENED; - if (flags) { - int i; - - for (i = 0; i < 2; i++) { - ret = fcntl(p->fd[i], F_SETFD, flags); - if (ret < 0) { - PERROR("fcntl lttng pipe %d", flags); - goto error; - } - } + ret = _pipe_set_flags(p, flags); + if (ret) { + goto error; } - pthread_mutex_init(&p->read_mutex, NULL); - pthread_mutex_init(&p->write_mutex, NULL); - p->r_state = LTTNG_PIPE_STATE_OPENED; - p->w_state = LTTNG_PIPE_STATE_OPENED; p->flags = flags; return p; - error: lttng_pipe_destroy(p); return NULL; } +/* + * Open a new lttng pipe at path and set flags using fcntl(). + * + * Return a newly allocated lttng pipe on success or else NULL. + */ +LTTNG_HIDDEN +struct lttng_pipe *lttng_pipe_named_open(const char *path, mode_t mode, + int flags) +{ + int ret, fd_r, fd_w; + struct lttng_pipe *pipe; + + pipe = _pipe_create(); + if (!pipe) { + goto error; + } + + ret = mkfifo(path, mode); + if (ret) { + PERROR("mkfifo"); + goto error; + } + + fd_r = open(path, O_RDONLY | O_NONBLOCK); + if (fd_r < 0) { + PERROR("open fifo"); + ret = fd_r; + goto error; + } + pipe->fd[0] = fd_r; + pipe->r_state = LTTNG_PIPE_STATE_OPENED; + + fd_w = open(path, O_WRONLY | O_NONBLOCK); + if (fd_w < 0) { + PERROR("open fifo"); + ret = fd_w; + goto error; + } + pipe->fd[1] = fd_w; + pipe->w_state = LTTNG_PIPE_STATE_OPENED; + + ret = _pipe_set_flags(pipe, flags); + if (ret) { + goto error; + } + pipe->flags = flags; + + return pipe; +error: + lttng_pipe_destroy(pipe); + return NULL; +} + /* * Close read side of a lttng pipe. * * Return 0 on success else a negative value. */ +LTTNG_HIDDEN int lttng_pipe_read_close(struct lttng_pipe *pipe) { int ret; @@ -184,6 +279,7 @@ int lttng_pipe_read_close(struct lttng_pipe *pipe) * * Return 0 on success else a negative value. */ +LTTNG_HIDDEN int lttng_pipe_write_close(struct lttng_pipe *pipe) { int ret; @@ -202,6 +298,7 @@ int lttng_pipe_write_close(struct lttng_pipe *pipe) * * Return 0 on success else a negative value. */ +LTTNG_HIDDEN int lttng_pipe_close(struct lttng_pipe *pipe) { int ret, ret_val = 0; @@ -224,6 +321,7 @@ int lttng_pipe_close(struct lttng_pipe *pipe) /* * Close and destroy a lttng pipe object. Finally, pipe is freed. */ +LTTNG_HIDDEN void lttng_pipe_destroy(struct lttng_pipe *pipe) { int ret; @@ -257,51 +355,24 @@ void lttng_pipe_destroy(struct lttng_pipe *pipe) /* * Read on a lttng pipe and put the data in buf of at least size count. * - * Return 0 on success or else a negative errno message from read(2). + * Return "count" on success. Return < count on error. errno can be used + * to check the actual error. */ +LTTNG_HIDDEN ssize_t lttng_pipe_read(struct lttng_pipe *pipe, void *buf, size_t count) { - ssize_t ret, read_len, read_left, index; + ssize_t ret; assert(pipe); assert(buf); lock_read_side(pipe); - if (!lttng_pipe_is_read_open(pipe)) { - ret = -EBADF; + ret = -1; + errno = EBADF; goto error; } - - read_left = count; - index = 0; - do { - read_len = read(pipe->fd[0], buf + index, read_left); - if (read_len < 0) { - ret = -errno; - if (errno == EINTR) { - /* Read again. */ - continue; - } else if (errno == EAGAIN || errno == EWOULDBLOCK) { - /* - * Return the number of bytes read up to this point if any. - */ - if (index) { - ret = index; - } - goto error; - } else { - PERROR("lttng pipe read"); - goto error; - } - } - read_left -= read_len; - index += read_len; - } while (read_left > 0); - - /* Everything went fine. */ - ret = index; - + ret = lttng_read(pipe->fd[0], buf, count); error: unlock_read_side(pipe); return ret; @@ -310,52 +381,25 @@ error: /* * Write on a lttng pipe using the data in buf and size of count. * - * Return 0 on success or else a negative errno message from write(2). + * Return "count" on success. Return < count on error. errno can be used + * to check the actual error. */ +LTTNG_HIDDEN ssize_t lttng_pipe_write(struct lttng_pipe *pipe, const void *buf, size_t count) { - ssize_t ret, write_len, write_left, index; + ssize_t ret; assert(pipe); assert(buf); lock_write_side(pipe); - if (!lttng_pipe_is_write_open(pipe)) { - ret = -EBADF; + ret = -1; + errno = EBADF; goto error; } - - write_left = count; - index = 0; - do { - write_len = write(pipe->fd[1], buf + index, write_left); - if (write_len < 0) { - ret = -errno; - if (errno == EINTR) { - /* Read again. */ - continue; - } else if (errno == EAGAIN || errno == EWOULDBLOCK) { - /* - * Return the number of bytes read up to this point if any. - */ - if (index) { - ret = index; - } - goto error; - } else { - PERROR("lttng pipe write"); - goto error; - } - } - write_left -= write_len; - index += write_len; - } while (write_left > 0); - - /* Everything went fine. */ - ret = index; - + ret = lttng_write(pipe->fd[1], buf, count); error: unlock_write_side(pipe); return ret;