minix/test/test2.c
2005-08-22 15:08:27 +00:00

409 lines
7.5 KiB
C

/* test 2 */
#include <sys/types.h>
#include <sys/times.h>
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <stdio.h>
#define ITERATIONS 5
#define MAX_ERROR 4
int is, array[4], parsigs, parcum, sigct, cumsig, errct, subtest;
int iteration, kk = 0, errct = 0;
char buf[2048];
_PROTOTYPE(int main, (int argc, char *argv []));
_PROTOTYPE(void test2a, (void));
_PROTOTYPE(void test2b, (void));
_PROTOTYPE(void test2c, (void));
_PROTOTYPE(void test2d, (void));
_PROTOTYPE(void test2e, (void));
_PROTOTYPE(void test2f, (void));
_PROTOTYPE(void test2g, (void));
_PROTOTYPE(void test2h, (void));
_PROTOTYPE(void sigpip, (int s));
_PROTOTYPE(void quit, (void));
_PROTOTYPE(void e, (int n));
int main(argc, argv)
int argc;
char *argv[];
{
int i, m = 0xFFFF;
sync();
if (argc == 2) m = atoi(argv[1]);
printf("Test 2 ");
fflush(stdout); /* have to flush for child's benefit */
system("rm -rf DIR_02; mkdir DIR_02");
chdir("DIR_02");
for (i = 0; i < ITERATIONS; i++) {
iteration = i;
if (m & 0001) test2a();
if (m & 0002) test2b();
if (m & 0004) test2c();
if (m & 0010) test2d();
if (m & 0020) test2e();
if (m & 0040) test2f();
if (m & 0100) test2g();
if (m & 0200) test2h();
}
subtest = 100;
if (cumsig != ITERATIONS) e(101);
quit();
return(-1); /* impossible */
}
void test2a()
{
/* Test pipes */
int fd[2];
int n, i, j, q = 0;
subtest = 1;
if (pipe(fd) < 0) {
printf("pipe error. errno= %d\n", errno);
errct++;
quit();
}
i = fork();
if (i < 0) {
printf("fork failed\n");
errct++;
quit();
}
if (i != 0) {
/* Parent code */
close(fd[0]);
for (i = 0; i < 2048; i++) buf[i] = i & 0377;
for (q = 0; q < 8; q++) {
if (write(fd[1], buf, 2048) < 0) {
printf("write pipe err. errno=%d\n", errno);
errct++;
quit();
}
}
close(fd[1]);
wait(&q);
if (q != 256 * 58) {
printf("wrong exit code %d\n", q);
errct++;
quit();
}
} else {
/* Child code */
close(fd[1]);
for (q = 0; q < 32; q++) {
n = read(fd[0], buf, 512);
if (n != 512) {
printf("read yielded %d bytes, not 512\n", n);
errct++;
quit();
}
for (j = 0; j < n; j++)
if ((buf[j] & 0377) != (kk & 0377)) {
printf("wrong data: %d %d %d \n ",
j, buf[j] & 0377, kk & 0377);
} else {
kk++;
}
}
exit(58);
}
}
void test2b()
{
int fd[2], n;
char buf[4];
subtest = 2;
sigct = 0;
signal(SIGPIPE, sigpip);
pipe(fd);
if (fork()) {
/* Parent */
close(fd[0]);
while (sigct == 0) {
write(fd[1], buf, 1);
}
wait(&n);
} else {
/* Child */
close(fd[0]);
close(fd[1]);
exit(0);
}
}
void test2c()
{
int n;
subtest = 3;
signal(SIGINT, SIG_DFL);
is = 0;
if ((array[is++] = fork()) > 0) {
if ((array[is++] = fork()) > 0) {
if ((array[is++] = fork()) > 0) {
if ((array[is++] = fork()) > 0) {
signal(SIGINT, SIG_IGN);
kill(array[0], SIGINT);
kill(array[1], SIGINT);
kill(array[2], SIGINT);
kill(array[3], SIGINT);
wait(&n);
wait(&n);
wait(&n);
wait(&n);
} else {
pause();
}
} else {
pause();
}
} else {
pause();
}
} else {
pause();
}
}
void test2d()
{
int pid, stat_loc, s;
/* Test waitpid. */
subtest = 4;
/* Test waitpid(pid, arg2, 0) */
pid = fork();
if (pid < 0) e(1);
if (pid > 0) {
/* Parent. */
s = waitpid(pid, &stat_loc, 0);
if (s != pid) e(2);
if (WIFEXITED(stat_loc) == 0) e(3);
if (WIFSIGNALED(stat_loc) != 0) e(4);
if (WEXITSTATUS(stat_loc) != 22) e(5);
} else {
/* Child */
exit(22);
}
/* Test waitpid(-1, arg2, 0) */
pid = fork();
if (pid < 0) e(6);
if (pid > 0) {
/* Parent. */
s = waitpid(-1, &stat_loc, 0);
if (s != pid) e(7);
if (WIFEXITED(stat_loc) == 0) e(8);
if (WIFSIGNALED(stat_loc) != 0) e(9);
if (WEXITSTATUS(stat_loc) != 33) e(10);
} else {
/* Child */
exit(33);
}
/* Test waitpid(0, arg2, 0) */
pid = fork();
if (pid < 0) e(11);
if (pid > 0) {
/* Parent. */
s = waitpid(0, &stat_loc, 0);
if (s != pid) e(12);
if (WIFEXITED(stat_loc) == 0) e(13);
if (WIFSIGNALED(stat_loc) != 0) e(14);
if (WEXITSTATUS(stat_loc) != 44) e(15);
} else {
/* Child */
exit(44);
}
/* Test waitpid(0, arg2, WNOHANG) */
signal(SIGTERM, SIG_DFL);
pid = fork();
if (pid < 0) e(16);
if (pid > 0) {
/* Parent. */
s = waitpid(0, &stat_loc, WNOHANG);
if (s != 0) e(17);
if (kill(pid, SIGTERM) != 0) e(18);
if (waitpid(pid, &stat_loc, 0) != pid) e(19);
if (WIFEXITED(stat_loc) != 0) e(20);
if (WIFSIGNALED(stat_loc) == 0) e(21);
if (WTERMSIG(stat_loc) != SIGTERM) e(22);
} else {
/* Child */
pause();
}
/* Test some error conditions. */
errno = 9999;
if (waitpid(0, &stat_loc, 0) != -1) e(23);
if (errno != ECHILD) e(24);
errno = 9999;
if (waitpid(0, &stat_loc, WNOHANG) != -1) e(25);
if (errno != ECHILD) e(26);
}
void test2e()
{
int pid1, pid2, stat_loc, s;
/* Test waitpid with two children. */
subtest = 5;
if (iteration > 1) return; /* slow test, don't do it too much */
if ( (pid1 = fork())) {
/* Parent. */
if ( (pid2 = fork()) ) {
/* Parent. Collect second child first. */
s = waitpid(pid2, &stat_loc, 0);
if (s != pid2) e(1);
if (WIFEXITED(stat_loc) == 0) e(2);
if (WIFSIGNALED(stat_loc) != 0) e(3);
if (WEXITSTATUS(stat_loc) != 222) e(4);
/* Now collect first child. */
s = waitpid(pid1, &stat_loc, 0);
if (s != pid1) e(5);
if (WIFEXITED(stat_loc) == 0) e(6);
if (WIFSIGNALED(stat_loc) != 0) e(7);
if (WEXITSTATUS(stat_loc) != 111) e(8);
} else {
/* Child 2. */
sleep(2); /* child 2 delays before exiting. */
exit(222);
}
} else {
/* Child 1. */
exit(111); /* child 1 exits immediately */
}
}
void test2f()
{
/* test getpid, getppid, getuid, etc. */
pid_t pid, pid1, ppid, cpid, stat_loc, err;
subtest = 6;
errno = -2000;
err = 0;
pid = getpid();
if ( (pid1 = fork())) {
/* Parent. Do nothing. */
if (wait(&stat_loc) != pid1) e(1);
if (WEXITSTATUS(stat_loc) != (pid1 & 0377)) e(2);
} else {
/* Child. Get ppid. */
cpid = getpid();
ppid = getppid();
if (ppid != pid) err = 3;
if (cpid == ppid) err = 4;
exit(cpid & 0377);
}
if (err != 0) e(err);
}
void test2g()
{
/* test time(), times() */
time_t t1, t2;
clock_t t3, t4;
struct tms tmsbuf;
subtest = 7;
errno = -7000;
/* First time(). */
t1 = -1;
t2 = -2;
t1 = time(&t2);
if (t1 < 650000000L) e(1); /* 650000000 is Sept. 1990 */
if (t1 != t2) e(2);
t1 = -1;
t1 = time( (time_t *) NULL);
if (t1 < 650000000L) e(3);
t3 = times(&tmsbuf);
sleep(1);
t2 = time( (time_t *) NULL);
if (t2 < 0L) e(4);
if (t2 - t1 < 1) e(5);
/* Now times(). */
t4 = times(&tmsbuf);
if ( t4 == (clock_t) -1) e(6);
if (t4 - t3 < CLOCKS_PER_SEC) e(7);
if (tmsbuf.tms_utime < 0) e(8);
if (tmsbuf.tms_stime < 0) e(9);
if (tmsbuf.tms_cutime < 0) e(10);
if (tmsbuf.tms_cstime < 0) e(11);
}
void test2h()
{
/* Test getgroups(). */
gid_t g[10];
subtest = 8;
errno = -8000;
if (getgroups(10, g) != 0) e(1);
if (getgroups(1, g) != 0) e(2);
if (getgroups(0, g) != 0) e(3);
}
void sigpip(s)
int s; /* for ANSI */
{
sigct++;
cumsig++;
}
void quit()
{
chdir("..");
system("rm -rf DIR*");
if (errct == 0) {
printf("ok\n");
exit(0);
} else {
printf("%d errors\n", errct);
exit(4);
}
}
void e(n)
int n;
{
int err_num = errno; /* save errno in case printf clobbers it */
printf("Subtest %d, error %d errno=%d ", subtest, n, errno);
errno = err_num; /* restore errno, just in case */
perror("");
if (errct++ > MAX_ERROR) {
printf("Too many errors; test aborted\n");
chdir("..");
system("rm -rf DIR*");
exit(1);
}
}