From 41f17ba4a5e603ae5360962ac9f9fda9064f554a Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Mon, 24 Sep 2007 21:34:47 +0000 Subject: 2007-09-24 Joel Sherrill PR 1262/filesystem * Makefile.am, configure.ac, include/pmacros.h: Add support for readv() and writev() including documentation and test case. * psxrdwrv/.cvsignore, psxrdwrv/Makefile.am, psxrdwrv/main.c, psxrdwrv/psxrdwrv.scn, psxrdwrv/test.c: New files. --- testsuites/psxtests/psxrdwrv/.cvsignore | 2 + testsuites/psxtests/psxrdwrv/Makefile.am | 28 ++ testsuites/psxtests/psxrdwrv/main.c | 45 ++++ testsuites/psxtests/psxrdwrv/psxrdwrv.scn | 18 ++ testsuites/psxtests/psxrdwrv/test.c | 415 ++++++++++++++++++++++++++++++ 5 files changed, 508 insertions(+) create mode 100644 testsuites/psxtests/psxrdwrv/.cvsignore create mode 100644 testsuites/psxtests/psxrdwrv/Makefile.am create mode 100644 testsuites/psxtests/psxrdwrv/main.c create mode 100644 testsuites/psxtests/psxrdwrv/psxrdwrv.scn create mode 100644 testsuites/psxtests/psxrdwrv/test.c (limited to 'testsuites/psxtests/psxrdwrv') diff --git a/testsuites/psxtests/psxrdwrv/.cvsignore b/testsuites/psxtests/psxrdwrv/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/testsuites/psxtests/psxrdwrv/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/testsuites/psxtests/psxrdwrv/Makefile.am b/testsuites/psxtests/psxrdwrv/Makefile.am new file mode 100644 index 0000000000..dc199c4601 --- /dev/null +++ b/testsuites/psxtests/psxrdwrv/Makefile.am @@ -0,0 +1,28 @@ +## +## $Id$ +## + +MANAGERS = all + +rtems_tests_PROGRAMS = psxrdwrv.exe +psxrdwrv_exe_SOURCES = main.c test.c ../include/pmacros.h + +dist_rtems_tests_DATA = psxrdwrv.scn + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../automake/compile.am +include $(top_srcdir)/../automake/leaf.am + +psxrdwrv_exe_LDADD = $(MANAGERS_NOT_WANTED:%=$(PROJECT_LIB)/no-%.rel) + +AM_CPPFLAGS += -I$(top_srcdir)/include +AM_CPPFLAGS += -I$(top_srcdir)/../support/include + +LINK_OBJS = $(psxrdwrv_exe_OBJECTS) $(psxrdwrv_exe_LDADD) +LINK_LIBS = $(psxrdwrv_exe_LDLIBS) + +psxrdwrv.exe$(EXEEXT): $(psxrdwrv_exe_OBJECTS) $(psxrdwrv_exe_DEPENDENCIES) + @rm -f psxrdwrv.exe$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/psxtests/psxrdwrv/main.c b/testsuites/psxtests/psxrdwrv/main.c new file mode 100644 index 0000000000..3b864ac7e7 --- /dev/null +++ b/testsuites/psxtests/psxrdwrv/main.c @@ -0,0 +1,45 @@ +/* + * Simple test program -- simplified version of sample test hello. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#define TEST_INIT + +#include +#include + +void test_main( void ); + +rtems_task Init( + rtems_task_argument ignored +) +{ + test_main(); + rtems_test_exit( 0 ); +} + +/* configuration information */ + +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM +#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 6 + +#define CONFIGURE_MAXIMUM_TASKS 1 + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_INIT + +#include + +/* end of file */ diff --git a/testsuites/psxtests/psxrdwrv/psxrdwrv.scn b/testsuites/psxtests/psxrdwrv/psxrdwrv.scn new file mode 100644 index 0000000000..26e1ea5ac9 --- /dev/null +++ b/testsuites/psxtests/psxrdwrv/psxrdwrv.scn @@ -0,0 +1,18 @@ +*** POSIX TEST READV/WRITEV *** +writev bad file descriptor -- EBADF +readv bad file descriptor -- EBADF +writev bad iovec pointer -- EINVAL +readv bad iovec pointer -- EINVAL +readv bad iovcnt of 0 -- EINVAL +readv bad iovcnt of 0 -- EINVAL +writev bad iovcnt negative -- EINVAL +readv bad iovcnt negative -- EINVAL +writev bad iov[i].iov_base -- EINVAL +readv bad iov[i].iov_base -- EINVAL +writev bad iov[i].iov_len < 0 -- EINVAL +readv bad iov[i].iov_len = 0 -- EINVAL +writev iov_len total overflows -- EINVAL +readv iov_len total overflows -- EINVAL +File written using writev .. OK +File read using readv .. OK +*** END OF TEST PSXRDWRV *** diff --git a/testsuites/psxtests/psxrdwrv/test.c b/testsuites/psxtests/psxrdwrv/test.c new file mode 100644 index 0000000000..aa583bc61f --- /dev/null +++ b/testsuites/psxtests/psxrdwrv/test.c @@ -0,0 +1,415 @@ +/* + * Psx13 + * + * This test exercises the following routines: + * + * readv - implemented + * writev - implemented + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if defined(__rtems__) + #include + #include + #include +#else + #define TRUE 1 + #define FALSE 0 + #include + #define rtems_test_exit(_s) exit(_s) +#endif + +#define TESTFILE "testfile1.tst" + + +/* This buffer size is assumed in the iovec initialization below */ +#define MAX_BUFFER 1000 +unsigned char PatternBuffer[MAX_BUFFER]; +unsigned char ReadBuffer[MAX_BUFFER]; + +/* + * fillPatternBuffer function + * + * Fill the test buffer. + * + * Returns: TRUE if buffer filled + * FALSE if buffer failed to fill + * + */ + +int fillPatternBuffer(void) +{ + int retval = TRUE; + int i; + + for (i=0 ; i<200 ; i++ ) PatternBuffer[i] = 'a'; + for ( ; i<400 ; i++ ) PatternBuffer[i] = 'b'; + for ( ; i<600 ; i++ ) PatternBuffer[i] = 'c'; + for ( ; i<800 ; i++ ) PatternBuffer[i] = 'd'; + for ( ; i<1000 ; i++ ) PatternBuffer[i] = 'e'; + return retval; +} + +/* + * doFunctionalTest function + * + * Write a file with writev and then read it back with readv. + * + * Returns: TRUE if all operations worked as expected + * FALSE if an operation did not work as expected. + * + */ + +int doFunctionalTest(void) { + FILE *fp; + int fd; + struct iovec rdvec[4]; + struct iovec wrvec[4]; + int rc; + + + /* + * Setup the iovec + */ + wrvec[0].iov_base = &PatternBuffer[0]; + wrvec[0].iov_len = 100; + wrvec[1].iov_base = &PatternBuffer[100]; + wrvec[1].iov_len = 200; + wrvec[2].iov_base = &PatternBuffer[300]; + wrvec[2].iov_len = 300; + wrvec[3].iov_base = &PatternBuffer[600]; + wrvec[3].iov_len = 400; + + rdvec[0].iov_base = &ReadBuffer[0]; + rdvec[0].iov_len = 400; + rdvec[1].iov_base = &ReadBuffer[400]; + rdvec[1].iov_len = 300; + rdvec[2].iov_base = &ReadBuffer[700]; + rdvec[2].iov_len = 200; + rdvec[3].iov_base = &ReadBuffer[900]; + rdvec[3].iov_len = 100; + + /* + * Write the File + */ + fp = fopen(TESTFILE, "wt"); + if ( fp == NULL ) { + printf( "fopen for write: %d=%s\n", errno, strerror(errno)); + return FALSE; + } + fd = fileno(fp); + + rc = writev(fd, wrvec, 4); + if ( rc <= 0 ) { + printf( "writev: %d=%s\n", errno, strerror(errno) ); + return FALSE; + } + + fclose(fp); + + puts("File written using writev .. OK"); + + /* + * Now read it back and check it + */ + + fp = fopen(TESTFILE, "rt"); + if ( fp == NULL ) { + printf( "fopen for write: %d=%s\n", errno, strerror(errno)); + return FALSE; + } + fd = fileno(fp); + + rc = readv(fd, rdvec, 4); + if ( rc <= 0 ) { + printf( "rd: %d=%s\n", errno, strerror(errno) ); + return FALSE; + } + + if ( memcmp( PatternBuffer, ReadBuffer, MAX_BUFFER ) ) { + puts("readv .. Buffers do not match"); + return FALSE; + } + + puts("File read using readv .. OK"); + + return TRUE; +} + +/* + * doErrorTest function + * + * Hit all the error cases in readv/writev. + * + * Returns: TRUE if all operations worked as expected + * FALSE if an operation did not work as expected. + * + */ + +int doErrorTest(void) +{ + FILE *fp; + int fd; + struct iovec vec[4]; + int rc; + + /* + * Open and close the file to get a bad file descriptor + */ + fp = fopen(TESTFILE, "wt"); + if ( fp == NULL ) { + printf( "fopen for error 1: %d=%s\n", errno, strerror(errno)); + return FALSE; + } + fd = fileno(fp); + fclose(fp); + + /* writev -- bad file descriptor */ + puts("writev bad file descriptor -- EBADF"); + rc = writev(fd, vec, 4); + if ( (rc != -1) || (errno != EBADF) ) { + printf( "writev error 1: %d=%s\n", errno, strerror(errno) ); + return FALSE; + } + + /* readv -- bad file descriptor */ + puts("readv bad file descriptor -- EBADF"); + rc = read(fd, vec, 4); + if ( (rc != -1) || (errno != EBADF) ) { + printf( "readv error 1: %d=%s\n", errno, strerror(errno) ); + return FALSE; + } + + /* + * Open the file for the rest of the tests + */ + fp = fopen(TESTFILE, "wt"); + if ( fp == NULL ) { + printf( "fopen for error 2: %d=%s\n", errno, strerror(errno)); + return FALSE; + } + fd = fileno(fp); + + /* writev -- bad iovec pointer */ + puts("writev bad iovec pointer -- EINVAL"); + rc = writev(fd, NULL, 4); + if ( (rc != -1) || (errno != EINVAL) ) { + printf( "writev error 2: %d=%s\n", errno, strerror(errno) ); + fclose(fp); + return FALSE; + } + + /* readv -- bad iovec pointer */ + puts("readv bad iovec pointer -- EINVAL"); + rc = readv(fd, NULL, 4); + if ( (rc != -1) || (errno != EINVAL) ) { + printf( "readv error 2: %d=%s\n", errno, strerror(errno) ); + fclose(fp); + return FALSE; + } + + /* writev -- bad iovcnt 0 */ + puts("readv bad iovcnt of 0 -- EINVAL"); + rc = writev(fd, vec, 0); + if ( (rc != -1) || (errno != EINVAL) ) { + printf( "writev error 3: %d=%s\n", errno, strerror(errno) ); + fclose(fp); + return FALSE; + } + + /* readv -- bad iovcnt 0 */ + puts("readv bad iovcnt of 0 -- EINVAL"); + rc = readv(fd, vec, 0); + if ( (rc != -1) || (errno != EINVAL) ) { + printf( "readv error 3: %d=%s\n", errno, strerror(errno) ); + fclose(fp); + return FALSE; + } + + /* writev -- bad iovcnt negative */ + puts("writev bad iovcnt negative -- EINVAL"); + rc = writev(fd, vec, -2); + if ( (rc != -1) || (errno != EINVAL) ) { + printf( "writev error 4: %d=%s\n", errno, strerror(errno) ); + fclose(fp); + return FALSE; + } + + /* readv -- bad iovcnt negative */ + puts("readv bad iovcnt negative -- EINVAL"); + rc = readv(fd, vec, -100); + if ( (rc != -1) || (errno != EINVAL) ) { + printf( "readv error 4: %d=%s\n", errno, strerror(errno) ); + fclose(fp); + return FALSE; + } + + /* writev -- bad iov[i].iov_base */ + vec[0].iov_base = vec; + vec[0].iov_len = 100; + vec[1].iov_base = NULL; + vec[1].iov_len = 100; + puts("writev bad iov[i].iov_base -- EINVAL"); + rc = writev(fd, vec, 2); + if ( (rc != -1) || (errno != EINVAL) ) { + printf( "writev error 5: %d=%s\n", errno, strerror(errno) ); + fclose(fp); + return FALSE; + } + + /* readv -- bad iov[i].iov_base */ + vec[0].iov_base = vec; + vec[0].iov_len = 100; + vec[1].iov_base = NULL; + vec[1].iov_len = 100; + puts("readv bad iov[i].iov_base -- EINVAL"); + rc = readv(fd, vec, 2); + if ( (rc != -1) || (errno != EINVAL) ) { + printf( "readv error 5: %d=%s\n", errno, strerror(errno) ); + fclose(fp); + return FALSE; + } + + /* writev -- bad iov[i].iov_len < 0 */ + vec[0].iov_base = vec; + vec[0].iov_len = 100; + vec[1].iov_base = vec; + vec[1].iov_len = -10; + puts("writev bad iov[i].iov_len < 0 -- EINVAL"); + rc = writev(fd, vec, 2); + if ( (rc != -1) || (errno != EINVAL) ) { + printf( "writev error 6: %d=%s\n", errno, strerror(errno) ); + fclose(fp); + return FALSE; + } + + /* readv -- bad iov[i].iov_len = 0 */ + vec[0].iov_base = vec; + vec[0].iov_len = 100; + vec[1].iov_base = vec; + vec[1].iov_len = -1024; + puts("readv bad iov[i].iov_len = 0 -- EINVAL"); + rc = readv(fd, vec, 2); + if ( (rc != -1) || (errno != EINVAL) ) { + printf( "readv error 6: %d=%s\n", errno, strerror(errno) ); + fclose(fp); + return FALSE; + } + + /* writev -- iov_len total overflows */ + vec[0].iov_base = vec; + vec[0].iov_len = SSIZE_MAX; + vec[1].iov_base = vec; + vec[1].iov_len = SSIZE_MAX; + vec[2].iov_base = vec; + vec[2].iov_len = SSIZE_MAX; + puts("writev iov_len total overflows -- EINVAL"); + rc = writev(fd, vec, 3); + if ( (rc != -1) || (errno != EINVAL) ) { + printf( "writev error 7: %d=%s\n", errno, strerror(errno) ); + fclose(fp); + return FALSE; + } + + /* readv -- iov_len total overflows */ + vec[0].iov_base = vec; + vec[0].iov_len = SSIZE_MAX; + vec[1].iov_base = vec; + vec[1].iov_len = SSIZE_MAX; + puts("readv iov_len total overflows -- EINVAL"); + rc = readv(fd, vec, 2); + if ( (rc != -1) || (errno != EINVAL) ) { + printf( "readv error 7: %d=%s\n", errno, strerror(errno) ); + fclose(fp); + return FALSE; + } + + /* writev -- all zero length buffers */ + vec[0].iov_base = vec; + vec[0].iov_len = 0; + vec[1].iov_base = vec; + vec[1].iov_len = 0; + puts("writev iov_len works with no effect -- OK"); + rc = writev(fd, vec, 2); + if ( (rc != 0) ) { + printf( "writev error 8: %d=%s\n", errno, strerror(errno) ); + fclose(fp); + return FALSE; + } + + /* readv -- all zero length buffers */ + vec[0].iov_base = vec; + vec[0].iov_len = 0; + vec[1].iov_base = vec; + vec[1].iov_len = 0; + puts("readv iov_len works with no effect -- OK"); + rc = readv(fd, vec, 2); + if ( (rc != 0) ) { + printf( "readv error 8: %d=%s\n", errno, strerror(errno) ); + fclose(fp); + return FALSE; + } + + fclose(fp); + return TRUE; +} + + +/* --------------------------------------------------------------- + * Main function + * + * main entry point to the test + * + * --------------------------------------------------------------- + */ + +#if defined(__rtems__) +int test_main(void) +#else +int main( + int argc, + char **argv +) +#endif +{ + puts( "*** POSIX TEST READV/WRITEV ***" ); + + if ( fillPatternBuffer() != TRUE ) { + puts("Error filling pattern buffer" ); + rtems_test_exit(0); + } + + if (doErrorTest() != TRUE) { + puts("Error during error test!!!!"); + rtems_test_exit(0); + } + if (doFunctionalTest() != TRUE) { + puts("Error during functional test!!!!"); + rtems_test_exit(0); + } + + unlink(TESTFILE); + puts( "*** END OF TEST PSXRDWRV ***" ); + rtems_test_exit(0); +} -- cgit v1.2.3