Add missing permission notice in each source file
[babeltrace.git] / formats / ctf / memstream.h
CommitLineData
f8370579
MD
1#ifndef _BABELTRACE_FORMAT_CTF_MEMSTREAM_H
2#define _BABELTRACE_FORMAT_CTF_MEMSTREAM_H
3
4/*
5 * format/ctf/memstream.h
6 *
7 * Copyright 2012 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 *
9 * memstream compatibility layer.
10 *
eb31c5e6
MD
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
f8370579 17 *
eb31c5e6
MD
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
c462e188
MD
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * SOFTWARE.
f8370579
MD
28 */
29
30#define _GNU_SOURCE
31#include <config.h>
32
33#ifdef BABELTRACE_HAVE_FMEMOPEN
34#include <stdio.h>
35
36static inline
37FILE *babeltrace_fmemopen(void *buf, size_t size, const char *mode)
38{
39 return fmemopen(buf, size, mode);
40}
41
42#else /* BABELTRACE_HAVE_FMEMOPEN */
43
44#include <stdlib.h>
45#include <stdio.h>
46
47/*
48 * Fallback for systems which don't have fmemopen. Copy buffer to a
49 * temporary file, and use that file as FILE * input.
50 */
51static inline
52FILE *babeltrace_fmemopen(void *buf, size_t size, const char *mode)
53{
54 char tmpname[PATH_MAX];
55 size_t len;
56 FILE *fp;
57 int ret;
58
59 /*
60 * Support reading only.
61 */
62 if (strcmp(mode, "rb") != 0) {
63 return NULL;
64 }
65 strncpy(tmpname, "/tmp/babeltrace-tmp-XXXXXX", PATH_MAX);
66 ret = mkstemp(tmpname);
67 if (ret < 0) {
68 return NULL;
69 }
70 /*
71 * We need to write to the file.
72 */
73 fp = fdopen(ret, "w+");
74 if (!fp) {
75 goto error_unlink;
76 }
77 /* Copy the entire buffer to the file */
78 len = fwrite(buf, sizeof(char), size, fp);
79 if (len != size) {
80 goto error_close;
81 }
82 ret = fseek(fp, 0L, SEEK_SET);
83 if (ret < 0) {
84 perror("fseek");
85 goto error_close;
86 }
87 /* We keep the handle open, but can unlink the file on the VFS. */
88 ret = unlink(tmpname);
89 if (ret < 0) {
90 perror("unlink");
91 }
92 return fp;
93
94error_close:
95 ret = fclose(fp);
96 if (ret < 0) {
97 perror("close");
98 }
99error_unlink:
100 ret = unlink(tmpname);
101 if (ret < 0) {
102 perror("unlink");
103 }
104 return NULL;
105}
106
107#endif /* BABELTRACE_HAVE_FMEMOPEN */
108
109#ifdef BABELTRACE_HAVE_OPEN_MEMSTREAM
110
111#include <stdio.h>
112
113static inline
114FILE *babeltrace_open_memstream(char **ptr, size_t *sizeloc)
115{
116 return open_memstream(ptr, sizeloc);
117}
118
119static inline
120int babeltrace_close_memstream(char **buf, size_t *size, FILE *fp)
121{
122 return fclose(fp);
123}
124
125#else /* BABELTRACE_HAVE_OPEN_MEMSTREAM */
126
127#include <stdlib.h>
128#include <stdio.h>
129
130/*
131 * Fallback for systems which don't have open_memstream. Create FILE *
132 * with babeltrace_open_memstream, but require call to
133 * babeltrace_close_memstream to flush all data written to the FILE *
134 * into the buffer (which we allocate).
135 */
136static inline
137FILE *babeltrace_open_memstream(char **ptr, size_t *sizeloc)
138{
139 char tmpname[PATH_MAX];
140 int ret;
141 FILE *fp;
142
143 strncpy(tmpname, "/tmp/babeltrace-tmp-XXXXXX", PATH_MAX);
144 ret = mkstemp(tmpname);
145 if (ret < 0) {
146 return NULL;
147 }
148 fp = fdopen(ret, "w+");
149 if (!fp) {
150 goto error_unlink;
151 }
152 /*
153 * babeltrace_flush_memstream will update the buffer content
154 * with read from fp. No need to keep the file around, just the
155 * handle.
156 */
157 ret = unlink(tmpname);
158 if (ret < 0) {
159 perror("unlink");
160 }
161 return fp;
162
163error_unlink:
164 ret = unlink(tmpname);
165 if (ret < 0) {
166 perror("unlink");
167 }
168 return NULL;
169}
170
171/* Get file size, allocate buffer, copy. */
172static inline
173int babeltrace_close_memstream(char **buf, size_t *size, FILE *fp)
174{
175 size_t len, n;
176 long pos;
177 int ret;
178
179 ret = fflush(fp);
180 if (ret < 0) {
181 perror("fflush");
182 return ret;
183 }
184 ret = fseek(fp, 0L, SEEK_END);
185 if (ret < 0) {
186 perror("fseek");
187 return ret;
188 }
189 pos = ftell(fp);
190 if (ret < 0) {
191 perror("ftell");
192 return ret;
193 }
194 *size = pos;
195 /* add final \0 */
196 *buf = calloc(pos + 1, sizeof(char));
197 if (!*buf) {
198 return -ENOMEM;
199 }
200 ret = fseek(fp, 0L, SEEK_SET);
201 if (ret < 0) {
202 perror("fseek");
203 goto error_free;
204 }
205 /* Copy the entire file into the buffer */
206 n = 0;
207 clearerr(fp);
208 while (!feof(fp) && !ferror(fp) && (*size - n > 0)) {
209 len = fread(*buf, sizeof(char), *size - n, fp);
210 n += len;
211 }
212 if (n != *size) {
213 ret = -1;
214 goto error_close;
215 }
216 ret = fclose(fp);
217 if (ret < 0) {
218 perror("fclose");
219 return ret;
220 }
221 return 0;
222
223error_close:
224 ret = fclose(fp);
225 if (ret < 0) {
226 perror("fclose");
227 }
228error_free:
229 free(*buf);
230 *buf = NULL;
231 return ret;
232}
233
234#endif /* BABELTRACE_HAVE_OPEN_MEMSTREAM */
235
236#endif /* _BABELTRACE_FORMAT_CTF_MEMSTREAM_H */
This page took 0.045688 seconds and 4 git commands to generate.