[LTP] [COMMITTED] [PATCH 3/4] syscalls/write: write05 new test library refactoring
Cyril Hrubis
chrubis@suse.cz
Tue Jan 23 17:41:16 CET 2018
From: Carlo Marcelo Arenas Belón <carenas@gmail.com>
Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
testcases/kernel/syscalls/write/write05.c | 235 +++++++++---------------------
1 file changed, 70 insertions(+), 165 deletions(-)
diff --git a/testcases/kernel/syscalls/write/write05.c b/testcases/kernel/syscalls/write/write05.c
index bcbe85874..ec157ae28 100644
--- a/testcases/kernel/syscalls/write/write05.c
+++ b/testcases/kernel/syscalls/write/write05.c
@@ -1,6 +1,9 @@
/*
*
* Copyright (c) International Business Machines Corp., 2001
+ * 07/2001 Ported by John George
+ * 04/2002 wjhuie sigset cleanups
+ * 08/2007 Ricardo Salveti de Araujo <rsalveti@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,199 +21,101 @@
*/
/*
- * NAME
- * write05.c
- *
* DESCRIPTION
* Check the return value, and errnos of write(2)
* - when the file descriptor is invalid - EBADF
* - when the buf parameter is invalid - EFAULT
* - on an attempt to write to a pipe that is not open for reading - EPIPE
- *
- * ALGORITHM
- * Attempt to write on a file with negative file descriptor, check for -1
- * Attempt to write on a file with invalid buffer, check for -1
- * Open a pipe and close the read end, attempt to write to the write
- * end, check for -1.
- *
- * USAGE: <for command-line>
- * write05 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -e : Turn on errno logging.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * History
- * 07/2001 John George
- * -Ported
- * 04/2002 wjhuie sigset cleanups
- * 08/2007 Ricardo Salveti de Araujo <rsalveti@linux.vnet.ibm.com>
- * - Closing the fd before removing the file
- *
- * Restrictions
- * None
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
+#include <stdlib.h>
#include <sys/wait.h>
#include <sys/mman.h>
-#include "test.h"
-
-void setup(void);
-void cleanup(void);
-
-char *TCID = "write05";
-int TST_TOTAL = 1;
-char filename[100];
-int fd;
-
-char *bad_addr = 0;
-
-int main(int argc, char **argv)
+#include "tst_test.h"
+
+static int fd;
+static int inv_fd = -1;
+static char b[32];
+static char *buf = b;
+static char *bad_addr;
+static int pipefd[2];
+
+static struct tcase {
+ int *fd;
+ char **buf;
+ size_t size;
+ int exp_errno;
+} tcases[] = {
+ {&inv_fd, &buf, sizeof(buf), EBADF},
+ {&fd, &bad_addr, sizeof(buf), EFAULT},
+ {&pipefd[1], &buf, sizeof(buf), EPIPE},
+};
+
+static int sigpipe_cnt;
+
+static void sighandler(int sig)
{
- int lc;
-
- char pbuf[BUFSIZ];
- int pipefildes[2];
- int status, pid;
-
- tst_parse_opts(argc, argv, NULL, NULL);
-
- /* global setup */
- 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;
-
-//block1:
- tst_resm(TINFO, "Enter Block 1: test with bad fd");
- if (write(-1, pbuf, 1) != -1) {
- tst_resm(TFAIL, "write of invalid fd passed");
- } else {
- if (errno != EBADF) {
- tst_resm(TFAIL, "expected EBADF got %d", errno);
- }
- tst_resm(TPASS, "received EBADF as expected.");
- }
- tst_resm(TINFO, "Exit Block 1");
-
-//block2:
- tst_resm(TINFO, "Enter Block 2: test with a bad address");
- fd = creat(filename, 0644);
- if (fd < 0) {
- tst_resm(TFAIL, "creating a new file failed");
- cleanup();
- }
- if (write(fd, bad_addr, 10) != -1) {
- tst_resm(TFAIL, "write() on an invalid buffer "
- "succeeded, but should have failed");
- cleanup();
- } else {
- if (errno != EFAULT) {
- tst_resm(TFAIL, "write() returned illegal "
- "errno: expected EFAULT, got %d",
- errno);
- cleanup();
- }
- tst_resm(TPASS, "received EFAULT as expected.");
- }
- tst_resm(TINFO, "Exit Block 2");
-
-//block3:
- tst_resm(TINFO, "Enter Block 3: test with invalid pipe");
- if ((pid = FORK_OR_VFORK()) == 0) { /* child */
- if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
- tst_resm(TINFO, "signal failed");
- }
- if (pipe(pipefildes) == -1) {
- tst_brkm(TBROK, NULL, "can't open pipe");
- exit(errno);
- }
- close(pipefildes[0]);
- if (write(pipefildes[1], pbuf, 1) != -1) {
- tst_resm(TFAIL, "write on read-closed"
- "pipe succeeded");
- exit(-1);
- } else {
- if (errno != EPIPE) {
- tst_resm(TFAIL, "write() failed to set"
- " errno to EPIPE, got: %d",
- errno);
- exit(errno);
- }
- exit(0);
- }
- } else {
- if (pid < 0) {
- tst_resm(TFAIL, "Fork failed");
- }
- wait(&status);
- if (WIFSIGNALED(status) &&
- WTERMSIG(status) == SIGPIPE) {
- tst_resm(TFAIL, "child set SIGPIPE in exit");
- } else if (WEXITSTATUS(status) != 0) {
- tst_resm(TFAIL, "exit status from child "
- "expected 0 got %d", status >> 8);
- } else {
- tst_resm(TPASS, "received EPIPE as expected.");
- }
- tst_resm(TINFO, "Exit Block 3");
- }
- close(fd);
- }
- cleanup();
- tst_exit();
+ if (sig == SIGPIPE)
+ sigpipe_cnt++;
}
-/*
- * setup()
- * performs all ONE TIME setup for this test
- */
-void setup(void)
+static void verify_write(unsigned int i)
{
+ struct tcase *tc = &tcases[i];
- tst_sig(FORK, DEF_HANDLER, cleanup);
+ sigpipe_cnt = 0;
- /* Pause if that option was specified
- * TEST_PAUSE contains the code to fork the test with the -i option.
- * You want to make sure you do this before you create your temporary
- * directory.
- */
- TEST_PAUSE;
+ TEST(write(*tc->fd, *tc->buf, tc->size));
- /* Create a unique temporary directory and chdir() to it. */
- tst_tmpdir();
+ if (TEST_RETURN != -1) {
+ tst_res(TFAIL, "write() succeeded unexpectedly");
+ return;
+ }
- sprintf(filename, "write05.%d", getpid());
+ if (TEST_ERRNO != tc->exp_errno) {
+ tst_res(TFAIL | TTERRNO,
+ "write() failed unexpectedly, expected %s",
+ tst_strerrno(tc->exp_errno));
+ return;
+ }
- bad_addr = mmap(0, 1, PROT_NONE,
- MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
- if (bad_addr == MAP_FAILED) {
- printf("mmap failed\n");
+ if (tc->exp_errno == EPIPE && sigpipe_cnt != 1) {
+ tst_res(TFAIL, "sigpipe_cnt = %i", sigpipe_cnt);
+ return;
}
+ tst_res(TPASS | TTERRNO, "write() failed expectedly");
}
-/*
- * cleanup()
- * performs all ONE TIME cleanup for this test at
- * completion or premature exit
- */
-void cleanup(void)
+static void setup(void)
{
+ fd = SAFE_OPEN("write_test", O_RDWR | O_CREAT, 0644);
+
+ bad_addr = SAFE_MMAP(0, 1, PROT_NONE,
+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+
+ SAFE_PIPE(pipefd);
+ SAFE_CLOSE(pipefd[0]);
- /* Close the file descriptor befor removing the file */
- close(fd);
+ SAFE_SIGNAL(SIGPIPE, sighandler);
+}
- unlink(filename);
- tst_rmdir();
+static void cleanup(void)
+{
+ if (fd > 0)
+ SAFE_CLOSE(fd);
+ SAFE_MUNMAP(bad_addr, 1);
}
+
+static struct tst_test test = {
+ .needs_tmpdir = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .test = verify_write,
+ .tcnt = ARRAY_SIZE(tcases),
+};
--
2.13.6
More information about the ltp
mailing list