00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <stdio.h>
00037 #include <unistd.h>
00038 #include <err.h>
00039 #include "triple.h"
00040
00041 static
00042 pid_t
00043 spawnv(const char *prog, char **argv)
00044 {
00045 pid_t pid = fork();
00046 switch (pid) {
00047 case -1:
00048 err(1, "fork");
00049 case 0:
00050
00051 execv(prog, argv);
00052 err(1, "%s: execv", prog);
00053 default:
00054
00055 break;
00056 }
00057 return pid;
00058 }
00059
00060 static
00061 int
00062 dowait(int index, int pid)
00063 {
00064 int status;
00065
00066 if (waitpid(pid, &status, 0)<0) {
00067 warn("waitpid for copy #%d (pid %d)", index, pid);
00068 return 1;
00069 }
00070 else if (WIFSIGNALED(status)) {
00071 warnx("copy #%d (pid %d): signal %d", index, pid,
00072 WTERMSIG(status));
00073 return 1;
00074 }
00075 else if (WEXITSTATUS(status) != 0) {
00076 warnx("copy #%d (pid %d): exit %d", index, pid,
00077 WEXITSTATUS(status));
00078 return 1;
00079 }
00080 return 0;
00081 }
00082
00083 void
00084 triple(const char *prog)
00085 {
00086 pid_t pids[3];
00087 int i, failures = 0;
00088 char *args[2];
00089
00090
00091 args[0]=(char *)prog;
00092 args[1]=NULL;
00093
00094 warnx("Starting: running three copies of %s...", prog);
00095
00096 for (i=0; i<3; i++) {
00097 pids[i]=spawnv(args[0], args);
00098 }
00099
00100 for (i=0; i<3; i++) {
00101 failures += dowait(i, pids[i]);
00102 }
00103
00104 if (failures > 0) {
00105 warnx("%d failures", failures);
00106 }
00107 else {
00108 warnx("Congratulations! You passed.");
00109 }
00110 }
00111