12ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata/*
22ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata * This file is part of ltrace.
32ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata * Copyright (C) 2012 Petr Machata, Red Hat Inc.
42ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata *
52ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata * This program is free software; you can redistribute it and/or
62ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata * modify it under the terms of the GNU General Public License as
72ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata * published by the Free Software Foundation; either version 2 of the
82ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata * License, or (at your option) any later version.
92ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata *
102ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata * This program is distributed in the hope that it will be useful, but
112ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of
122ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
132ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata * General Public License for more details.
142ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata *
152ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata * You should have received a copy of the GNU General Public License
162ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata * along with this program; if not, write to the Free Software
172ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
182ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata * 02110-1301 USA
192ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata */
202ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata
213690fad65d26e4e140595d6c0075410a84ff22f5Petr Machata/* _GNU_SOURCE may be necessary for open_memstream visibility (see
223690fad65d26e4e140595d6c0075410a84ff22f5Petr Machata * configure.ac), and there's no harm defining it just in case.  */
233690fad65d26e4e140595d6c0075410a84ff22f5Petr Machata#define _GNU_SOURCE
243690fad65d26e4e140595d6c0075410a84ff22f5Petr Machata
253690fad65d26e4e140595d6c0075410a84ff22f5Petr Machata#include <stdio.h>
262ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata#include <stdlib.h>
272ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata
282ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata#include "config.h"
292ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata#include "memstream.h"
302ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata
312ae374a196ca76406cd14503622060c2c5dc4cefPetr Machataint
322ae374a196ca76406cd14503622060c2c5dc4cefPetr Machatamemstream_init(struct memstream *memstream)
332ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata{
342ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata#if HAVE_OPEN_MEMSTREAM
352ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata	memstream->stream = open_memstream(&memstream->buf,
362ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata					   &memstream->size);
372ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata#else
382ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata	memstream->stream = tmpfile();
392ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata	memstream->buf = NULL;
4067f7adebdea215a583df9536e874ecd1a4162c4eOliver Spornitz#endif
412ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata	return memstream->stream != NULL ? 0 : -1;
422ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata}
432ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata
442ae374a196ca76406cd14503622060c2c5dc4cefPetr Machataint
452ae374a196ca76406cd14503622060c2c5dc4cefPetr Machatamemstream_close(struct memstream *memstream)
462ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata{
472ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata#if !defined(HAVE_OPEN_MEMSTREAM) || !HAVE_OPEN_MEMSTREAM
482ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata	if (fseek(memstream->stream, 0, SEEK_END) < 0) {
492ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata	fail:
502ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata		fclose(memstream->stream);
512ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata		return -1;
522ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata	}
532ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata	memstream->size = ftell(memstream->stream);
542ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata	if (memstream->size == (size_t)-1)
552ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata		goto fail;
562ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata	memstream->buf = malloc(memstream->size);
572ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata	if (memstream->buf == NULL)
582ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata		goto fail;
592ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata
602ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata	rewind(memstream->stream);
612ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata	if (fread(memstream->buf, 1, memstream->size, memstream->stream)
622ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata	    < memstream->size)
632ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata		goto fail;
642ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata#endif
652ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata
662ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata	return fclose(memstream->stream) == 0 ? 0 : -1;
672ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata}
682ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata
692ae374a196ca76406cd14503622060c2c5dc4cefPetr Machatavoid
702ae374a196ca76406cd14503622060c2c5dc4cefPetr Machatamemstream_destroy(struct memstream *memstream)
712ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata{
722ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata	free(memstream->buf);
732ae374a196ca76406cd14503622060c2c5dc4cefPetr Machata}
74