1*0f4c859eSApple OSS Distributions #include <stdlib.h>
2*0f4c859eSApple OSS Distributions #include <stdio.h>
3*0f4c859eSApple OSS Distributions #include <unistd.h>
4*0f4c859eSApple OSS Distributions #include <stdint.h>
5*0f4c859eSApple OSS Distributions #include <errno.h>
6*0f4c859eSApple OSS Distributions #include <err.h>
7*0f4c859eSApple OSS Distributions #include <pthread.h>
8*0f4c859eSApple OSS Distributions #include <spawn.h>
9*0f4c859eSApple OSS Distributions
10*0f4c859eSApple OSS Distributions extern char **environ;
11*0f4c859eSApple OSS Distributions
12*0f4c859eSApple OSS Distributions char * const *newargv;
13*0f4c859eSApple OSS Distributions
14*0f4c859eSApple OSS Distributions void usage(void);
15*0f4c859eSApple OSS Distributions
16*0f4c859eSApple OSS Distributions void *work(void *);
17*0f4c859eSApple OSS Distributions
18*0f4c859eSApple OSS Distributions int
main(int argc,char * argv[])19*0f4c859eSApple OSS Distributions main(int argc, char *argv[])
20*0f4c859eSApple OSS Distributions {
21*0f4c859eSApple OSS Distributions int i, count, threadcount;
22*0f4c859eSApple OSS Distributions int ret;
23*0f4c859eSApple OSS Distributions pthread_t *threads;
24*0f4c859eSApple OSS Distributions
25*0f4c859eSApple OSS Distributions if (argc < 4) {
26*0f4c859eSApple OSS Distributions usage();
27*0f4c859eSApple OSS Distributions }
28*0f4c859eSApple OSS Distributions
29*0f4c859eSApple OSS Distributions threadcount = atoi(argv[1]);
30*0f4c859eSApple OSS Distributions count = atoi(argv[2]);
31*0f4c859eSApple OSS Distributions
32*0f4c859eSApple OSS Distributions newargv = &argv[3];
33*0f4c859eSApple OSS Distributions
34*0f4c859eSApple OSS Distributions threads = (pthread_t *)calloc(threadcount, sizeof(pthread_t));
35*0f4c859eSApple OSS Distributions for (i = 0; i < threadcount; i++) {
36*0f4c859eSApple OSS Distributions ret = pthread_create(&threads[i], NULL, work, (void *)(intptr_t)count);
37*0f4c859eSApple OSS Distributions if (ret) {
38*0f4c859eSApple OSS Distributions err(1, "pthread_create");
39*0f4c859eSApple OSS Distributions }
40*0f4c859eSApple OSS Distributions }
41*0f4c859eSApple OSS Distributions
42*0f4c859eSApple OSS Distributions for (i = 0; i < threadcount; i++) {
43*0f4c859eSApple OSS Distributions ret = pthread_join(threads[i], NULL);
44*0f4c859eSApple OSS Distributions if (ret) {
45*0f4c859eSApple OSS Distributions err(1, "pthread_join");
46*0f4c859eSApple OSS Distributions }
47*0f4c859eSApple OSS Distributions }
48*0f4c859eSApple OSS Distributions
49*0f4c859eSApple OSS Distributions return 0;
50*0f4c859eSApple OSS Distributions }
51*0f4c859eSApple OSS Distributions
52*0f4c859eSApple OSS Distributions void
usage(void)53*0f4c859eSApple OSS Distributions usage(void)
54*0f4c859eSApple OSS Distributions {
55*0f4c859eSApple OSS Distributions fprintf(stderr, "Usage: %s <threadcount> <count> <program> [<arg1> [<arg2> ...]]\n",
56*0f4c859eSApple OSS Distributions getprogname());
57*0f4c859eSApple OSS Distributions exit(1);
58*0f4c859eSApple OSS Distributions }
59*0f4c859eSApple OSS Distributions
60*0f4c859eSApple OSS Distributions void *
work(void * arg)61*0f4c859eSApple OSS Distributions work(void *arg)
62*0f4c859eSApple OSS Distributions {
63*0f4c859eSApple OSS Distributions int count = (int)(intptr_t)arg;
64*0f4c859eSApple OSS Distributions int i;
65*0f4c859eSApple OSS Distributions int ret;
66*0f4c859eSApple OSS Distributions pid_t pid;
67*0f4c859eSApple OSS Distributions
68*0f4c859eSApple OSS Distributions for (i = 0; i < count; i++) {
69*0f4c859eSApple OSS Distributions ret = posix_spawn(&pid, newargv[0], NULL, NULL, newargv, environ);
70*0f4c859eSApple OSS Distributions if (ret != 0) {
71*0f4c859eSApple OSS Distributions errc(1, ret, "posix_spawn(%s)", newargv[0]);
72*0f4c859eSApple OSS Distributions }
73*0f4c859eSApple OSS Distributions
74*0f4c859eSApple OSS Distributions while (-1 == waitpid(pid, &ret, 0)) {
75*0f4c859eSApple OSS Distributions if (errno != EINTR) {
76*0f4c859eSApple OSS Distributions err(1, "waitpid(%d)", pid);
77*0f4c859eSApple OSS Distributions }
78*0f4c859eSApple OSS Distributions }
79*0f4c859eSApple OSS Distributions
80*0f4c859eSApple OSS Distributions if (WIFSIGNALED(ret)) {
81*0f4c859eSApple OSS Distributions errx(1, "process exited with signal %d", WTERMSIG(ret));
82*0f4c859eSApple OSS Distributions } else if (WIFSTOPPED(ret)) {
83*0f4c859eSApple OSS Distributions errx(1, "process stopped with signal %d", WSTOPSIG(ret));
84*0f4c859eSApple OSS Distributions } else if (WIFEXITED(ret)) {
85*0f4c859eSApple OSS Distributions if (WEXITSTATUS(ret) != 42) {
86*0f4c859eSApple OSS Distributions errx(1, "process exited with unexpected exit code %d", WEXITSTATUS(ret));
87*0f4c859eSApple OSS Distributions }
88*0f4c859eSApple OSS Distributions } else {
89*0f4c859eSApple OSS Distributions errx(1, "unknown exit condition %x", ret);
90*0f4c859eSApple OSS Distributions }
91*0f4c859eSApple OSS Distributions }
92*0f4c859eSApple OSS Distributions
93*0f4c859eSApple OSS Distributions return NULL;
94*0f4c859eSApple OSS Distributions }
95