int main(const int argc,char* argv[])
{
	//test_fork_return_twice();
	test_fork();
	//test_vfork();
	return 0;
}
Beispiel #2
0
int main(int argc, char **argv)
{
	int rv, i;
	int counter = 0;

	test_init(argc, argv);

	if (scale > MAX_SCALE) {
		err("Too many children specified\n");
		exit(-1);
	}

	if (signal(SIGUSR2, do_stop) == SIG_ERR) {
		err("Can't setup handler\n");
		exit(-1);
	}

	for (i = 0; i < scale; i++) {
		rv = test_fork();
		if (rv == -1) {
			err("Can't fork\n");
			killall();
			exit(-1);
		}
		if (rv == 0)
			chew_some_file(i);
		pids[i] = rv;
	}

	test_daemon();
	test_waitsig();

	killall();
	for (i = 0; i < scale; i++) {
		if (waitpid(pids[i], &rv, 0) == -1) {
			fail("Can't wipe up the kid\n");
			counter++;
			continue;
		}
		if (!WIFEXITED(rv)) {
			fail("Kid was killed\n");
			counter++;
		} else {
			rv = WEXITSTATUS(rv);
			if (rv < MAX_EXIT_CODE_VAL && rv > SUCCESS) {
				fail("Kid failed: %s (%d)\n",
						kids_fail_reasons[rv], rv);
				counter++;
			} else if (rv != SUCCESS) {
				fail("Unknow exitcode from kid: %d\n", rv);
				counter++;
			}
		}
	}

	if (counter == 0)
		pass();
	return 0;
}
int main(int argc, char *argv[]){
	int number_of_cycles[] = {50000,100000,150000,200000};
	int i = 0;
	

//	for(i = 0; i<1;i++){
//		printf("\n counter after fork %d, real_time %ld ", counter, test_fork(number_of_cycles[i]));
//		counter = 0;		
//		printf("\n counter after vfork %d, real_time %ld ", counter, test_vfork(number_of_cycles[i]));
//		counter = 0;
//		printf("\n counter after clone_fork %d, real_time %ld ", counter, test_clone_fork(number_of_cycles[i]));
//		counter = 0;
//		printf("\n counter after clone_vfork %d, real_time %ld ", counter, test_clone_vfork(number_of_cycles[i]));
//	}

	FILE *parent_handle;
	if( (parent_handle = fopen("data/parent","w")) < 0) perror("fopen failed");
	FILE *child_handle;
	if( (child_handle = fopen("data/child","w")) < 0) perror("fopen failed");
	FILE *sum_handle;
	if( (sum_handle = fopen("data/sum","w")) < 0) perror("fopen failed");
	fprintf(parent_handle,"%10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s","N","sys_f","usr_f","syusr_f","real_f","syst_f","usr_vf","syusr_vf","real_vf","sys_cf","usr_cf","syusr_cf","real_cf","sys_cvf","usr_cvf","syusr_cvf","real_cvf");
	fprintf(child_handle,"%10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s","N","sys_f","usr_f","syusr_f","real_f","syst_f","usr_vf","syusr_vf","real_vf","sys_cf","usr_cf","syusr_cf","real_cf","sys_cvf","usr_cvf","syusr_cvf","real_cvf");
	fprintf(sum_handle,"%10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s","N","sys_f","usr_f","syusr_f","real_f","syst_f","usr_vf","syusr_vf","real_vf","sys_cf","usr_cf","syusr_cf","real_cf","sys_cvf","usr_cvf","syusr_cvf","real_cvf");
	for(i = 0; i<4; i++){
		struct tms *t = malloc(sizeof(struct tms));
		fprintf(parent_handle,"\n%10d ", number_of_cycles[i]);
		fprintf(child_handle,"\n%10d ", number_of_cycles[i]);
		fprintf(sum_handle,"\n%10d ", number_of_cycles[i]);
		counter = 0;
		clock_t p_real_time = times(t);
		suseconds_t c_real_time = test_fork(number_of_cycles[i]);
		time_checker(t, c_real_time, p_real_time, parent_handle, child_handle, sum_handle); 		
	
		p_real_time = times(t); 
		counter = 0;	
		c_real_time = test_vfork(number_of_cycles[i]);
		time_checker(t, c_real_time, p_real_time, parent_handle, child_handle, sum_handle); 		
		
		p_real_time = times(t);
		counter = 0;
		c_real_time = test_clone_fork(number_of_cycles[i]);
		time_checker(t, c_real_time, p_real_time, parent_handle, child_handle, sum_handle); 		
		
		p_real_time = times(t);
		counter = 0;
		c_real_time = test_clone_vfork(number_of_cycles[i]);
		time_checker(t, c_real_time, p_real_time, parent_handle, child_handle, sum_handle); 		
	}


	

return 0;
}
Beispiel #4
0
int main(int argc, char **argv)
{
    test_file();
    test_fork();
    test_time();
    test_socket();
    //    test_clone();
    test_signal();
    test_shm();
    return 0;
}
Beispiel #5
0
int main(void)
{
	int ret;

	ret = test_init();
	if (ret != 0) {
		fprintf(stderr, "test_init failed\n");
		return 1;
	}

	ret = test_fork();
	if (ret != 0) {
		fprintf(stderr, "test_fork failed\n");
		return 1;
	}

	ret = test_jobs(10, 10000);
	if (ret != 0) {
		fprintf(stderr, "test_jobs failed\n");
		return 1;
	}

	ret = test_busydestroy();
	if (ret != 0) {
		fprintf(stderr, "test_busydestroy failed\n");
		return 1;
	}

	/*
	 * Test 10 threads adding jobs on a single pool
	 */
	ret = test_threaded_addjob(1, 10, 5, 5000);
	if (ret != 0) {
		fprintf(stderr, "test_jobs failed\n");
		return 1;
	}

	/*
	 * Test 10 threads on 3 pools to verify our fork handling
	 * works right.
	 */
	ret = test_threaded_addjob(3, 10, 5, 5000);
	if (ret != 0) {
		fprintf(stderr, "test_jobs failed\n");
		return 1;
	}

	printf("success\n");
	return 0;
}
Beispiel #6
0
int main(int argc, char **argv)
{
	int ret = 0;
	int readfd, writefd;
	mode_t mode = S_IFIFO | 0644;
	char path[PROCS_DEF][BUF_SIZE];
	pid_t pid;
	int i;
	uint8_t buf[0x100000];
	char *file_path;

	test_init(argc, argv);

	for (i = 0; i < PROCS_DEF; i++) {
		file_path = path[i];
		if (snprintf(file_path, BUF_SIZE, "%s-%02d", filename, i) >= BUF_SIZE) {
			err("filename %s is too long\n", filename);
			exit(1);
		}
		if (mkfifo(file_path, mode)) {
			err("can't make fifo \"%s\": %m\n", file_path);
			exit(1);
		}
	}

	if (signal(SIGCHLD, inc_num_exited) == SIG_ERR) {
		err("can't set SIGCHLD handler: %m\n");
		exit(1);
	}

	for (i = 1; i < num_procs; i++) {	/* i = 0 - parent */
		pid = test_fork();
		if (pid < 0) {
			err("Can't fork: %m\n");
			kill(0, SIGKILL);
			exit(1);
		}
		if (pid == 0) {
			file_path = path[i - 1];
			readfd = open(file_path, O_RDONLY);
			if (readfd < 0) {
				err("open(%s, O_RDONLY) Failed: %m\n",
					file_path);
				ret = errno;
				return ret;
			}
			file_path = path[i];
			writefd = open(file_path, O_WRONLY);
			if (writefd < 0) {
				err("open(%s, O_WRONLY) Failed: %m\n",
					file_path);
				ret = errno;
				return ret;
			}
			signal(SIGPIPE, SIG_IGN);
			if (pipe_in2out(readfd, writefd, buf, sizeof(buf)) < 0)
				/* pass errno as exit code to the parent */
				if (test_go() /* signal NOT delivered */ ||
						(errno != EINTR && errno != EPIPE))
					ret = errno;
			close(readfd);
			close(writefd);
			exit(ret);
		}
		pids[i] = pid;
	}

	file_path = path[0];
	writefd = open(file_path, O_WRONLY);
	if (writefd < 0) {
		err("open(%s, O_WRONLY) Failed: %m\n", file_path);
		kill(0, SIGKILL);
		exit(1);
	}

	file_path = path[i - 1];
	readfd = open(file_path, O_RDONLY);
	if (readfd < 0) {
		err("open(%s, O_RDONLY) Failed: %m\n", file_path);
		kill(0, SIGKILL);
		exit(1);
	}

	if (num_exited) {
		err("Some children died unexpectedly\n");
		kill(0, SIGKILL);
		exit(1);
	}

	test_daemon();

	while (test_go()) {
		int len, rlen = 0, wlen;
		uint8_t rbuf[sizeof(buf)], *p;

		datagen(buf, sizeof(buf), NULL);
		wlen = write(writefd, buf, sizeof(buf));
		if (wlen < 0) {
			if (errno == EINTR)
				continue;
			else {
				fail("write failed: %m\n");
				ret = 1;
				break;
			}
		}

		for (p = rbuf, len = wlen; len > 0; p += rlen, len -= rlen) {
			rlen = read(readfd, p, len);
			if (rlen <= 0)
				break;
		}

		if (rlen < 0 && errno == EINTR)
			continue;

		if (len > 0) {
			fail("read failed: %m\n");
			ret = 1;
			break;
		}

		if (memcmp(buf, rbuf, wlen)) {
			fail("data mismatch\n");
			ret = 1;
			break;
		}
	}

	close(writefd);

	test_waitsig(); /* even if failed, wait for migration to complete */

	if (kill(0, SIGTERM)) {
		fail("failed to send SIGTERM to my process group: %m\n");
		return 1;	/* shouldn't wait() in this case */
	}
	close(readfd);

	for (i = 1; i < num_procs; i++) {	/* i = 0 - parent */
		int chret;
		if (waitpid(pids[i], &chret, 0) < 0) {
			fail("waitpid error: %m\n");
			ret = 1;
			continue;
		}

		chret = WEXITSTATUS(chret);
		if (chret) {
			fail("child %d exited with non-zero code %d (%s)\n",
				i, chret, strerror(chret));
			ret = 1;
			continue;
		}
	}

	if (!ret)
		pass();

	for (i = 0; i < PROCS_DEF; i++)
		unlink(path[i]);
	return 0;
}
Beispiel #7
0
int main(int argc, char **argv)
{
	char buf[BUF_SIZE];
	int fd, fd_s;
	struct aiocb aiocb;
	int status;
	pid_t pid;
	int ret, res;
	const struct aiocb   *aioary[1];
	task_waiter_t child_waiter;

	test_init(argc, argv);

	task_waiter_init(&child_waiter);

	if ((fd_s = tcp_init_server(AF_INET, &port)) < 0) {
		pr_err("initializing server failed\n");
		return 1;
	}

	pid = test_fork();
	if (pid < 0) {
		pr_perror("fork failed");
		return 1;
	}

	if (pid == 0) {
		/*
		 * Chiled is client of TCP connection
		 */
		close(fd_s);
		fd = tcp_init_client(AF_INET, "127.0.0.1", port);
		if (fd < 0)
			return 1;

		memset(&aiocb, 0, sizeof(struct aiocb));
		aiocb.aio_fildes = fd;
		aiocb.aio_buf = buf;
		aiocb.aio_nbytes = BUF_SIZE;
		ret = aio_read(&aiocb);
		if (ret < 0) {
			pr_perror("aio_read failed");
			return 1;
		}

		task_waiter_complete_current(&child_waiter);

		/* Wait for request completion */
		aioary[0] = &aiocb;
		ret = aio_error(&aiocb);
#ifdef DEBUG
		test_msg(".");
#endif
		res = 0;
again:
		if (aio_suspend(aioary, 1, NULL) < 0 && errno != EINTR) {
			pr_perror("aio_suspend failed");
			res = 1;
		}

		ret = aio_error(&aiocb);
		if (!res && ret == EINPROGRESS) {
#ifdef DEBUG
			test_msg("restart aio_suspend\n");
#endif
			goto again;
		}
		if (ret != 0) {
			pr_err("Error at aio_error(): %s\n", strerror(ret));
			res = 1;
		}

		if (aio_return(&aiocb) != BUF_SIZE) {
			pr_perror("Error at aio_return()");
			res = 1;
		}

		close(fd);
		return res;
	}

	/*
	 * parent is server of TCP connection
	 */
	fd = tcp_accept_server(fd_s);
	close(fd_s);
	if (fd < 0) {
		pr_err("can't accept client connection\n");
		goto error;
	}

	task_waiter_wait4(&child_waiter, pid);

	test_daemon();
	test_waitsig();

	if (write(fd, buf, BUF_SIZE) < BUF_SIZE) {
		pr_perror("can't write");
		goto error;
	}
	close(fd);


	if (wait(&status) < 0) {
		pr_perror("wait failed");
		goto error;
	}

	if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
		pr_err("child failed with exit code %d\n", WEXITSTATUS(status));
		return 1;
	}

	pass();
	return 0;
