#ifndef bisqwit_likes_cats
#define bisqwit_likes_cats

/* cat.h - used in plis, erec and ecat                      */
/* Copyright (C) 1992,2002 Bisqwit (http://iki.fi/bisqwit/) */
/* Shared file version: 1.02                                */

#include <sys/poll.h>
#include <errno.h>
static void cat(void)
{
    char Buf[16384];

    /* We don't need any directories (don't keep mounted directories busy) */
    chdir("/");
    
    for(;;)
    {
        struct pollfd fds[2];
        int i, written;
        
        memset(&fds, 0, sizeof(fds));
        fds[0].fd = 0; fds[0].events = POLLIN;
        fds[1].fd = 1; fds[1].events = 0;
        
        /* Wait until data is available */
        i = poll(fds, 2, 60000);
        if(i < 0)
        {
            if(errno == EINTR)
                continue;
                
            /* UNEXPECTED ERROR */
            perror("poll(reading)");
            break;
        }
        
        if(fds[0].revents & POLLNVAL
        || fds[0].revents & POLLERR)
        {
        	/* End of input */
        	break;
        }
        
        if((fds[1].revents & POLLNVAL)
        || (fds[1].revents & POLLHUP)
        || (fds[1].revents & POLLERR))
        {
        	/* Broken pipe */
        	break;
        }
        
        if(fds[0].revents & POLLIN)
        {
            int wc, rc;
            rc = read(0, Buf, sizeof Buf);
            if(rc == 0)
            {
                /* End of file */
                break;
            }
            if(rc < 0)
            {
                if(errno == EAGAIN)continue;
                perror("read");
                /* READ ERROR */
                break;
            }
            written = 0;
        RetryWrite:
            wc = write(1, Buf+written, rc - written);
            if(wc < 0 && (errno == EAGAIN || errno == EINTR))wc = 0;
            if(wc < 0)
            {
                perror("write");
                /* WRITE ERROR */
                break;
            }
            if(wc < rc - written)
            {
		        memset(&fds, 0, sizeof(fds));
		        fds[0].fd = 1; fds[0].events = POLLOUT;
		        
                /* Wait until the output-fd is available */
		        i = poll(fds, 1, 60000);
		        if(i < 0)
		        {
		        	if(errno == EINTR)goto RetryWrite;
		        	/* UNEXPECTED ERROR */
		        	perror("poll(writing)");
		        	break;
		        }
		        
		        if(fds[0].revents & POLLHUP)
		        {
		        	/* Broken pipe */
		        	break;
		        }
		        
		        if(fds[0].revents & POLLOUT)
		        	goto RetryWrite;
		        
                fprintf(stderr, "Timeout writing\n");
                /* TIMEOUT WRITING */
            }
        }
        else if(fds[0].revents & POLLHUP)
        {
        	/* End of input */
        	break;
        }
    }
    close(0);
    close(1);
    exit(0);
}
#endif
