Пример #1
0
int getchild(int group, int child, int children)
{
	int pid;

	pid = FORK_OR_VFORK();

	if (pid < 0) {

		massmurder();	/* kill the kids */
		tst_brkm(TBROK, cleanup,
			 "\tFork failed (may be OK if under stress)");
		tst_exit();
	} else if (pid == 0) {	/* child does this */
		switch (children % NCHILD) {
		case 0:
#ifdef UCLINUX
			if (self_exec(argv0, "nd", 1, nfiles) < 0) {
				massmurder();
				tst_brkm(TBROK, cleanup, "\tself_exec failed");
				tst_exit();
			}
#else
			dochild1();	/* create existing directories */
#endif
			break;	/* so lint won't complain */
		case 1:
#ifdef UCLINUX
			if (self_exec(argv0, "n", 2) < 0) {
				massmurder();
				tst_brkm(TBROK, cleanup, "\tself_exec failed");
				tst_exit();
			}
#else
			dochild2();	/* remove nonexistant directories */
#endif
			break;
		case 2:
#ifdef UCLINUX
			if (self_exec(argv0, "nd", 3, group) < 0) {
				massmurder();
				tst_brkm(TBROK, cleanup, "\tself_exec failed");
				tst_exit();
			}
#else
			dochild3(group);	/* create/delete directories */
#endif
			break;
		default:
			tst_brkm(TFAIL, cleanup,
				 "Test not inplemented for child %d", child);
			exit(1);
			break;
		}
		exit(1);	/* If child gets here, something wrong */
	}
	pidlist[children] = pid;
	return 0;
}
Пример #2
0
int runtest(void)
{
	int i, j;
	int count, child, status;
	char tmpdir[MAXPATHLEN];

	/* Create permanent directories with holes in directory structure */

	for (j = 0; j < nfiles; j++) {
		sprintf(tmpdir, DIR_NAME, j);
		TEST(mkdir(tmpdir, MODE_RWX));

		if (TEST_RETURN < 0) {
			tst_brkm(TFAIL, cleanup,
				 "Error creating permanent directories, ERRNO = %d",
				 TEST_ERRNO);
		}
		if ((j % NCHILD) != 0) {
			if (rmdir(tmpdir) < 0) {
				tst_brkm(TFAIL, cleanup,
					 "Error removing directory, ERRNO = %d",
					 errno);
			}
		}
	}

	parent_pid = getpid();

	/* allocate space for list of child pid's */

	if ((pidlist = malloc((child_groups * NCHILD) * sizeof(int))) ==
	    NULL) {
		tst_brkm(TWARN, NULL,
			 "\tMalloc failed (may be OK if under stress)");
	}

	child_count = 0;
	for (j = 0; j < child_groups; j++) {
		for (i = 0; i < NCHILD; i++) {
			getchild(j, i, child_count);
			child_count++;
		}
	}

	/* If signal already received, skip to cleanup */

	if (!sigchld && !sigterm) {
		if (test_time) {
			/* To get out of sleep if signal caught */
			if (!setjmp(env_buf)) {
				jump++;
				sleep(test_time);
			}
		} else {
			pause();
		}
	}

	/* Reset signals since we are about to clean-up and to avoid
	 * problem with wait call *               $
	 * */

	if (signal(SIGTERM, SIG_IGN) == SIG_ERR) {
		tst_brkm(TFAIL, cleanup,
			 "Error resetting SIGTERM signal, ERRNO = %d", errno);
	}
	if (signal(SIGCLD, SIG_DFL) == SIG_ERR) {
		tst_brkm(TFAIL, cleanup,
			 "Error resetting SIGCLD signal, ERRNO = %d", errno);
	}

	if (test_time) {
		sleep(test_time);
	}

	/* Clean up children */
	massmurder();
	/*
	 * Watch children finish and show returns.
	 */

	count = 0;
	while (1) {
		if ((child = wait(&status)) > 0) {
			if (status != 0) {
				tst_brkm(TWARN,
					 NULL,
					 "\tChild{%d} exited status = %0x",
					 child, status);
			}
			count++;
		} else {
			if (errno != EINTR) {
				break;
			}
			tst_resm(TINFO, "\tSignal detected during wait");
		}
	}

	/*
	 * Make sure correct number of children exited.
	 */

	if (count != child_count) {
		tst_resm(TWARN, "\tWrong number of children waited on!");
		tst_brkm(TWARN, NULL, "\tSaw %d, expected %d", count,
			 NCHILD);
	}

	/* Check for core file in test directory. */

	if (access("core", 0) == 0) {
		tst_brkm(TWARN, NULL, "\tCore file found in test directory.");
	}

	/* Remove expected files */

	for (j = 0; j < nfiles; j += NCHILD) {
		sprintf(tmpdir, DIR_NAME, j);
		if (rmdir(tmpdir) < 0) {
			tst_brkm(TWARN,
				 NULL,
				 "\tError removing expected directory, ERRNO = %d",
				 errno);
		}
	}

	tst_resm(TPASS, "PASS");

	return 0;
}