void do_child_1() { int fildes; #ifdef UCLINUX if (sync_pipe_create(start_sync_pipes, PIPE_NAME_START) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_create failed"); if (sync_pipe_create(end_sync_pipes, PIPE_NAME_END) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_create failed"); #endif if ((fildes = open(test_app, O_WRONLY)) == -1) { printf("%s\n", test_app); perror("open failed"); exit(1); } if (sync_pipe_notify(start_sync_pipes) == -1) { perror("sync_pipe_notify failed"); exit(1); } if (sync_pipe_close(start_sync_pipes, PIPE_NAME_START) == -1) { perror("sync_pipe_close failed"); exit(1); } if (sync_pipe_wait(end_sync_pipes) == -1) { perror("sync_pipe_wait failed"); exit(1); } exit(0); }
/* * do_child() */ void do_child(int i) { #ifdef UCLINUX if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_create failed"); #endif if (sync_pipe_notify(sync_pipes) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_notify failed: %d", errno); if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_close failed: %d", errno); /* * make the call with the TEST macro */ TEST(semop(sem_id_1, &s_buf, 1)); if (TEST_RETURN != -1) { tst_resm(TFAIL, "call succeeded when error expected"); exit(-1); } TEST_ERROR_LOG(TEST_ERRNO); if (TEST_ERRNO == TC[i].error) { tst_resm(TPASS, "expected failure - errno = %d" " : %s", TEST_ERRNO, strerror(TEST_ERRNO)); } else { tst_resm(TFAIL, "unexpected error - " "%d : %s", TEST_ERRNO, strerror(TEST_ERRNO)); } exit(0); }
/* * do_child_uclinux() - capture signals again, then run do_child() */ void do_child_uclinux() { if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_create failed"); tst_sig(FORK, SIG_IGN, cleanup); do_child(); }
/* * stat_setup() - Set up for the IPC_STAT command with shmctl(). * Make things interesting by forking some children * that will either attach or inherit the shared memory. */ void stat_setup() { void *set_shmat(); pid_t pid; /* * The first time through, let the children attach the memory. * The second time through, attach the memory first and let * the children inherit the memory. */ if (stat_time == SECOND) { /* * use the global "set_shared" variable here so that * it can be removed in the stat_func() routine. */ set_shared = set_shmat(); } tst_flush(); for (stat_i = 0; stat_i < N_ATTACH; stat_i++) { if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_create failed"); if ((pid = FORK_OR_VFORK()) == -1) { tst_brkm(TBROK, cleanup, "could not fork"); } if (pid == 0) { /* child */ #ifdef UCLINUX if (self_exec(argv0, "ddd", stat_i, stat_time, shm_id_1) < 0) { tst_brkm(TBROK, cleanup, "could not self_exec"); } #else do_child(); #endif } else { /* parent */ /* save the child's pid for cleanup later */ pid_arr[stat_i] = pid; if (sync_pipe_wait(sync_pipes) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_wait failed"); if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_close failed"); } } /* Wait 1 second to be sure all sons are in the pause function. */ sleep(1); }
/* * do_child() */ void do_child() { int retval = 0; #ifdef UCLINUX /* initialize the message buffer */ init_buf(&msg_buf, MSGTYPE, MSGSIZE); if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_create failed"); #endif if (sync_pipe_notify(sync_pipes) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_notify failed"); if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_close failed"); /* * Attempt to write another message to the full queue. * Without the IPC_NOWAIT flag, the child sleeps */ TEST(msgsnd(msg_q_1, &msg_buf, MSGSIZE, 0)); if (TEST_RETURN != -1) { retval = 1; tst_resm(TFAIL, "call succeeded when error expected"); exit(retval); } TEST_ERROR_LOG(TEST_ERRNO); switch (TEST_ERRNO) { case EIDRM: tst_resm(TPASS, "expected failure - errno = %d : %s", TEST_ERRNO, strerror(TEST_ERRNO)); /* mark the queue as invalid as it was removed */ msg_q_1 = -1; break; default: retval = 1; tst_resm(TFAIL, "call failed with an unexpected error - %d : %s", TEST_ERRNO, strerror(TEST_ERRNO)); break; } exit(retval); }
void dochild(void) { int fd; struct flock flocks; #ifdef UCLINUX #define PIPE_NAME "ftruncate04" if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_create failed"); #endif if ((fd = open(filename, O_RDWR)) < 0) { tst_resm(TFAIL, "child open"); tst_exit(); } lseek(fd, 0, SEEK_SET); flocks.l_type = F_WRLCK; flocks.l_whence = SEEK_CUR; flocks.l_start = recstart; flocks.l_len = reclen; if (fcntl(fd, F_SETLKW, &flocks) < 0) { tst_resm(TFAIL, "child fcntl failed"); tst_exit(); } if (kill(ppid, SIGUSR1) < 0) { tst_resm(TFAIL, "child kill"); tst_exit(); } if (sync_pipe_notify(sync_pipes) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_notify failed"); if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_close failed"); pause(); tst_exit(); }
/* * do_child */ void do_child() { int rval; void *test; #ifdef UCLINUX if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_create failed"); #endif if (stat_time == FIRST) { test = set_shmat(); } else { test = set_shared; } if (sync_pipe_notify(sync_pipes) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_notify failed"); #ifdef UCLINUX if (sync_pipe_close(sync_pipes, NULL) == -1) #else if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1) #endif tst_brkm(TBROK, cleanup, "sync_pipe_close failed"); /* do an assignement for fun */ memcpy(test, &stat_i, sizeof(stat_i)); /* pause until we get a signal from stat_cleanup() */ rval = pause(); /* now we're back - detach the memory and exit */ if (shmdt(test) == -1) { tst_resm(TBROK, "shmdt() failed - %d", errno); } tst_exit(); }
int main(int ac, char **av) { int lc; /* loop counter */ char *msg; /* message returned from parse_opts */ int i; pid_t pid; void do_child(); /* parse standard options */ if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); #ifdef UCLINUX maybe_run_child(&do_child_uclinux, "dd", &i_uclinux, &sem_id_1); #endif setup(); /* global setup */ /* The following loop checks looping state if -i option given */ for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping */ Tst_count = 0; for (i = 0; i < TST_TOTAL; i++) { if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_create failed"); /* initialize the s_buf buffer */ s_buf.sem_op = TC[i].op; s_buf.sem_flg = TC[i].flg; s_buf.sem_num = TC[i].num; /* initialize all of the primitive semaphores */ if (semctl(sem_id_1, TC[i].num, SETVAL, TC[i].semunptr) == -1) { tst_brkm(TBROK, cleanup, "semctl() failed"); } if ((pid = FORK_OR_VFORK()) == -1) { tst_brkm(TBROK, cleanup, "could not fork"); } if (pid == 0) { /* child */ #ifdef UCLINUX if (self_exec(av[0], "dd", i, sem_id_1) < 0) { tst_brkm(TBROK, cleanup, "could not self_exec"); } #else do_child(i); #endif } else { /* parent */ if (sync_pipe_wait(sync_pipes) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_wait failed: %d", errno); if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_close failed: %d", errno); /* After son has been created, give it a chance to execute the * semop command before we continue. Without this sleep, on SMP machine * the father rm_sema/kill could be executed before the son semop. */ sleep(1); /* * If we are testing for EIDRM then remove * the semaphore, else send a signal that * must be caught as we are testing for * EINTR. */ if (TC[i].error == EIDRM) { /* remove the semaphore resource */ rm_sema(sem_id_1); } else { if (kill(pid, SIGHUP) == -1) { tst_brkm(TBROK, cleanup, "kill failed"); } } /* let the child carry on */ waitpid(pid, NULL, 0); } /* * recreate the semaphore resource if needed */ if (TC[i].error == EINTR) { continue; } if ((sem_id_1 = semget(semkey, PSEMS, IPC_CREAT | IPC_EXCL | SEM_RA)) == -1) { tst_brkm(TBROK, cleanup, "couldn't recreate " "semaphore"); } } } cleanup(); tst_exit(); }
int main(int ac, char **av) { int lc; char *msg; if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } #ifdef UCLINUX maybe_run_child(&do_child_uclinux, "d", &msg_q_1); #endif setup(); /* global setup */ if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_create failed"); /* The following loop checks looping state if -i option given */ for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset tst_count in case we are looping */ tst_count = 0; /* * set up the queue here so that multiple test iterations * will work. */ msgkey = getipckey(); /* create a message queue with read/write permission */ if ((msg_q_1 = msgget(msgkey, IPC_CREAT | IPC_EXCL | MSG_RW)) == -1) { tst_brkm(TBROK, cleanup, "Can't create message queue"); } /* * fork a child that will attempt to read a non-existent * message from the queue */ if ((c_pid = FORK_OR_VFORK()) == -1) { tst_brkm(TBROK, cleanup, "could not fork"); } if (c_pid == 0) { /* child */ /* * Attempt to read a message without IPC_NOWAIT. * With no message to read, the child sleeps. */ #ifdef UCLINUX if (self_exec(av[0], "d", msg_q_1) < 0) { tst_brkm(TBROK, cleanup, "could not self_exec"); } #else do_child(); #endif } else { /* parent */ if (sync_pipe_wait(sync_pipes) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_wait failed"); if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_close failed"); sleep(1); /* remove the queue */ rm_queue(msg_q_1); waitpid(c_pid, NULL, 0); } } tst_exit(); }
int main(int ac, char **av) { int lc; char *msg; pid_t c_pid; int status, e_code; if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } #ifdef UCLINUX #define PIPE_NAME "msgsnd06" maybe_run_child(&do_child, "d", &msg_q_1); #endif setup(); /* global setup */ if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_create failed"); /* The following loop checks looping state if -i option given */ for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping */ Tst_count = 0; msgkey = getipckey(); /* create a message queue with read/write permission */ if ((msg_q_1 = msgget(msgkey, IPC_CREAT | IPC_EXCL | MSG_RW)) == -1) { tst_brkm(TBROK, cleanup, "Can't create message queue"); } /* initialize the message buffer */ init_buf(&msg_buf, MSGTYPE, MSGSIZE); /* write messages to the queue until it is full */ while (msgsnd(msg_q_1, &msg_buf, MSGSIZE, IPC_NOWAIT) != -1) { msg_buf.mtype += 1; } /* * fork a child that will attempt to write a message * to the queue without IPC_NOWAIT */ if ((c_pid = FORK_OR_VFORK()) == -1) { tst_brkm(TBROK, cleanup, "could not fork"); } if (c_pid == 0) { /* child */ #ifdef UCLINUX if (self_exec(av[0], "d", msg_q_1) < 0) { tst_brkm(TBROK, cleanup, "could not self_exec"); } #else do_child(); #endif } else { /* parent */ if (sync_pipe_wait(sync_pipes) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_wait failed"); if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_close failed"); /* After son has been created, give it a chance to execute the * msgsnd command before we continue. Without this sleep, on SMP machine * the father rm_queue could be executed before the son msgsnd. */ sleep(2); /* remove the queue */ rm_queue(msg_q_1); /* wait for the child to finish */ wait(&status); /* make sure the child returned a good exit status */ e_code = status >> 8; if (e_code != 0) { tst_resm(TFAIL, "Failures reported above"); } } } cleanup(); tst_exit(); }
int main(int ac, char **av) { int lc; char *msg; pid_t pid, pid1; int retval = 3, status; char *argv[1], *env[1]; if ((msg = parse_opts(ac, av, options, &help)) != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); #ifdef UCLINUX maybe_run_child(&do_child_1, "nS", 1, &test_app); #endif if (!Fflag) tst_brkm(TBROK, NULL, "You must specify an executable file with the -F option."); setup(*av); TEST_EXP_ENOS(exp_enos); for (lc = 0; TEST_LOOPING(lc); lc++) { Tst_count = 0; if (sync_pipe_create(start_sync_pipes, PIPE_NAME_START) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_create failed"); if (sync_pipe_create(end_sync_pipes, PIPE_NAME_END) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_create failed"); /* * to test whether execve(2) sets ETXTBSY when a second * child process attempts to execve the executable opened * by the first child process */ if ((pid = FORK_OR_VFORK()) == -1) tst_brkm(TBROK, cleanup, "fork #1 failed"); else if (pid == 0) { #ifdef UCLINUX if (self_exec(av[0], "nS", 1, test_app) < 0) tst_brkm(TBROK, cleanup, "self_exec failed"); #else do_child_1(); #endif } if (sync_pipe_wait(start_sync_pipes) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_wait failed"); if (sync_pipe_close(start_sync_pipes, PIPE_NAME_START) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_close failed"); if ((pid1 = FORK_OR_VFORK()) == -1) tst_brkm(TBROK, cleanup, "fork #2 failed"); if (pid1 == 0) { retval = 3; argv[0] = 0; env[0] = 0; /* do not interfere with end synchronization of first * child */ sync_pipe_close(end_sync_pipes, PIPE_NAME_END); TEST(execve(test_app, argv, env)); TEST_ERROR_LOG(TEST_ERRNO); if (TEST_ERRNO != ETXTBSY) { retval = 1; perror("didn't get ETXTBSY\n"); } else printf("execve failed with ETXTBSY as " "expected\n"); exit(retval); } /* wait for the child to finish */ if (waitpid(pid1, &status, 0) == -1) tst_brkm(TBROK|TERRNO, cleanup, "waitpid failed"); if (WIFEXITED(status) && WEXITSTATUS(status) == 3) tst_resm(TPASS, "execve failed as expected"); else tst_resm(TFAIL, "execve succeeded, expected failure"); /* terminate first child */ sync_pipe_notify(end_sync_pipes); (void) waitpid(pid, NULL, 0); } cleanup(); tst_exit(); }
int main(int ac, char **av) { int fd, i; int tlen = 0; struct sigaction act; int lc; char *msg; struct statvfs fs; /* * parse standard options */ if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) { tst_resm(TBROK, "OPTION PARSING ERROR - %s", msg); tst_exit(); } #ifdef UCLINUX maybe_run_child(&dochild, "dddd", filename, &recstart, &reclen, &ppid); #endif local_flag = PASSED; tst_tmpdir(); if (statvfs(".", &fs) == -1) { tst_resm(TFAIL | TERRNO, "statvfs failed"); tst_rmdir(); tst_exit(); } if ((fs.f_flag & MS_MANDLOCK) == 0) { tst_resm(TCONF, "The filesystem where /tmp is mounted does" " not support mandatory locks. Cannot run this test."); tst_rmdir(); tst_exit(); } for (lc = 0; TEST_LOOPING(lc); lc++) { setvbuf(stdin, 0, _IOLBF, BUFSIZ); setvbuf(stdout, 0, _IOLBF, BUFSIZ); setvbuf(stderr, 0, _IOLBF, BUFSIZ); ppid = getpid(); srand(ppid); sigemptyset(&set); act.sa_handler = (void (*)())usr1hndlr; act.sa_mask = set; act.sa_flags = 0; if (sigaction(SIGUSR1, &act, 0)) { tst_resm(TBROK, "Sigaction for SIGUSR1 failed"); tst_rmdir(); tst_exit(); } /* end if */ if (sigaddset(&set, SIGUSR1)) { tst_resm(TBROK, "sigaddset for SIGUSR1 failed"); tst_rmdir(); tst_exit(); } if (sigprocmask(SIG_SETMASK, &set, 0)) { tst_resm(TBROK, "sigprocmask for SIGUSR1 failed"); tst_rmdir(); tst_exit(); } for (i = 0; i < iterations; i++) { sprintf(filename, "%s.%d.%d\n", progname, ppid, i); if ((fd = open(filename, O_CREAT | O_RDWR, 02666)) < 0) { tst_resm(TBROK, "parent error opening/creating %s", filename); cleanup(); } /* end if */ if (chown(filename, geteuid(), getegid()) == -1) { tst_resm(TBROK, "parent error chowning %s", filename); cleanup(); } /* end if */ if (chmod(filename, 02666) == -1) { tst_resm(TBROK, "parent error chmoding %s", filename); cleanup(); } /* end if */ do { if (write(fd, buffer, BUFSIZE) < 0) { tst_resm(TBROK, "parent write failed to %s", filename); cleanup(); } tlen += BUFSIZE; } while (tlen < len); close(fd); reclen = RECLEN; /* * want at least RECLEN bytes BEFORE AND AFTER the * record lock. */ recstart = RECLEN + rand() % (len - 3 * RECLEN); if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_create failed"); if ((cpid = FORK_OR_VFORK()) < 0) { unlink(filename); tst_resm(TINFO, "System resource may be too low, fork() malloc()" " etc are likely to fail."); tst_resm(TBROK, "Test broken due to inability of fork."); tst_rmdir(); tst_exit(); } if (cpid == 0) { #ifdef UCLINUX if (self_exec (av[0], "dddd", filename, recstart, reclen, ppid) < -1) { unlink(filename); tst_resm(TBROK, "self_exec failed."); tst_rmdir(); tst_exit(); } #else dochild(); #endif /* never returns */ } if (sync_pipe_wait(sync_pipes) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_wait failed"); if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_close failed"); doparent(); /* child should already be dead */ unlink(filename); } if (local_flag == PASSED) tst_resm(TPASS, "Test passed."); else tst_resm(TFAIL, "Test failed."); tst_rmdir(); tst_exit(); } /* end for */ tst_exit(); }
int main(int ac, char **av) { int lc; char *msg; if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); #ifdef UCLINUX maybe_run_child(&do_child_uclinux, "d", &msg_q_1); #endif setup(); /* global setup */ if (sync_pipe_create(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_create failed"); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; /* * fork a child that will attempt to read a non-existent * message from the queue */ if ((c_pid = FORK_OR_VFORK()) == -1) tst_brkm(TBROK, cleanup, "could not fork"); if (c_pid == 0) { /* * Attempt to read a message without IPC_NOWAIT. * With no message to read, the child sleeps. */ #ifdef UCLINUX if (self_exec(av[0], "d", msg_q_1) < 0) tst_brkm(TBROK, cleanup, "could not self_exec"); #else do_child(); #endif } else { if (sync_pipe_wait(sync_pipes) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_wait failed"); if (sync_pipe_close(sync_pipes, PIPE_NAME) == -1) tst_brkm(TBROK, cleanup, "sync_pipe_close failed"); /* After son has been created, give it a chance to execute the * msgrcv command before we continue. Without this sleep, on SMP machine * the father kill could be executed before the son msgrcv. */ sleep(1); /* send a signal that must be caught to the child */ if (kill(c_pid, SIGHUP) == -1) tst_brkm(TBROK, cleanup, "kill failed"); waitpid(c_pid, NULL, 0); } } cleanup(); tst_exit(); }