static void child_alloc(int *bufsz_arr) { char **foo; int i, j; char buf[BUFSIZ]; long count; foo = SAFE_MALLOC(tst_exit, nr_iovecs * sizeof(char *)); count = 0; for (i = 0; i < nr_iovecs; i++) { foo[i] = SAFE_MALLOC(tst_exit, bufsz_arr[i]); for (j = 0; j < bufsz_arr[i]; j++) { foo[i][j] = count % 256; count++; } } tst_resm(TINFO, "child 0: %d iovecs allocated and initialized.", nr_iovecs); /* passing addr via pipe */ SAFE_CLOSE(tst_exit, pipe_fd[0]); snprintf(buf, BUFSIZ, "%p", (void *)foo); SAFE_WRITE(tst_exit, 1, pipe_fd[1], buf, strlen(buf)); SAFE_CLOSE(tst_exit, pipe_fd[1]); /* wait until child_invoke is done reading from our VM */ safe_semop(semid, 0, -1); }
int main(int argc, char **argv) { int lc, status; int *bufsz_arr; tst_parse_opts(argc, argv, options, &help); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; if (pipe(pipe_fd) < 0) tst_brkm(TBROK | TERRNO, cleanup, "pipe"); bufsz_arr = SAFE_MALLOC(cleanup, nr_iovecs * sizeof(int)); gen_random_arr(bufsz_arr, nr_iovecs); /* the start of child_alloc and child_invoke is already * synchronized via pipe */ pids[0] = fork(); switch (pids[0]) { case -1: tst_brkm(TBROK | TERRNO, cleanup, "fork #0"); case 0: child_alloc(bufsz_arr); exit(0); } pids[1] = fork(); switch (pids[1]) { case -1: tst_brkm(TBROK | TERRNO, cleanup, "fork #1"); case 0: child_invoke(bufsz_arr); exit(0); } /* wait until child_invoke reads from child_alloc's VM */ if (waitpid(pids[1], &status, 0) == -1) tst_brkm(TBROK | TERRNO, cleanup, "waitpid"); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) tst_resm(TFAIL, "child 1 returns %d", status); /* child_alloc is free to exit now */ safe_semop(semid, 0, 1); if (waitpid(pids[0], &status, 0) == -1) tst_brkm(TBROK | TERRNO, cleanup, "waitpid"); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) tst_resm(TFAIL, "child 0 returns %d", status); free(bufsz_arr); } cleanup(); tst_exit(); }
int main(int argc, char **argv) { int lc, status; char *msg; msg = parse_opts(argc, argv, NULL, NULL); if (msg != NULL) tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; len = strlen(tst_string); if (pipe(pipe_fd) < 0) tst_brkm(TBROK | TERRNO, cleanup, "pipe"); /* the start of child_alloc and child_invoke is already * synchronized via pipe */ pids[0] = fork(); switch (pids[0]) { case -1: tst_brkm(TBROK | TERRNO, cleanup, "fork #0"); case 0: child_alloc(); exit(0); } pids[1] = fork(); switch (pids[1]) { case -1: tst_brkm(TBROK | TERRNO, cleanup, "fork #1"); case 0: child_invoke(); exit(0); } /* wait until child_invoke reads from child_alloc's VM */ if (waitpid(pids[1], &status, 0) == -1) tst_brkm(TBROK | TERRNO, cleanup, "waitpid"); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) tst_resm(TFAIL, "child 1 returns %d", status); /* child_alloc is free to exit now */ safe_semop(semid, 0, 1); if (waitpid(pids[0], &status, 0) == -1) tst_brkm(TBROK | TERRNO, cleanup, "waitpid"); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) tst_resm(TFAIL, "child 0 returns %d", status); } cleanup(); tst_exit(); }
static void child_alloc(void) { char *foo; char buf[BUFSIZ]; foo = SAFE_MALLOC(tst_exit, len + 1); strncpy(foo, tst_string, len); foo[len] = '\0'; tst_resm(TINFO, "child 0: memory allocated and initialized."); /* passing addr of string "foo" via pipe */ SAFE_CLOSE(tst_exit, pipe_fd[0]); snprintf(buf, BUFSIZ, "%p", foo); SAFE_WRITE(tst_exit, 1, pipe_fd[1], buf, strlen(buf)); SAFE_CLOSE(tst_exit, pipe_fd[1]); /* wait until child_invoke is done reading from our VM */ safe_semop(semid, 0, -1); }