error:
	kill(pid, SIGKILL);
	wait(&status);
	return -1;
}
Beispiel #8
0
int main(int argc, char **argv)
{
	int fd, fd1;
	struct stat st;
	mode_t mode = S_IFIFO | 0600;
	int pid;
	int chret;

	test_init(argc, argv);

	if (mknod(filename, mode, 0)) {
		pr_perror("can't make fifo \"%s\"", filename);
		exit(1);
	}

	pid = test_fork();
	if (pid < 0) {
		pr_perror("Can't fork");
		exit(1);
	}

	if (pid == 0) {
		char rbuf[BUF_SIZE];
		int res;
		fd1 = open(filename, O_RDONLY);
		if (fd1 < 0) {
			pr_perror("open(%s, O_RDONLY) Failed", filename);
			chret = errno;
			return chret;
		}
		res = read(fd1, rbuf, 7);
		if (res < 0) {
			pr_perror("read error %s", filename);
			chret = errno;
			return chret;
		}
		else if (res == 0) {
			pr_perror("read(%d, rbuf, 7) return 0", fd1);
			return 1;
		}
		if (close(fd1) < 0) {
			fail("can't close %d, %s: %m", fd1, filename);
			chret = errno;
			return chret;
		}

	} else {

		fd = open(filename, O_WRONLY);
		if (fd < 0) {
			pr_perror("open(%s, O_WRONLY) Failed", filename);
			kill(pid, SIGKILL);
			wait(NULL);
			return 1;
		}

		test_daemon();
		test_waitsig();

		if (write(fd, "string", 7) == -1) {
			pr_perror("write(%d, 'string', 7) Failed", fd);
			return 1;
		}

		wait(&chret);
		chret = WEXITSTATUS(chret);
		if (chret) {
			fail("child exited with non-zero code %d (%s)\n",
				chret, strerror(chret));
			return 1;
		}

		if (close(fd) < 0) {
			fail("can't close %d, %s: %m", fd, filename);
			return 1;
		}

		if (stat(filename, &st) < 0) {
			fail("can't stat %s: %m", filename);
			return 1;
		}

		if (st.st_mode != mode) {
			fail("%s is no longer the fifo we had", filename);
			return 1;
		}

		if (unlink(filename) < 0) {
			fail("can't unlink %s: %m", filename);
			return 1;
		}
	}

	pass();
	return 0;
}
Beispiel #9
0
int main(int argc, char ** argv)
{
	int pipe1[2];
	int pipe2[2];
	int ret;
	pid_t pid;
	char buf[sizeof(TEST_STRING)];

	test_init(argc, argv);

	ret = pipe(pipe1);
	if (ret)
		return 1;

	ret = pipe(pipe2);
	if (ret)
		return 1;

	pid = test_fork();
	if (pid < 0) {
		err("Can't fork");
		exit(1);
	} else if (pid == 0) {
		if (dup2(pipe1[1], 11) == -1 || dup2(pipe2[0], 12) == -1) {
			err("dup2 failed");
			return 1;
		}
	} else {
		if (dup2(pipe1[0], 12) == -1 ||	dup2(pipe2[1], 11) == -1) {
			err("dup2 failed");
			goto err;
		}
	}

	close(pipe2[0]);
	close(pipe2[1]);
	close(pipe1[0]);
	close(pipe1[1]);

	if (pid > 0) {
		int status;

		test_daemon();

		while (test_go())
			;

		ret = read(12, buf, sizeof(TEST_STRING));
		if (ret != sizeof(TEST_STRING)) {
			err("read failed: %d", ret);
			goto err;
		}
		ret = write(11, TEST_STRING, sizeof(TEST_STRING));
		if (ret != sizeof(TEST_STRING)) {
			err("write failed: %d", ret);
			goto err;
		}
		close(11);
		ret = read(12, buf, sizeof(TEST_STRING));
		if (ret != sizeof(TEST_STRING)) {
			err("read failed: %d", ret);
			goto err;
		}
		if (strcmp(TEST_STRING, buf)) {
			err("data curruption");
			goto err;
		}

		ret = wait(&status);
		if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status)) {
			kill(pid, SIGKILL);
			goto err;
		}

		pass();
	} else {
		ret = write(11, TEST_STRING, sizeof(TEST_STRING));
		if (ret != sizeof(TEST_STRING)) {
			err("write failed: %d", ret);
			return 1;
		}
		ret = read(12, buf, sizeof(TEST_STRING));
		if (ret != sizeof(TEST_STRING)) {
			err("read failed: %d", ret);
			return 1;
		}
		ret = write(11, TEST_STRING, sizeof(TEST_STRING));
		if (ret != sizeof(TEST_STRING)) {
			err("write failed: %d", ret);
			return 1;
		}
		close(11);
		if (strcmp(TEST_STRING, buf)) {
			err("data curruption");
			return 1;
		}
	}

	return 0;
