1 /* 2 * This file is part of ltrace. 3 * Copyright (C) 2012 Petr Machata, Red Hat Inc. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation; either version 2 of the 8 * License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 18 * 02110-1301 USA 19 */ 20 21 /* _GNU_SOURCE may be necessary for open_memstream visibility (see 22 * configure.ac), and there's no harm defining it just in case. */ 23 #define _GNU_SOURCE 24 25 #include <stdio.h> 26 #include <stdlib.h> 27 28 #include "config.h" 29 #include "memstream.h" 30 31 int 32 memstream_init(struct memstream *memstream) 33 { 34 #if HAVE_OPEN_MEMSTREAM 35 memstream->stream = open_memstream(&memstream->buf, 36 &memstream->size); 37 #else 38 memstream->stream = tmpfile(); 39 memstream->buf = NULL; 40 #endif 41 return memstream->stream != NULL ? 0 : -1; 42 } 43 44 int 45 memstream_close(struct memstream *memstream) 46 { 47 #if !defined(HAVE_OPEN_MEMSTREAM) || !HAVE_OPEN_MEMSTREAM 48 if (fseek(memstream->stream, 0, SEEK_END) < 0) { 49 fail: 50 fclose(memstream->stream); 51 return -1; 52 } 53 memstream->size = ftell(memstream->stream); 54 if (memstream->size == (size_t)-1) 55 goto fail; 56 memstream->buf = malloc(memstream->size); 57 if (memstream->buf == NULL) 58 goto fail; 59 60 rewind(memstream->stream); 61 if (fread(memstream->buf, 1, memstream->size, memstream->stream) 62 < memstream->size) 63 goto fail; 64 #endif 65 66 return fclose(memstream->stream) == 0 ? 0 : -1; 67 } 68 69 void 70 memstream_destroy(struct memstream *memstream) 71 { 72 free(memstream->buf); 73 } 74