#define _GNU_SOURCE

#include <errno.h>
#include <error.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

void fork_child(unsigned nr)
{
	char *s;
	pid_t pid;
	off_t pos[2];
	int len, r;

	pid = fork();
	if (pid < 0)
		error(EXIT_FAILURE, errno, "fork");

	if (pid)
		return;

	len = asprintf(&s, "This is fork %u\n", nr);

	pos[0] = lseek(1, 0, SEEK_CUR);

	r = write(1, s, len);

	pos[1] = lseek(1, 0, SEEK_CUR);

	if (r != len)
		error(0, errno, "write: fork %u", nr);

	fprintf(stderr, "pos %-6zd -> %-6zd (fork %u)\n",
		pos[0], pos[1], nr);

	exit(0);
}

int main(int argc, char **argv)
{
	unsigned forks;
	unsigned i;
	int running = 0;
	unsigned burst;

	if (argc < 2)
		error(EXIT_FAILURE, 0, "Missing number of requested forks");

	if (argc > 4)
		error(EXIT_FAILURE, 0, "To many arguments");

	if (sscanf(argv[1], "%u", &forks) != 1)
		error(EXIT_FAILURE, errno, "Unable to convert '%s' to a "
		      "positive number", argv[1]);

	if ((argc < 3) || (sscanf(argv[2], "%u", &burst) != 1))
		burst = 0;

	for (i = 0; i < forks; i++) {
		int status;

		fork_child(i);
		running++;

		if (burst && i && !(i % burst)) {
			siginfo_t infop;

			infop.si_pid = 0;

			fprintf(stderr, "Burst wait: i=%d, burst=%d; running=%d -> ",
			       i, burst, running);

			while (1) {
			       if ((waitpid(-1, &status, WNOHANG) <= 0) ||
				   !WIFEXITED(status))
				       break;
			       running--;
			}

			fprintf(stderr, "%d\n", running);
		} else {
			if ((waitpid(-1, &status, WNOHANG) > 0) &&
			    WIFEXITED(status))
				running--;
		}
	}

	while (!waitid(P_ALL, 0, NULL, WEXITED))
		;

	error(0, 0, "exit");
}


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to