err:
	err("FAIL");
	return 1;
}
Beispiel #10
0
int main(int argc, char ** argv)
{
	int fdm, fds, status;
	task_waiter_t t;
	char *slavename;
	pid_t pid;

	test_init(argc, argv);

	task_waiter_init(&t);

	fdm = open("/dev/ptmx", O_RDWR);
	if (fdm == -1) {
		pr_perror("Can't open a master pseudoterminal");
		return 1;
	}

	grantpt(fdm);
	unlockpt(fdm);
	slavename = ptsname(fdm);

	pid = test_fork();
	if (pid < 0) {
		pr_perror("fork() failed");
		return 1;
	}

	if (pid == 0) {
		close(fdm);
		signal(SIGHUP, sighup_handler);

		if (setsid() == -1)
			return 1;

		/* set up a controlling terminal */
		fds = open(slavename, O_RDWR);
		if (fds == -1) {
			pr_perror("Can't open a slave pseudoterminal %s", slavename);
			return 1;
		}

		if (ioctl(fdm, TIOCSCTTY, 1) < 0) {
			pr_perror("Can't setup a controlling terminal");
			return 1;
		}
		close(fds);

		task_waiter_complete_current(&t);

		test_waitsig();
		if (sighup)
			return 0;
		return 1;
	}

	task_waiter_wait4(&t, pid);

	test_daemon();

	test_waitsig();

	close(fdm);

	if (kill(pid, SIGTERM) == -1) {
		pr_perror("kill failed");
		return 1;
	}

	pid = waitpid(pid, &status, 0);
	if (pid < 0)
		return 1;

	if (WIFEXITED(status)) {
		if (WEXITSTATUS(status)) {
			fail("The child returned %d", WEXITSTATUS(status));
			return 1;
		}
	} else {
		test_msg("The child has been killed by %d\n", WTERMSIG(status));
		return 1;
	}

	pass();

	return 0;
}
Beispiel #11
0
int main(int argc, char *argv[])
{
    struct sigaction saio = { };
    struct params obtained = { };
    uid_t ruid, euid, suid;
    int status, pipes[2];
    pid_t pid;

    test_init(argc, argv);

    shared = (void *)mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
    if ((void *)shared == MAP_FAILED) {
        fail("mmap failed");
        exit(1);
    }

    if (getresuid(&ruid, &euid, &suid)) {
        fail("getresuid failed\n");
        exit(1);
    }

    if (pipe(pipes)) {
        err("Can't create pipe: %m\n");
        exit(1);
    }

    saio.sa_handler	= (sig_t)signal_handler_io;
    saio.sa_flags	= SA_RESTART;
    if (sigaction(SIGIO, &saio, 0)) {
        fail("sigaction failed\n");
        exit(1);
    }

    if (setresuid(-1, 1, -1)) {
        fail("setresuid failed\n");
        exit(1);
    }

    if (fcntl(pipes[0], F_SETOWN, getpid())					||
            fcntl(pipes[1], F_SETOWN, getpid())					||
            fcntl(pipes[0], F_SETSIG, SIGIO)					||
            fcntl(pipes[1], F_SETSIG, SIGIO)					||
            fcntl(pipes[0], F_SETFL, fcntl(pipes[0], F_GETFL) | O_ASYNC)	||
            fcntl(pipes[1], F_SETFL, fcntl(pipes[1], F_GETFL) | O_ASYNC)) {
        fail("fcntl failed\n");
        exit(1);
    }

    asm volatile ("" :::);

    fill_pipe_params(shared, pipes);

    if (setresuid(-1, euid, -1)) {
        fail("setresuid failed\n");
        exit(1);
    }

    pid = test_fork();
    if (pid < 0) {
        err("can't fork %m");
        exit(1);
    }

    if (pid == 0) {
        struct params p = { };

        test_waitsig();

        fcntl(pipes[1], F_SETOWN, getpid());
        fill_pipe_params(&p, pipes);

        if (write(pipes[1], &p, sizeof(p)) != sizeof(p)) {
            fail("write failed\n");
            exit(1);
        }

        exit(0);
    }

    test_daemon();
    test_waitsig();
    kill(pid, SIGTERM);

    if (waitpid(pid, &status, P_ALL) == -1) {
        fail("waitpid failed\n");
        exit(1);
    }

    if (read(pipes[0], &obtained, sizeof(obtained)) != sizeof(obtained)) {
        fail("read failed\n");
        exit(1);
    }

    if (shared->sigio < 1) {
        fail("shared->sigio = %d (> 0 expected)\n", shared->sigio);
        exit(1);
    }

    shared->pipe_pid[1] = pid;

    if (cmp_pipe_params(shared, &obtained)) {
        fail("params comparison failed\n");
        exit(1);
    }

    pass();
    return 0;
}
Beispiel #12
0
int main(int argc, char **argv)
{
	int ret = 0;
	int readfd, writefd;
	mode_t mode = S_IFIFO | 0600;
	char path[PROCS_DEF][BUF_SIZE];
	pid_t pid;
	int i;
	uint8_t buf[0x100000];
	int chret;
	char *file_path;

	test_init(argc, argv);

	for (i = 0; i < PROCS_DEF; i++) {
		file_path = path[i];
		if (snprintf(file_path, BUF_SIZE, "%s-%02d", filename, i) >= BUF_SIZE) {
			pr_perror("filename %s is too long", filename);
			exit(1);
		}
		if (mkfifo(file_path, mode)) {
			pr_perror("can't make fifo \"%s\"", file_path);
			exit(1);
		}
	}

	pid = test_fork();
	if (pid < 0) {
		pr_perror("Can't fork");
		kill(0, SIGKILL);
		exit(1);
	}
	if (pid == 0) {
		file_path = path[0];
		readfd = open(file_path, O_RDONLY);
		if (readfd < 0) {
			pr_perror("open(%s, O_RDONLY) Failed", file_path);
			ret = errno;
			return ret;
		}
		file_path = path[1];
		writefd = open(file_path, O_WRONLY);
		if (writefd < 0) {
			pr_perror("open(%s, O_WRONLY) Failed", file_path);
			ret = errno;
			return ret;
		}

		if (pipe_in2out(readfd, writefd, buf, sizeof(buf)) < 0)
			/* pass errno as exit code to the parent */
			if (test_go() /* signal NOT delivered */ ||
					(errno != EINTR && errno != EPIPE))
				ret = errno;
		close(readfd);
		close(writefd);
		exit(ret);
	}
	file_path = path[0];
	writefd = open(file_path, O_WRONLY);
	if (writefd < 0) {
		pr_perror("open(%s, O_WRONLY) Failed", file_path);
		kill(pid, SIGKILL);
		return 1;
	}

	file_path = path[1];
	readfd = open(file_path, O_RDONLY);
	if (readfd < 0) {
		pr_perror("open(%s, O_RDONLY) Failed", file_path);
		kill(pid, SIGKILL);
		return 1;
	}
	test_daemon();

	while (test_go()) {
		int len, rlen = 0, wlen;
		uint8_t rbuf[sizeof(buf)], *p;

		datagen(buf, sizeof(buf), NULL);
		wlen = write(writefd, buf, sizeof(buf));
		if (wlen < 0) {
			if (errno == EINTR)
				continue;
			else {
				fail("write failed: %m\n");
				ret = 1;
				break;
			}
		}

		for (p = rbuf, len = wlen; len > 0; p += rlen, len -= rlen) {
			rlen = read(readfd, p, len);
			if (rlen <= 0)
				break;
		}

		if (rlen < 0 && errno == EINTR)
			continue;

		if (len > 0) {
			fail("read failed: %m\n");
			ret = 1;
			break;
		}

		if (memcmp(buf, rbuf, wlen)) {
			fail("data mismatch\n");
			ret = 1;
			break;
		}
	}

	close(writefd);
	test_waitsig();

	wait(&chret);
	chret = WEXITSTATUS(chret);
	if (chret) {
		fail("child exited with non-zero code %d (%s)\n",
			chret, strerror(chret));
		return 1;
	}
	if (!ret)
		pass();
	close(readfd);
	for (i = 0; i < PROCS_DEF; i++)
		unlink(path[i]);
	return 0;
}
Beispiel #13
0
static int test_fn(int argc, char **argv)
{
	key_t key;
	int sem, shm, pid1, pid2;
	int fail_count = 0;
	uint8_t *mem;
	uint32_t crc;
	int ret;

	key = ftok(argv[0], 822155650);
	if (key == -1) {
		pr_perror("Can't make key");
		goto out;
	}

	sem = semget(key, 1, 0777 | IPC_CREAT | IPC_EXCL);
	if (sem  == -1) {
		pr_perror("Can't get sem");
		goto out;
	}

	if (semctl(sem, 0, SETVAL, 1) == -1) {
		pr_perror("Can't init sem");
		fail_count++;
		goto out_sem;
	}

	shm = shmget(key, shmem_size, 0777 | IPC_CREAT | IPC_EXCL);
	if (shm == -1) {
		pr_perror("Can't get shm");
		fail_count++;
		goto out_sem;
	}

	mem = shmat(shm, NULL, 0);
	if (mem == (void *)-1) {
		pr_perror("Can't attach shm");
		fail_count++;
		goto out_shm;
	}

	poison_area((int *)mem);

	pid1 = test_fork();
	if (pid1 == -1) {
		pr_perror("Can't fork 1st time");
		goto out_shdt;
	} else if (pid1 == 0)
		exit(child(key));

	pid2 = test_fork();
	if (pid2 == -1) {
		pr_perror("Can't fork 2nd time");
		fail_count++;
		goto out_child;
	} else if (pid2 == 0)
		exit(child(key));

	test_daemon();
	while (test_go()) {
		ret = semop(sem, &lock, 1);
		if (ret) {
			if (errno == EINTR)
				continue;
			fail_count++;
			fail("Error in semop lock");
			break;
		}
		if (mem[0] != POISON) {
			crc = INIT_CRC;
			if (datachk(mem, shmem_size, &crc)) {
				fail_count++;
				fail("Semaphore protection is broken or "
						"shmem pages are messed");
				semop(sem, &unlock, 1);
				break;
			}
			poison_area((int *)mem);
		}
		while ((ret = semop(sem, &unlock, 1)) && (errno == EINTR));
		if (ret) {
			fail_count++;
			fail("Error in semop unlock");
			break;
		}
	}
	test_waitsig();

	kill(pid2, SIGTERM);
	waitpid(pid2, &ret, 0);
	if (!WIFEXITED(ret)) {
		fail_count++;
		pr_perror("Child 2 was killed");
	} else if (WEXITSTATUS(ret)) {
		fail_count++;
		pr_perror("Child 2 couldn't inititalise");
	}
out_child:
	kill(pid1, SIGTERM);
	waitpid(pid1, &ret, 0);
	if (!WIFEXITED(ret)) {
		fail_count++;
		pr_perror("Child 1 was killed");
	} else if (WEXITSTATUS(ret)) {
		fail_count++;
		pr_perror("Child 1 couldn't inititalise");
	}
out_shdt:
	shmdt(mem);
out_shm:
	shmctl(shm, IPC_RMID, NULL);
out_sem:
	semctl(sem, 1, IPC_RMID);
	if (fail_count == 0)
		pass();
out:
	return 0;
}
Beispiel #14
0
int main(int argc, char **argv)
{
	int pid, pipe_prep[2], pipe_goon[2], pipe_res[2];
	char res;
	int fd, fd2;

	test_init(argc, argv);

	filepath = malloc(strlen(filename) + 1);
	sprintf(filepath, "/%s", filename);

	pipe(pipe_prep);
	pipe(pipe_goon);
	pipe(pipe_res);
	pid = test_fork();
	if (pid != 0) {
		close(pipe_prep[1]);
		close(pipe_goon[0]);
		close(pipe_res[1]);

		res = ERR_PIPES;
		read(pipe_prep[0], &res, 1);
		read(pipe_prep[0], &res, 1); /* wait when pipe_prep[] will be closed */
		if (res != SUCCESS) {
			if (res == ERR_PIPES)
				pr_perror("broken pipes");
			else {
				if (res & ERR_IN_FILE)
					pr_perror("inside-root file fail");
				if (res & ERR_ROOT)
					pr_perror("chroot fail");
				if (res & ERR_DIR)
					pr_perror("mkdir fail");
			}
			return 0;
		}

		test_daemon();
		test_waitsig();
		close(pipe_goon[1]);

		res = ERR_PIPES;
		read(pipe_res[0], &res, 1);

		if (res == SUCCESS)
			pass();
		else if (res == ERR_PIPES)
			fail("broken pipes");
		else {
			if (res & ERR_IN_FILE)
				fail("opened file broken");
			if (res & ERR_OPEN)
				fail("open in chroot fail");
			if (res & ERR_FILE2)
				fail("wrong file opened");
		}

		wait(NULL);
		return 0;
	}

	close(pipe_prep[0]);
	close(pipe_goon[1]);
	close(pipe_res[0]);

	if (mkdir(dirname, 0700)) {
		res = ERR_DIR;
		goto err_nodir;
	}

	if (chroot(dirname)) {
		res = ERR_ROOT;
		goto err_noroot;
	}

	fd = make_file(filepath);
	if (fd < 0) {
		res = ERR_IN_FILE;
		goto err_nofile2;
	}

	res = SUCCESS;
	write(pipe_prep[1], &res, 1);
	close(pipe_prep[1]);
	read(pipe_goon[0], &res, 1);

	res = SUCCESS;

	if (check_file(fd))
		res |= ERR_IN_FILE;

	fd2 = open(filepath, O_RDWR);
	if (fd2 < 0)
		res |= ERR_OPEN;
	else if (check_file(fd2))
		res |= ERR_FILE2;

	write(pipe_res[1], &res, 1);
	exit(0);

err_nofile2:
err_noroot:
err_nodir:
	write(pipe_prep[1], &res, 1);
	exit(0);
}
Beispiel #15
0
int main(int argc, char ** argv)
{
    int sock, acc_sock, ret;
    pid_t pid;
    uint32_t crc;
    uint8_t buf[1000];

    test_init(argc, argv);

    sock = setup_srv_sock();
    if (sock < 0)
        exit(1);

    pid = test_fork();
    if (pid < 0) {
        pr_perror("can't fork");
        exit(1);
    }

    if (pid == 0) {	/* child writes to the unlinked socket and returns */
        close(sock);

        sock = setup_clnt_sock();
        if (sock < 0)
            _exit(1);

        test_waitsig();

        crc = ~0;
        datagen(buf, sizeof(buf), &crc);
        if (write(sock, buf, sizeof(buf)) != sizeof(buf)) {
            pr_perror("can't write to socket");
            exit(errno);
        }

        close(sock);
        exit(0);
    }

    acc_sock = accept(sock, NULL, NULL);
    if (acc_sock < 0) {
        pr_perror("can't accept() the connection on \"%s\"", filename);
        goto out_kill;
    }

    close(sock);
    sock = acc_sock;

    if (unlink(filename)) {
        pr_perror("can't unlink %s", filename);
        goto out_kill;
    }

    test_daemon();
    test_waitsig();

    if (kill(pid, SIGTERM)) {
        fail("terminating the child failed: %m\n");
        goto out;
    }

    if (wait(&ret) != pid) {
        fail("wait() returned wrong pid %d: %m\n", pid);
        goto out;
    }

    if (WIFEXITED(ret)) {
        ret = WEXITSTATUS(ret);
        if (ret) {
            fail("child exited with nonzero code %d (%s)\n", ret, strerror(ret));
            goto out;
        }
    }
    if (WIFSIGNALED(ret)) {
        fail("child exited on unexpected signal %d\n", WTERMSIG(ret));
        goto out;
    }

    if (read(sock, buf, sizeof(buf)) != sizeof(buf)) {
        fail("can't read %s: %m\n", filename);
        goto out;
    }

    crc = ~0;
    if (datachk(buf, sizeof(buf), &crc)) {
        fail("CRC mismatch\n");
        goto out;
    }


    if (close(sock)) {
        fail("close failed: %m\n");
        goto out;
    }

    if (unlink(filename) != -1 || errno != ENOENT) {
        fail("file %s should have been deleted before migration: unlink: %m\n", filename);
        goto out;
    }

    pass();

out_kill:
    kill(pid, SIGTERM);
out:
    close(sock);
    return 0;
}
Beispiel #16
0
int main(int argc, char ** argv)
{
	void *m, *m2;
	char path[PATH_MAX];
	uint32_t crc;
	pid_t pid = -1;
	int status, fd;

	test_init(argc, argv);

	m = mmap(NULL, MEM_SIZE, PROT_WRITE | PROT_READ,
				MAP_SHARED | MAP_ANONYMOUS, -1, 0);

	if (m == MAP_FAILED)
		goto err;

	pid = test_fork();
	if (pid < 0) {
		goto err;
	} else if (pid == 0) {
		crc = ~0;
		datagen(m + MEM_OFFSET, PAGE_SIZE, &crc);
		crc = ~0;
		datagen(m + MEM_OFFSET2, PAGE_SIZE, &crc);

		test_waitsig();

		crc = ~0;
		status = datachk(m + MEM_OFFSET, PAGE_SIZE, &crc);
		if (status)
			return 1;
		crc = ~0;
		status = datachk(m + MEM_OFFSET2, PAGE_SIZE, &crc);
		if (status)
			return 1;
		crc = ~0;
		status = datachk(m + PAGE_SIZE, PAGE_SIZE, &crc);
		if (status)
			return 1;
		return 0;
	}

	snprintf(path, PATH_MAX, "/proc/self/map_files/%lx-%lx",
						(unsigned long) m,
						(unsigned long) m + MEM_SIZE);
	fd = open(path, O_RDWR);
	if (fd == -1) {
		err("Can't open file %s: %m", path);
		goto err;
	}

	m2 = mmap(NULL, PAGE_SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, fd, MEM_OFFSET3);
	if (m2 == MAP_FAILED) {
		err("Can't map file %s", path);
		goto err;
	}
	close(fd);

	munmap(m, PAGE_SIZE);
	munmap(m + PAGE_SIZE * 10, PAGE_SIZE);
	munmap(m + MEM_OFFSET2, PAGE_SIZE);

	crc = ~0;
	datagen(m + PAGE_SIZE, PAGE_SIZE, &crc);

	crc = ~0;
	datagen(m2, PAGE_SIZE, &crc);

	test_daemon();
	test_waitsig();

	kill(pid, SIGTERM);
	wait(&status);
	if (WIFEXITED(status)) {
		if (WEXITSTATUS(status))
			goto err;
	} else
		goto err;

	crc = ~0;
	if (datachk(m + MEM_OFFSET, PAGE_SIZE, &crc))
		goto err;

	crc = ~0;
	if (datachk(m2, PAGE_SIZE, &crc))
		goto err;

	pass();

	return 0;
err:
	if (waitpid(-1, NULL, WNOHANG) == 0) {
		kill(pid, SIGTERM);
		wait(NULL);
	}
	return 1;
}
Beispiel #17
0
static int fork_child(int i)
{
	int p[2];
	int status, ret;
	pid_t pid, sid;

	ret = pipe(p);
	if (ret) {
		pr_perror("pipe() failed");
		return 1;
	}

	pid = test_fork();
	if (pid < 0) {
		pr_perror("Can't fork");
		return 1;
	}

	if (pid == 0) {
		if (testcases[i].flags & NEWSID) {
			sid = setsid();
			if (sid == -1) {
				pr_perror("setsid failed");
				write(p[1], &sid, sizeof(sid));
				exit(1);
			}
		}

		if (testcases[i].flags & (DETACH | CHANGESID)) {
			pid = test_fork();
			if (pid < 0) {
				write(p[1], &pid, sizeof(pid));
				exit(1);
			}
		}

		if (pid != 0) {
			if (!(testcases[i].flags & CHANGESID))
				exit(0);

			sid = setsid();
			if (sid == -1) {
				pr_perror("setsid failed");
				write(p[1], &sid, sizeof(sid));
				exit(1);
			}

			close(p[1]);
			wait(NULL);
			if (getsid(getpid()) != sid) {
				fail("The process %d (%x) has SID=%d (expected %d)",
					pid, testcases[i].flags, sid, testcases[i].sid);
				exit(1);
			}
			exit(0);
		}

		if (testcases[i].flags & DOUBLE_CHANGESID) {
			pid = fork();
			if (pid < 0) {
				write(p[1], &pid, sizeof(pid));
				exit(1);
			}

			if (pid == 0)
				goto child;

			sid = setsid();
			if (sid == -1) {
				pr_perror("setsid failed");
				write(p[1], &sid, sizeof(sid));
				exit(1);
			}

			close(p[1]);
			wait(NULL);
			if (getsid(getpid()) != sid) {
				fail("The process %d (%x) has SID=%d (expected %d)",
					pid, testcases[i].flags, sid, testcases[i].sid);
				exit(1);
			}
			exit(0);
		}

child:
		pid = getpid();
		write(p[1], &pid, sizeof(pid));
		close(p[1]);

		test_waitsig();
		pass();
		exit(0);
	}

	close(p[1]);

	if (testcases[i].flags & DETACH) {
		pid_t ret;
		ret = wait(&status);
		if (ret != pid) {
			pr_perror("wait return %d instead of %d", ret, pid);
			kill(pid, SIGKILL);
			return 1;
		}
	}

	ret = read(p[0], &testcases[i].pid, sizeof(pid));
	if (ret != sizeof(ret)) {
		pr_perror("read failed");
		return 1;
	}
	/* wait when a child closes fd */
	ret = read(p[0], &testcases[i].pid, sizeof(pid));
	if (ret != 0) {
		pr_perror("read failed");
		return 1;
	}

	close(p[0]);

	if (testcases[i].pid < 0) {
		pr_perror("child failed");
		return 1;
	}

	testcases[i].sid = getsid(testcases[i].pid);

	return 0;
}
Beispiel #18
0
int main(int argc, char **argv)
{
	unsigned char buf[BUF_SIZE];
	int fd, fd_s;
	int status;
	pid_t pid;
	int res;
	uint32_t crc;
	struct sigaction sa = {
		.sa_handler	= sig_hand,
		/* don't set SA_RESTART */
	};

	test_init(argc, argv);

	if ((fd_s = tcp_init_server(ZDTM_FAMILY, &port)) < 0) {
		err("initializing server failed");
		return 1;
	}

	test_daemon();
	test_waitsig();

	sigemptyset(&sa.sa_mask);
	if (sigaction(SIGCHLD, &sa, NULL))
		fprintf(stderr, "Can't set SIGTERM handler: %m\n");

	pid = test_fork();
	if (pid < 0) {
		err("fork failed. Return %d %m", pid);
		return 1;
	}

	if (pid == 0) {
		/*
		 * Chiled is client of TCP connection
		 */
		close(fd_s);
		fd = tcp_init_client(ZDTM_FAMILY, "localhost", port);
		if (fd < 0)
			return 1;

		res = read(fd, buf, BUF_SIZE);
		close(fd);
		if (res != BUF_SIZE) {
			err("read less then have to: %d instead of %d", res, BUF_SIZE);
			return -1;
		}
		if (datachk(buf, BUF_SIZE, &crc))
			return -2;
		return 0;
	}

	/*
	 * parent is server of TCP connection
	 */
	fd = tcp_accept_server(fd_s);
	close(fd_s);
	if (fd < 0) {
		err("can't accept client connection %m");
		goto error;
	}

	datagen(buf, BUF_SIZE, &crc);
	if (write(fd, buf, BUF_SIZE) < BUF_SIZE) {
		err("can't write");
		goto error;
	}
	close(fd);


	if (wait(&status) < 0) {
		err("wait failed %m");
		goto error;
	}

	if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
		err("chiled failed. Return %d", WEXITSTATUS(status));
		return 1;
	}

	pass();
	return 0;
