
/*
 *  TEST.C
 *
 *  TEST [R/W][N] fifo_name
 *
 *  test fifo operation
 *
 */

#include <exec/types.h>
#include <exec/ports.h>
#include <libraries/dos.h>
#include <stdio.h>
#include "fifo.h"

typedef struct MsgPort	MsgPort;
typedef struct Message	Message;

long FifoBase;
long Fh;
MsgPort *WaPort;
char IBuf[256];

void DoWait();
void *CreatePort();

void
myexit(void)
{
    if (Fh) {
	CloseFifo(Fh, FIFOF_EOF);
	Fh = 0;
    }
    if (FifoBase) {
	CloseLibrary(FifoBase);
	FifoBase = 0;
    }
    if (WaPort) {
	DeletePort(WaPort);
	WaPort = NULL;
    }
}

main(ac, av)
char *av[];
{
    if (ac != 3) {
	fputs("TEST [R/W][N] fifo_name\n", stderr);
	exit(1);
    }
    atexit(myexit);

    WaPort = CreatePort(NULL, 0);

    if (FifoBase = OpenLibrary(FIFONAME, 0)) {
	long flags = FIFOF_NORMAL;

	fputs("fifo.library opened!\n", stderr);

	if (av[1][1] == 'N')
	    flags |= FIFOF_NBIO;

	switch(av[1][0]) {
	case 'R':
	    if (Fh = OpenFifo(av[2], 4096, FIFOF_READ | flags)) {
		long i = 0;
		char *ptr;

		fprintf(stderr, "fifo is %d bytes\n", BufSizeFifo(Fh));
		for (;;) {
		    long n = ReadFifo(Fh, &ptr, i);
		    if (n > 64)     /*  limit amount of data read/loop */
			n = 64;
		    i = n;

		    if (n < 0) {
			fputs("EOF\n", stderr);
			break;
		    }
		    if (n > 0) {
			/*
			 *  just so other windows doesn't freeze while we
			 *  output kilobytes.
			 */

			write(1, ptr, n);
		    } else {	    /*	n == 0	*/
			if (flags & FIFOF_NBIO) {
			    DoWait(FREQ_RPEND);
			} else {
			    puts("0 bytes avail?");
			}
		    }
		    chkabort();
		}
	    }
	    break;
	case 'W':
	    if (Fh = OpenFifo(av[2], 4096, FIFOF_WRITE | FIFOF_KEEPIFD | flags)) {
		long n;

		fprintf(stderr, "fifo is %d bytes\n", BufSizeFifo(Fh));

		while ((n = read(0, IBuf, sizeof(IBuf))) > 0) {
		    long r;
		    long x = 5;

loop:
		    r = WriteFifo(Fh, IBuf, n);
		    if (r != n) {
			if (r >= 0 && (flags & FIFOF_NBIO)) {
			    DoWait(FREQ_WAVAIL);
			    goto loop;
			} else {
			    fprintf(stderr, "write failed! %d\n", r);
			    break;
			}
		    }
		}
	    }
	    break;
	default:
	    fputs("bad command line", stderr);
	    break;
	}
    }
    return(0);
}

void
DoWait(req)
long req;
{
    Message msg;
    long mask = 0;

    fputs("WAIT\n", stderr);
    msg.mn_ReplyPort = WaPort;
    RequestFifo(Fh, &msg, req);

    while (msg.mn_Node.ln_Type == NT_MESSAGE) {
	mask = Wait(SIGBREAKF_CTRL_C | (1 << WaPort->mp_SigBit));
	if (mask & SIGBREAKF_CTRL_C)
	    RequestFifo(Fh, &msg, FREQ_ABORT);
    }
    GetMsg(WaPort);
    if (mask & SIGBREAKF_CTRL_C)
	fputs("WAIT: ABORT\n", stderr);
}

