From owner-freebsd-hackers@FreeBSD.ORG  Sun Mar 30 10:36:26 2008
Return-Path: <owner-freebsd-hackers@FreeBSD.ORG>
Delivered-To: freebsd-hackers@freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 3017D1065674
	for <freebsd-hackers@freebsd.org>; Sun, 30 Mar 2008 10:36:26 +0000 (UTC)
	(envelope-from fbsd.hackers@rachie.is-a-geek.net)
Received: from snoogles.rachie.is-a-geek.net (rachie.is-a-geek.net
	[66.230.99.27]) by mx1.freebsd.org (Postfix) with ESMTP id 0BA938FC1C
	for <freebsd-hackers@freebsd.org>; Sun, 30 Mar 2008 10:36:26 +0000 (UTC)
	(envelope-from fbsd.hackers@rachie.is-a-geek.net)
Received: from localhost (localhost [127.0.0.1])
	by snoogles.rachie.is-a-geek.net (Postfix) with ESMTP id 95BD01CD18
	for <freebsd-hackers@freebsd.org>;
	Sun, 30 Mar 2008 02:20:42 -0800 (AKDT)
From: Mel <fbsd.hackers@rachie.is-a-geek.net>
To: freebsd-hackers@freebsd.org
Date: Sun, 30 Mar 2008 12:20:38 +0200
User-Agent: KMail/1.9.7
MIME-Version: 1.0
Content-Type: text/plain;
  charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Message-Id: <200803301220.39921.fbsd.hackers@rachie.is-a-geek.net>
Subject: Popen and EVFILT_WRITE question
X-BeenThere: freebsd-hackers@freebsd.org
X-Mailman-Version: 2.1.5
Precedence: list
List-Id: Technical Discussions relating to FreeBSD
	<freebsd-hackers.freebsd.org>
List-Unsubscribe: <http://lists.freebsd.org/mailman/listinfo/freebsd-hackers>, 
	<mailto:freebsd-hackers-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/freebsd-hackers>
List-Post: <mailto:freebsd-hackers@freebsd.org>
List-Help: <mailto:freebsd-hackers-request@freebsd.org?subject=help>
List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/freebsd-hackers>,
	<mailto:freebsd-hackers-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Sun, 30 Mar 2008 10:36:26 -0000

Hi,

from reading the manpage on EVFILT_WRITE I thought it would be an easy to use 
interface to detect when a program wants input.
So far, that doesn't seem to be the case. Ultimately what I want to do is pipe 
all the popen(3)'d output to a logfile and act on any input it wants.

Could anyone explain to me why I'm never getting the EVFILT_WRITE event in 
below testcode?
(It doesn't matter if I open the pipe with w+ or r+).

test.c:
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <sysexits.h>
#include <err.h>
#include <stdio.h>

int main(int argc, char **argv)
{
	FILE *proc;
	int kq;
	struct kevent changes[2], events[2];

	proc = popen("./test.sh", "w+");
	if( -1 == (kq = kqueue()) )
		err(EX_OSERR, "Cannot get a kqueue");

	EV_SET(&changes[0], fileno(proc), EVFILT_WRITE, EV_ADD|EV_ENABLE, 0,
			0, 0);
	EV_SET(&changes[1], fileno(proc), EVFILT_READ, EV_ADD|EV_ENABLE, 0,
			0, 0);

	for( ;; )
	{
		int nev, i;

		if( -1 == (nev = kevent(kq, changes, 2, events, 2, NULL)) )
			err(EX_OSERR, "kevent");

		for( i = 0; i < nev; i++ )
		{
			char *buf;

			if( events[i].filter == EVFILT_READ )
			{
				if( events[i].flags & EV_ERROR )
				{
					warn("Event error");
					goto END;
				}
				if( events[i].flags & EV_EOF )
					goto END;
				buf = malloc(events[i].data);
				(void)fread(buf, sizeof(char), events[i].data, proc);
				(void)fwrite(buf, sizeof(char), events[i].data, stdout);
				free(buf);
			}
			else if( events[i].filter == EVFILT_WRITE )
			{
				if( events[i].flags & EV_ERROR )
				{
					warn("Event error");
					goto END;
				}
				if( events[i].flags & EV_EOF )
					goto END;
				fprintf(proc, "yes\n");
			}
		}
	}

END:
	close(kq);
	pclose(proc);
	return 0;
}

test.sh:
#!/bin/sh

i=0
while(test $i -lt 3); do
	echo sleeping
	sleep 1;
	i=$((i+1));
done

echo "Do you wanna write? "; read ANSWER
echo $ANSWER


-- 
Mel