/*
 * Copyright (c) 2004, 2005 Sendmail, Inc. and its suppliers.
 *	All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 *
 * $Id: t-io-double.c,v 1.4 2006/07/16 02:07:39 ca Exp $
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: t-io-double.c,v 1.4 2006/07/16 02:07:39 ca Exp $")

#include "sm/assert.h"
#include "sm/error.h"
#include "sm/memops.h"
#include "sm/test.h"
#include "sm/io.h"
#include "sm/sysexits.h"

/*
**  This is just a program for playing around with double buffering.
**  See TODO.smi about the problems with the buffers in sm_file_T.
*/

#define SM_BUFSIZE	(8 * 1024)

static int Verbose = 0;

/*
**  T_WRITE -- write wr characters (according to above macro) to fp,
**
**	Parameters:
**		fp -- file pointer
**		wr -- number of chars to send
**
**	Returns:
**		usual error code
*/

static sm_ret_T
t_write(sm_file_T *fp, int wr)
{
	sm_ret_T res;
	size_t n, l, i;
	ssize_t rr;
	uchar buf[SM_BUFSIZE];

	l = sizeof(buf);
	n = SM_MIN(l, (size_t) wr);
	for (i = 0; i < n; i++)
		buf[i] = 'A' + (i % 16);

	res = sm_io_write(fp, buf, n, &rr);
	if (sm_is_err(res))
		return res;
	return SM_SUCCESS;
}

/*
**  WRITE_SOME -- write wr characters to fd
**
**	Parameters:
**		name -- name of file
**		wr -- number of chars to send
**
**	Returns:
**		usual error code
*/

static sm_ret_T
write_some(char *name, int wr)
{
	sm_ret_T res;
	int i;
	size_t r, w;
	sm_file_T *fp;

	r = w = 0;
	res = sm_io_open(SmStStdio, name, SM_IO_RDWRCR, &fp, SM_IO_WHAT_END);
	SM_TEST(res == SM_SUCCESS);
	SM_TEST(fp != NULL);
	if (sm_is_err(res))
		return res;
	res = sm_fp_nonblock(fp, true);
	SM_TEST(sm_is_success(res));

	i = 1;
	res = sm_io_setinfo(fp, SM_IO_DOUBLE, &i);
	SM_TEST(sm_is_success(res));

	sm_io_fprintf(smioout,
		"before write: "
		"f_bfbase=%6p, f_bfsize=%6d\n"
		"f_rd_bfbase=%6p, f_wr_bfbase=%6p\n"
		"f_rd_flags=%6p, f_wr_flags=%6p\n"
		, f_bfbase(*fp)
		, f_bfsize(*fp)
		, f_rd_bfbase(*fp)
		, f_wr_bfbase(*fp)
		, f_rd_flags(*fp)
		, f_wr_flags(*fp)
		);
	sm_io_flush(smioout);

	sm_io_fprintf(smioout,
		"before write: "
		"f_rd_bfbase=%6p, f_wr_bfbase=%6p\n"
		, f_rd_bfbase(*fp)
		, f_wr_bfbase(*fp)
		);
	sm_io_flush(smioout);


	res = t_write(fp, wr);
	SM_TEST(sm_is_success(res));

	sm_io_fprintf(smioout,
		"after write: "
		"f_bfbase=%6p, f_bfsize=%6d\n"
		"f_rd_bfbase=%6p, f_wr_bfbase=%6p\n"
		"f_rd_flags=%6p, f_wr_flags=%6p\n"
		, f_bfbase(*fp)
		, f_bfsize(*fp)
		, f_rd_bfbase(*fp)
		, f_wr_bfbase(*fp)
		, f_rd_flags(*fp)
		, f_wr_flags(*fp)
		);
	sm_io_flush(smioout);

	res = sm_io_close(fp, SM_IO_CF_NONE);
	return SM_SUCCESS;
}

int
main(int argc, char *argv[])
{
	int wr, c;
	sm_ret_T ret;

	opterr = 0;
	wr = 100;
	while ((c = getopt(argc, argv, "w:V")) != -1)
	{
		switch (c)
		{
		  case 'w':
			wr = atoi(optarg);
			break;
		  case 'V':
			++Verbose;
			break;
		  default:
/*
			usage(argv[0]);
*/
			return EX_USAGE;
		}
	}
	sm_test_begin(argc, argv, "test double buffer I/O");
	ret = write_some("io-double", wr);
	return sm_test_end();
}



syntax highlighted by Code2HTML, v. 0.9.1