/*
 *  Copyright (C) 2006-2017, Thomas Maier-Komor
 *
 *  This is the source code of xjobs.
 *
 *  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, see <http://www.gnu.org/licenses/>.
 */

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#include "jobctrl.h"
#include "log.h"
#include "settings.h"

extern volatile int ChildTerminated,InputsWaiting;


int input_data(char *buf, size_t max)
{
	int n, ret, trys = 1;

	do {
#if __CYGWIN__
		if (-1 == Input) {
			dbug("yyinput(): reopening input\n");
			Input = open(Script,O_RDONLY);
			if (Input == -1)
			{
				warn("unable to reopen named pipe %s: %s\n",Script,strerror(errno));
				return 0;
			}
			ret = fcntl(Input,F_SETOWN,getpid());
			if (ret != 0)
				warn("unable to set owning process for SIGPIPE of named pipe %s: %s\n",Script,strerror(errno));
			ret = fcntl(Input,F_SETFL,InFlags);
			assert(ret == 0);
		}
		ret = fcntl(Input,F_SETOWN,getpid());
		if (ret != 0)
			warn("unable to set owning process for SIGPIPE of named pipe %s: %s\n",Script,strerror(errno));
		ret = fcntl(Input,F_SETFL,InFlags);
		assert(ret == 0);
#endif
		if (Script) {
			if ((Running == 0) && (Waiting == 0)) {
				if (InFlags & O_NONBLOCK) {
					dbug("yyinput(): block on input\n");
					InFlags &= ~O_NONBLOCK;
					ret = fcntl(Input,F_SETFL,InFlags);
					assert(ret == 0);
				}
			} else {
				if ((InFlags & O_NONBLOCK) == 0) {
					dbug("yyinput(): read non-block\n");
					InFlags |= O_NONBLOCK;
					ret = fcntl(Input,F_SETFL,InFlags);
					assert(ret == 0);
				}

			}
		}
		//dbug("yyinput(): read\n");
		assert(Input != -1);
		n = read(Input,buf,max);	
		if (0 == n) {
			//dbug("yyinput(): shortread\n");
			if (InputsWaiting > 0)
				--InputsWaiting;
#if __CYGWIN__
			(void) close(Input);
			Input = -1;
			++ChildTerminated;
#endif
		} else if (-1 == n) {
			if (InputsWaiting > 0)
				--InputsWaiting;
			if ((errno != EAGAIN) && (errno != EINTR)) {
				warn("error reading input: %s\n",strerror(errno));
				close(Input);
				Input = -1;
			} else {
				dbug("input unavailable: %s\n",strerror(errno));
				++trys;
			}
			n = 0;
		} else {
			dbug("yyinput() = %d\n",n);
			return n;
		}
	} while (--trys);
	dbug("yyinput() = -- bailout\n",n);
	return 0;
}


int yywrap(void)
{
	return 1;
}


