Fix: kernel context memory leak on error
[lttng-tools.git] / src / common / readwrite.c
CommitLineData
33b14136
MD
1/*
2 * Copyright (C) 2013 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 *
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, version 2.1 only,
6 * as published by the Free Software Foundation.
7 *
8 * This library is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
6cd525e8 18#include <assert.h>
aeb16260 19#include <errno.h>
636ae5db 20#include <limits.h>
aeb16260
DG
21#include <unistd.h>
22
33b14136
MD
23#include "readwrite.h"
24
25/*
26 * lttng_read and lttng_write take care of EINTR and partial read/write.
27 * Upon success, they return the "count" received as parameter.
28 * They can return a negative value if an error occurs.
29 * If a value lower than the requested "count" is returned, it means an
30 * error occured.
31 * The error can be checked by querying errno.
32 */
33ssize_t lttng_read(int fd, void *buf, size_t count)
34{
35 size_t i = 0;
36 ssize_t ret;
37
aeb16260
DG
38 assert(buf);
39
636ae5db
DG
40 /*
41 * Deny a read count that can be bigger then the returned value max size.
42 * This makes the function to never return an overflow value.
43 */
44 if (count > SSIZE_MAX) {
45 return -EINVAL;
46 }
47
33b14136 48 do {
6cd525e8 49 ret = read(fd, buf + i, count - i);
33b14136
MD
50 if (ret < 0) {
51 if (errno == EINTR) {
52 continue; /* retry operation */
53 } else {
54 goto error;
55 }
56 }
57 i += ret;
58 assert(i <= count);
59 } while (count - i > 0 && ret > 0);
60 return i;
61
62error:
63 if (i == 0) {
64 return -1;
65 } else {
66 return i;
67 }
68}
69
70ssize_t lttng_write(int fd, const void *buf, size_t count)
71{
72 size_t i = 0;
73 ssize_t ret;
74
aeb16260
DG
75 assert(buf);
76
636ae5db
DG
77 /*
78 * Deny a write count that can be bigger then the returned value max size.
79 * This makes the function to never return an overflow value.
80 */
81 if (count > SSIZE_MAX) {
82 return -EINVAL;
83 }
84
33b14136 85 do {
6cd525e8 86 ret = write(fd, buf + i, count - i);
33b14136
MD
87 if (ret < 0) {
88 if (errno == EINTR) {
89 continue; /* retry operation */
90 } else {
91 goto error;
92 }
93 }
94 i += ret;
95 assert(i <= count);
96 } while (count - i > 0 && ret > 0);
97 return i;
98
99error:
100 if (i == 0) {
101 return -1;
102 } else {
103 return i;
104 }
105}
This page took 0.059492 seconds and 4 git commands to generate.