error:
	kill(pid, SIGKILL);
	wait(&status);
	return -1;
}
Beispiel #19
0
int main(int argc, char **argv)
{
	int ret = 0;
	pid_t pid;
	int i;
	uint8_t buf[PIPE_BUF * 100];
	int pipes[2];

	test_init(argc, argv);

	if (num_procs > PROCS_MAX) {
		pr_err("%d processes is too many: max = %d\n", num_procs, PROCS_MAX);
		exit(1);
	}

	if (pipe(pipes)) {
		pr_perror("Can't create pipes");
		exit(1);
	}

	if (signal(SIGCHLD, inc_num_exited) == SIG_ERR) {
		pr_perror("can't set SIGCHLD handler");
		exit(1);
	}

	for (i = 1; i < num_procs; i++) {	/* i = 0 - parent */
		pid = test_fork();
		if (pid < 0) {
			pr_perror("can't fork");
			kill(0, SIGKILL);
			exit(1);
		}

		if (pid == 0) {
			close(pipes[1]);

			while (test_go()) {
				int rlen = read(pipes[0], buf, sizeof(buf));
				if (rlen == 0)
					break;
				else if (rlen < 0) {
					ret = errno;	/* pass errno as exit code to the parent */
					break;
				}

				for (i = 0; i < rlen && buf[i] == SND_CHR; i++)
					;
				if (i < rlen) {
					ret = EILSEQ;
					break;
				}
			}

			test_waitsig();	/* even if failed, wait for migration to complete */

			close(pipes[0]);
			exit(ret);
		}
	}

	close(pipes[0]);

	if (num_exited) {
		pr_err("Some children died unexpectedly\n");
		kill(0, SIGKILL);
		exit(1);
	}

	test_daemon();

	memset(buf, SND_CHR, sizeof(buf));
	while(test_go())
		if (write(pipes[1], buf, sizeof(buf)) < 0 &&
		    (errno != EINTR || test_go())) {	/* only SIGTERM may stop us */
			fail("write failed: %m\n");
			ret = 1;
			break;
		}
	close(pipes[1]);

	test_waitsig();	/* even if failed, wait for migration to complete */

	if (kill(0, SIGTERM)) {
		fail("failed to send SIGTERM to my process group: %m\n");
		goto out;	/* shouldn't wait() in this case */
	}

	for (i = 1; i < num_procs; i++) {	/* i = 0 - parent */
		int chret;
		if (wait(&chret) < 0) {
			fail("can't wait for a child: %m\n");
			ret = 1;
			continue;
		}

		chret = WEXITSTATUS(chret);
		if (chret) {
			fail("child exited with non-zero code %d (%s)\n",
			     chret, strerror(chret));
			ret = 1;
			continue;
		}
	}

	if (!ret)
		pass();

out:
	return 0;
}
Beispiel #20
0
int main(int argc, char **argv)
{
	key_t key;
	int msg, pid;
	struct msg1 msgbuf;
	int chret;

	test_init(argc, argv);

	key = ftok(argv[0], 822155650);
	if (key == -1) {
		pr_perror("Can't make key");
		exit(1);
	}

	pid = test_fork();
	if (pid < 0) {
		pr_perror("Can't fork");
		exit(1);
	}

	msg = msgget(key, IPC_CREAT | IPC_EXCL | 0666);
	if (msg == -1) {
		msg = msgget(key, 0666);
		if (msg == -1) {
			pr_perror("Can't get queue");
			goto err_kill;
		}
	}

	if (pid == 0) {
		test_waitsig();

		if (msgrcv(msg, &msgbuf, sizeof(TEST_STRING), MSG_TYPE, IPC_NOWAIT) == -1) {
			fail("Child: msgrcv failed (%m)");
			return -errno;
		}

		if (strncmp(TEST_STRING, msgbuf.mtext, sizeof(TEST_STRING))) {
			fail("Child: the source and received strings aren't equal");
			return -errno;
		}
		test_msg("Child: received %s\n", msgbuf.mtext);

		msgbuf.mtype = ANOTHER_MSG_TYPE;
		memcpy(msgbuf.mtext, ANOTHER_TEST_STRING, sizeof(ANOTHER_TEST_STRING));
		if (msgsnd(msg, &msgbuf, sizeof(ANOTHER_TEST_STRING), IPC_NOWAIT) != 0) {
			fail("Child: msgsnd failed (%m)");
			return -errno;
		};
		pass();
		return 0;
	} else {
		msgbuf.mtype = MSG_TYPE;
		memcpy(msgbuf.mtext, TEST_STRING, sizeof(TEST_STRING));
		if (msgsnd(msg, &msgbuf, sizeof(TEST_STRING), IPC_NOWAIT) != 0) {
			fail("Parent: msgsnd failed (%m)");
			goto err_kill;
		};

		msgbuf.mtype = ANOTHER_MSG_TYPE;
		memcpy(msgbuf.mtext, ANOTHER_TEST_STRING, sizeof(ANOTHER_TEST_STRING));
		if (msgsnd(msg, &msgbuf, sizeof(ANOTHER_TEST_STRING), IPC_NOWAIT) != 0) {
			fail("child: msgsnd (2) failed (%m)");
			return -errno;
		};

		test_daemon();
		test_waitsig();

		kill(pid, SIGTERM);

		wait(&chret);
		chret = WEXITSTATUS(chret);
		if (chret) {
			fail("Parent: child exited with non-zero code %d (%s)\n",
			     chret, strerror(chret));
			goto out;
		}

		if (msgrcv(msg, &msgbuf, sizeof(ANOTHER_TEST_STRING), ANOTHER_MSG_TYPE, IPC_NOWAIT) == -1) {
			fail("Parent: msgrcv failed (%m)");
			goto err;
		}

		if (strncmp(ANOTHER_TEST_STRING, msgbuf.mtext, sizeof(ANOTHER_TEST_STRING))) {
			fail("Parent: the source and received strings aren't equal");
			goto err;
		}
		test_msg("Parent: received %s\n", msgbuf.mtext);

		pass();
	}

out:
	if (msgctl(msg, IPC_RMID, 0)) {
		fail("Failed to destroy message queue: %d\n", -errno);
		return -errno;
	}
	return chret;

err_kill:
	kill(pid, SIGKILL);
	wait(NULL);
err:
	chret = -errno;
	goto out;
}
Beispiel #21
0
int main(int argc, char **argv)
{
	pid_t pid;
	int p[2], ret, status;

	test_init(argc, argv);

	if (pipe(p)) {
		err("Unable to create pipe");
		return 1;
	}

	pid = test_fork();
	if (pid < 0)
		return -1;
	else if (pid == 0) {
		char c;

		close(p[1]);
		ret = read(p[0], &c, 1);
		if (ret != 1) {
			err("Unable to read: %d", ret);
			return 1;
		}

		return 0;
	}
	close(p[0]);

	kill(pid, SIGSTOP);

	write(p[1], "0", 1);
	close(p[1]);

	test_daemon();
	test_waitsig();

	// Return immediately if child run or stopped(by SIGSTOP)
	if (waitpid(pid, &status, WUNTRACED | WCONTINUED) == -1) {
		err("Unable to wait child");
		goto out;
	}

	if (WIFSTOPPED(status))
		test_msg("The procces stopped\n");
	else{
		fail("The process doesn't stopped");
		goto out;
	}

	kill(pid, SIGCONT);

	if (waitpid(pid, &status, 0) == -1) {
		err("Unable to wait child");
		goto out;
	}

	if (WIFEXITED(status))
		pass();
	else
		fail("The process doesn't continue");
out:
	return 0;
}
Beispiel #22
0
int main(int argc, char **argv)
{
	int ret = 0;
	pid_t pid;
	int i;
	uint8_t buf[0x100000];
	int pipes[PROCS_MAX * 2];
	int in, out;

	test_init(argc, argv);

	if (num_procs > PROCS_MAX) {
		err("%d processes is too many: max = %d\n", num_procs, PROCS_MAX);
		exit(1);
	}

	for (i = 0; i < num_procs; i++)
		if (pipe(pipes + i * 2)) {
			err("Can't create pipes: %m\n");
			exit(1);
		}

	if (signal(SIGCHLD, inc_num_exited) == SIG_ERR) {
		err("can't set SIGCHLD handler: %m\n");
		exit(1);
	}

	for (i = 1; i < num_procs; i++) {	/* i = 0 - parent */
		pid = test_fork();
		if (pid < 0) {
			err("Can't fork: %m\n");
			kill(0, SIGKILL);
			exit(1);
		}

		if (pid == 0) {
			int j;
			in = i * 2;
			out = in - 1;
			for (j = 0; j < num_procs * 2; j++)
				if (j != in && j != out)
					close(pipes[j]);

			signal(SIGPIPE, SIG_IGN);
			if (pipe_in2out(pipes[in], pipes[out], buf, sizeof(buf)) < 0)
				/* pass errno as exit code to the parent */
				if (test_go() /* signal NOT delivered */ ||
						(errno != EINTR && errno != EPIPE))
					ret = errno;

			test_waitsig();	/* even if failed, wait for migration to complete */

			close(pipes[in]);
			close(pipes[out]);
			exit(ret);
		}
	}

	for (i = 1; i < num_procs * 2 - 1; i++)
		close(pipes[i]);
	in = pipes[0];
	out = pipes[num_procs * 2 - 1];

	/* don't block on writing, _do_ block on reading */
	if (set_nonblock(out,1) < 0) {
		err("setting O_NONBLOCK failed: %m");
		exit(1);
	}

	if (num_exited) {
		err("Some children died unexpectedly\n");
		kill(0, SIGKILL);
		exit(1);
	}

	test_daemon();

	while (test_go()) {
		int len, rlen = 0, wlen;
		uint8_t rbuf[sizeof(buf)], *p;

		datagen(buf, sizeof(buf), NULL);
		wlen = write(out, buf, sizeof(buf));
		if (wlen < 0) {
			if (errno == EINTR)
				continue;
			else {
				fail("write failed: %m\n", i);
				ret = 1;
				break;
			}
		}

		for (p = rbuf, len = wlen; len > 0; p += rlen, len -= rlen) {
			rlen = read(in, p, len);
			if (rlen <= 0)
				break;
		}

		if (rlen < 0 && errno == EINTR)
			continue;

		if (len > 0) {
			fail("read failed: %m\n");
			ret = 1;
			break;
		}

		if (memcmp(buf, rbuf, wlen)) {
			fail("data mismatch\n");
			ret = 1;
			break;
		}
	}

	close(out);

	test_waitsig();	/* even if failed, wait for migration to complete */

	if (kill(0, SIGTERM)) {
		fail("failed to send SIGTERM to my process group: %m\n");
		goto out;	/* shouldn't wait() in this case */
	}

	for (i = 1; i < num_procs; i++) {	/* i = 0 - parent */
		int chret;
		if (wait(&chret) < 0) {
			fail("can't wait for a child: %m\n");
			ret = 1;
			continue;
		}

		chret = WEXITSTATUS(chret);
		if (chret) {
			fail("child %d exited with non-zero code %d (%s)\n",
			     i, chret, strerror(chret));
			ret = 1;
			continue;
		}
	}

	if (!ret)
		pass();

out:
	close(in);
	return 0;
}
Beispiel #23
0
int main(int argc, char *argv[])
{
	char buf[sizeof(teststr)];
	int master, slave, ret;
	char *slavename;
	task_waiter_t t;
	pid_t pid;

	test_init(argc, argv);

	master = open("/dev/ptmx", O_RDWR);
	if (master == -1) {
		err("open(%s) failed", "/dev/ptmx");
		return 1;
	}

	grantpt(master);
	unlockpt(master);

	slavename = ptsname(master);
	slave = open(slavename, O_RDWR);
	if (slave == -1) {
		err("open(%s) failed", slavename);
		return 1;
	}

	task_waiter_init(&t);

	pid = test_fork();
	if (pid == 0) {
		int new_master, ret;

		new_master = dup(master);
		if (new_master < 0) {
			err("can't dup master\n");
			exit_shot_parent(1);
		}

		task_waiter_complete_current(&t);

		ret = write(new_master, teststr, sizeof(teststr) - 1);
		if (ret != sizeof(teststr) - 1) {
			err("write(new_master) failed");
			exit_shot_parent(1);
		}

		task_waiter_wait4(&t, 1);

		close(new_master);
		exit(0);
	} else if (pid < 0) {
		err("test_fork failed: %m\n");
		exit(1);
	}

	task_waiter_wait4(&t, pid);
	close(master);

	test_daemon();
	test_waitsig();

	signal(SIGHUP, SIG_IGN);
	task_waiter_complete(&t, 1);

	ret = read(slave, buf, sizeof(teststr) - 1);
	if (ret != sizeof(teststr) - 1) {
		err("read(slave) failed");
		return 1;
	}

	if (strncmp(teststr, buf, sizeof(teststr) - 1)) {
		fail("data mismatch");
		return 1;
	}

	close(slave);

	pass();

	return 0;
}
Beispiel #24
0
int main(int argc, char **argv)
{
	int ret = 0;
	pid_t pid;
	int i;
	uint8_t buf[0x100000];
	int socks[PROCS_MAX * 2];
	int in, out;

	test_init(argc, argv);

	if (num_procs > PROCS_MAX) {
		err("%d processes is too many: max = %d\n", num_procs, PROCS_MAX);
		exit(1);
	}

	for (i = 0; i < num_procs; i++)
		if (socketpair(AF_LOCAL, SOCK_STREAM, 0, socks + i * 2)) {
			err("Can't create socks: %m\n");
			exit(1);
		}

	if (signal(SIGCHLD, inc_num_exited) == SIG_ERR) {
		err("can't set SIGCHLD handler: %m\n");
		exit(1);
	}

	for (i = 1; i < num_procs; i++) {	/* i = 0 - parent */
		pid = test_fork();
		if (pid < 0) {
			err("Can't fork: %m\n");
			kill(0, SIGKILL);
			exit(1);
		}

		if (pid == 0) {
			int j;
			in = i * 2;
			out = in - 1;
			for (j = 0; j < num_procs * 2; j++)
				if (j != in && j != out)
					close(socks[j]);

			signal(SIGPIPE, SIG_IGN);
			if (pipe_in2out(socks[in], socks[out], buf, sizeof(buf)) < 0)
				/* pass errno as exit code to the parent */
				if (test_go() /* signal NOT delivered */ ||
					(errno != EINTR && errno != EPIPE
						&& errno != ECONNRESET))
					ret = errno;

			test_waitsig();	/* even if failed, wait for migration to complete */

			close(socks[in]);
			close(socks[out]);
			exit(ret);
		}
	}

	for (i = 1; i < num_procs * 2 - 1; i++)
		close(socks[i]);
	in = socks[0];
	out = socks[num_procs * 2 - 1];

	/* don't block on writing, _do_ block on reading */
	if (set_nonblock(out,1) < 0) {
		err("setting O_NONBLOCK failed: %m");
		exit(1);
	}

	if (num_exited) {
		err("Some children died unexpectedly\n");
		kill(0, SIGKILL);
		exit(1);
	}

	test_daemon();

	while (test_go()) {
		int len, rlen = 0, wlen;
		uint8_t rbuf[sizeof(buf)], *p;

		datagen(buf, sizeof(buf), NULL);
		wlen = write(out, buf, sizeof(buf));
		if (wlen < 0) {
			if (errno == EINTR)
				continue;
			else {
				fail("write failed: %m\n", i);
				ret = 1;
				break;
			}
		}

		for (p = rbuf, len = wlen; len > 0; p += rlen, len -= rlen) {
			rlen = read(in, p, len);
			if (rlen <= 0)
				break;
		}

		if (rlen < 0 && errno == EINTR)
			continue;

		if (len > 0) {
			fail("read failed: %m\n");
			ret = 1;
			break;
		}

		if (memcmp(buf, rbuf, wlen)) {
			fail("data mismatch\n");
			ret = 1;
			break;
		}
	}


	test_waitsig();	/* even if failed, wait for migration to complete */

	/* We expect that write(2) in child may return error only after signal
	 * has been received. Thus, send signal before closing parent fds.
	 */
	if (kill(0, SIGTERM)) {
		fail("failed to send SIGTERM to my process group: %m\n");
		goto out;	/* shouldn't wait() in this case */
	}
	if (close(out))
		fail("Failed to close parent fd 'out': %m\n");
	/* If last child in the chain (from whom we read data) receives signal
	 * after parent has finished reading but before calling write(2), this
	 * child can block forever.  To avoid this, close 'in' fd.
	 */
	if (close(in))
		fail("failed to close parent fd 'in': %m\n");

	for (i = 1; i < num_procs; i++) {	/* i = 0 - parent */
		int chret;
		if (wait(&chret) < 0) {
			fail("can't wait for a child: %m\n");
			ret = 1;
			continue;
		}

		chret = WEXITSTATUS(chret);
		if (chret) {
			fail("child %d exited with non-zero code %d (%s)\n",
			     i, chret, strerror(chret));
			ret = 1;
			continue;
		}
	}

	if (!ret)
		pass();

out:
	return 0;
}