Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 3 Jun 2009 15:15:32 +0300
From:      Vlad Galu <dudu@dudu.ro>
To:        freebsd-stable@freebsd.org
Subject:   poll()-ing a pipe descriptor, watching for POLLHUP
Message-ID:  <ad79ad6b0906030515k2e41f4b9t25f752af8ef3866c@mail.gmail.com>

next in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
Hello,

Please take a look at the attached code. Shouldn't poll() get a
POLLHUP event when the child process exits, closing the write end of
the pipe?

Thanks,
Vlad

[-- Attachment #2 --]
#include <sys/types.h>
#include <sys/wait.h>
#include <poll.h>
#include <unistd.h>

#include <iostream>
#include <map>
#include <vector>
using namespace std;

int main(int argc, char* argv[]) {
	map<pid_t, int> children;

	for (int i = 0; i < 4; i++) {
		int pipepair[2];
		if (!pipe(pipepair)) {
			pid_t pid = fork();
			if (pid > 0) {	// parent
				children[pid] = pipepair[0];
				cout << "Child process " << pid << " spawned" << endl;
			} else if (pid == 0) { // child
				// sleep for a while
				sleep(5);
				// gracefully exit
				exit(0);
			}
		} else
			cerr << "Couldn't create the pipes!" << endl;
	}

	// check the children
	while (!children.empty()) {
		for (map<pid_t, int>::iterator it = children.begin(); it != children.end(); it++) {
			// poll each child's pipe to check for data
			struct pollfd pfd = { it->second, POLLIN, 0 };
			int pollret = poll(&pfd, 1, 1000);
			cout << "pollret: " << pollret << endl;
			if (pollret > 0) {
				if ((pfd.revents & POLLIN) && (pfd.revents & POLLHUP))
					cout << "Child " << it->first << " exited!" << endl;

				if (pfd.revents & POLLIN) {
					vector<char> tmpbuf(4);
					int readret = read(it->second, &tmpbuf[0], 4);

					if (readret > 0)
						cout << "Child " << it->first << " said: " << string(tmpbuf.begin(), tmpbuf.end()) << endl;
					else if (readret == 0)
						cout << "EOF from child " << it->first << ", must've exited" << endl;
					else if (readret < 0)
						cout << "Read error" << endl;
				}
			}

			int status = 0;
			if (waitpid(it->first, &status, WNOHANG)) {
				if (WIFEXITED(status)) {
					cout << "Child " << it->first << " stopped" << endl;
//					children.erase(it++);
				}
			} else {
//				++it;
			}
			sleep(1);
		}
	}
}

// vi:ts=4


Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?ad79ad6b0906030515k2e41f4b9t25f752af8ef3866c>