/*
 * blktrace output analysis: generate a timeline & gather statistics
 *
 * Copyright (C) 2006 Alan D. Brunelle <Alan.Brunelle@hp.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <fcntl.h>

#define INLINE_DECLARE
#include "globals.h"

struct file_info {
	struct list_head head;
	FILE *ofp;
	char *oname;
};

struct buf_info {
	struct list_head head;
	void *buf;
};

LIST_HEAD(files_to_clean);
LIST_HEAD(all_bufs);

static void clean_files(void)
{
	struct list_head *p, *q;

	list_for_each_safe(p, q, &files_to_clean) {
		struct stat buf;
		struct file_info *fip = list_entry(p, struct file_info, head);

		fclose(fip->ofp);
		if (!stat(fip->oname, &buf) && (buf.st_size == 0))
			unlink(fip->oname);

		list_del(&fip->head);
		free(fip->oname);
		free(fip);
	}
}

static void clean_bufs(void)
{
	struct list_head *p, *q;

	list_for_each_safe(p, q, &all_bufs) {
		struct buf_info *bip = list_entry(p, struct buf_info, head);

		list_del(&bip->head);
		free(bip->buf);
		free(bip);
	}
}

/*
 * Due to the N(devs) parts of a lot of the output features provided
 * by btt, it will fail opens on large(ish) systems. Here we try to
 * keep bumping our open file limits, and if those fail, we return NULL.
 *
 * Root users will probably be OK with this, others...
 */
static int increase_limit(int resource, rlim_t increase)
{
	struct rlimit rlim;
	int save_errno = errno;

	if (!getrlimit(resource, &rlim)) {
		rlim.rlim_cur += increase;
		if (rlim.rlim_cur >= rlim.rlim_max)
			rlim.rlim_max = rlim.rlim_cur + increase;

		if (!setrlimit(resource, &rlim))
			return 1;
	}

	errno = save_errno;
	return 0;
}

static int handle_open_failure(void)
{
	if (errno == ENFILE || errno == EMFILE)
		return increase_limit(RLIMIT_NOFILE, 16);

	return 0;
}

void add_file(FILE *fp, char *oname)
{
	struct file_info *fip = malloc(sizeof(*fip));

	fip->ofp = fp;
	fip->oname = oname;
	list_add_tail(&fip->head, &files_to_clean);
}

void add_buf(void *buf)
{
	struct buf_info *bip = malloc(sizeof(*bip));

	bip->buf = buf;
	list_add_tail(&bip->head, &all_bufs);
}

void clean_allocs(void)
{
	clean_files();
	clean_bufs();
}

char *make_dev_hdr(char *pad, size_t len, struct d_info *dip, int add_parens)
{
	if (dip->devmap)
		snprintf(pad, len, "%s", dip->devmap);
	else if (add_parens)
		snprintf(pad, len, "(%3d,%3d)",
			 MAJOR(dip->device), MINOR(dip->device));
	else
		snprintf(pad, len, "%d,%d",
			 MAJOR(dip->device), MINOR(dip->device));

	return pad;
}

char *mkhandle(struct d_info *dip, char *str, size_t len)
{
	return make_dev_hdr(str, len, dip, 0);
}

FILE *my_fopen(const char *path, const char *mode)
{
	FILE *fp;

	do {
		fp = fopen(path, mode);
	} while (fp == NULL && handle_open_failure());

	return fp;
}

int my_open(const char *path, int flags)
{
	int fd;

	do {
		fd = open(path, flags);
	} while (fd < 0 && handle_open_failure());

	return fd;
}

void dbg_ping(void) {}
