books/apitue/sample-code/13/busy-child.c

90 lines
1.9 KiB
C
Raw Normal View History

2024-01-20 14:39:54 +00:00
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
/* This program creates as many worker children as
* requested. To facilitate identification in the
* process table, we self-exec with a fake argv[0].
*/
#include <sys/wait.h>
#include <err.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#define ARGV0_LENGTH 8 + 1 /* "worker" + 2 digits + NULL */
#define MAXCHILDREN 32
void
work() {
int i = 0;
while (1) {
i++;
}
}
int
main(int argc, char **argv) {
int n;
pid_t pid;
if (argc == 1) {
work();
/* NOTREACHED */
} else if (argc > 2) {
(void)fprintf(stderr, "Usage: %s num\n", argv[0]);
exit(EXIT_FAILURE);
/* NOTREACHED */
}
n = atoi(argv[1]);
if ((n < 1) || (n > MAXCHILDREN)) {
(void)fprintf(stderr, "Please provide a number > 0 and <= %d.\n", MAXCHILDREN);
exit(EXIT_FAILURE);
/* NOTREACHED */
}
for (int i = 0; i < n; i++) {
if ((pid = fork()) < 0) {
err(EXIT_FAILURE, "fork");
/* NOTREACHED */
} else if (!pid) {
char argv0[ARGV0_LENGTH];
bzero(argv0, ARGV0_LENGTH);
(void)snprintf(argv0, ARGV0_LENGTH, "worker%d", i);
(void)printf("Created %s: %d\n", argv0, getpid());
char * const args[] = { argv0, NULL };
execve("./a.out", args, NULL);
err(EXIT_FAILURE, "execve");
/* NOTREACHED */
}
}
while ((pid = wait(NULL)) > 0);
if ((pid < 0) && errno != ECHILD) {
err(EXIT_FAILURE, "wait");
/* NOTREACHED */
}
return EXIT_SUCCESS;
}