Fix: poll max size should be checked during resize
[lttng-tools.git] / src / common / utils.c
CommitLineData
81b86775
DG
1/*
2 * Copyright (C) 2012 - David Goulet <dgoulet@efficios.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License, version 2 only, as
6 * published by the Free Software Foundation.
7 *
8 * This program 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 General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 51
15 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
18#define _GNU_SOURCE
35f90c40 19#include <assert.h>
81b86775
DG
20#include <ctype.h>
21#include <fcntl.h>
22#include <limits.h>
23#include <stdlib.h>
24#include <string.h>
25
26#include <common/common.h>
27
28#include "utils.h"
29
30/*
31 * Return the realpath(3) of the path even if the last directory token does not
32 * exist. For example, with /tmp/test1/test2, if test2/ does not exist but the
33 * /tmp/test1 does, the real path is returned. In normal time, realpath(3)
34 * fails if the end point directory does not exist.
35 */
32dd26fb 36__attribute__((visibility("hidden")))
81b86775
DG
37char *utils_expand_path(const char *path)
38{
39 const char *end_path = path;
40 char *next, *cut_path = NULL, *expanded_path = NULL;
41
42 /* Safety net */
43 if (path == NULL) {
44 goto error;
45 }
46
47 /* Find last token delimited by '/' */
48 while ((next = strpbrk(end_path + 1, "/"))) {
49 end_path = next;
50 }
51
52 /* Cut last token from original path */
53 cut_path = strndup(path, end_path - path);
54
55 expanded_path = zmalloc(PATH_MAX);
56 if (expanded_path == NULL) {
57 PERROR("zmalloc expand path");
58 goto error;
59 }
60
61 expanded_path = realpath((char *)cut_path, expanded_path);
62 if (expanded_path == NULL) {
63 switch (errno) {
64 case ENOENT:
65 ERR("%s: No such file or directory", cut_path);
66 break;
67 default:
68 PERROR("realpath utils expand path");
69 break;
70 }
71 goto error;
72 }
73
74 /* Add end part to expanded path */
c30ce0b3 75 strncat(expanded_path, end_path, PATH_MAX - strlen(expanded_path) - 1);
81b86775
DG
76
77 free(cut_path);
78 return expanded_path;
79
80error:
81 free(expanded_path);
82 free(cut_path);
83 return NULL;
84}
85
86/*
87 * Create a pipe in dst.
88 */
32dd26fb 89__attribute__((visibility("hidden")))
81b86775
DG
90int utils_create_pipe(int *dst)
91{
92 int ret;
93
94 if (dst == NULL) {
95 return -1;
96 }
97
98 ret = pipe(dst);
99 if (ret < 0) {
100 PERROR("create pipe");
101 }
102
103 return ret;
104}
105
106/*
107 * Create pipe and set CLOEXEC flag to both fd.
108 *
109 * Make sure the pipe opened by this function are closed at some point. Use
110 * utils_close_pipe().
111 */
32dd26fb 112__attribute__((visibility("hidden")))
81b86775
DG
113int utils_create_pipe_cloexec(int *dst)
114{
115 int ret, i;
116
117 if (dst == NULL) {
118 return -1;
119 }
120
121 ret = utils_create_pipe(dst);
122 if (ret < 0) {
123 goto error;
124 }
125
126 for (i = 0; i < 2; i++) {
127 ret = fcntl(dst[i], F_SETFD, FD_CLOEXEC);
128 if (ret < 0) {
129 PERROR("fcntl pipe cloexec");
130 goto error;
131 }
132 }
133
134error:
135 return ret;
136}
137
138/*
139 * Close both read and write side of the pipe.
140 */
32dd26fb 141__attribute__((visibility("hidden")))
81b86775
DG
142void utils_close_pipe(int *src)
143{
144 int i, ret;
145
146 if (src == NULL) {
147 return;
148 }
149
150 for (i = 0; i < 2; i++) {
151 /* Safety check */
152 if (src[i] < 0) {
153 continue;
154 }
155
156 ret = close(src[i]);
157 if (ret) {
158 PERROR("close pipe");
159 }
160 }
161}
a4b92340
DG
162
163/*
164 * Create a new string using two strings range.
165 */
32dd26fb 166__attribute__((visibility("hidden")))
a4b92340
DG
167char *utils_strdupdelim(const char *begin, const char *end)
168{
169 char *str;
170
171 str = zmalloc(end - begin + 1);
172 if (str == NULL) {
173 PERROR("zmalloc strdupdelim");
174 goto error;
175 }
176
177 memcpy(str, begin, end - begin);
178 str[end - begin] = '\0';
179
180error:
181 return str;
182}
b662582b
DG
183
184/*
185 * Set CLOEXEC flag to the give file descriptor.
186 */
187__attribute__((visibility("hidden")))
188int utils_set_fd_cloexec(int fd)
189{
190 int ret;
191
192 if (fd < 0) {
193 ret = -EINVAL;
194 goto end;
195 }
196
197 ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
198 if (ret < 0) {
199 PERROR("fcntl cloexec");
200 ret = -errno;
201 }
202
203end:
204 return ret;
205}
35f90c40
DG
206
207/*
208 * Create pid file to the given path and filename.
209 */
210__attribute__((visibility("hidden")))
211int utils_create_pid_file(pid_t pid, const char *filepath)
212{
213 int ret;
214 FILE *fp;
215
216 assert(filepath);
217
218 fp = fopen(filepath, "w");
219 if (fp == NULL) {
220 PERROR("open pid file %s", filepath);
221 ret = -1;
222 goto error;
223 }
224
225 ret = fprintf(fp, "%d\n", pid);
226 if (ret < 0) {
227 PERROR("fprintf pid file");
228 }
229
230 fclose(fp);
231 DBG("Pid %d written in file %s", pid, filepath);
232error:
233 return ret;
234}
This page took 0.048921 seconds and 4 git commands to generate.