/* * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Further, this software is distributed without any warranty that it is * free of the rightful claim of any third person regarding infringement * or the like. Any license provided herein, whether implied or * otherwise, applies only to this software file. Patent licenses, if * any, provided herein do not apply to combinations of this program with * other software, or any other product whatsoever. * * You should have received a copy of the GNU General Public License along * with this program; if not, write the Free Software Foundation, Inc., 59 * Temple Place - Suite 330, Boston MA 02111-1307, USA. * * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, * Mountain View, CA 94043, or: * * http://www.sgi.com * * For further information regarding this notice, see: * * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ * */ /* $Id$ */ /************************************************************ * OS Test - Silicon Graphics, Inc. * Mendota Heights, Minnesota * * TEST IDENTIFIER: aiotcs02: write/close flushes data to the file * * PARENT DOCUMENT: aiotds01: kernel i/o * * AUTHOR: Barrie Kletscher * * CO-PILOT: Dave Baumgartner * * TEST ITEMS: * for each open flags set used: * 1. Multiple writes to a file work as specified for * more than BUFSIZ bytes. * 2. Multiple writes to a file work as specified for * BUFSIZ bytes. * 3. Multiple writes to a file work as specified for * lower than BUFSIZ bytes. * * INPUT SPECIFICATIONS: * Standard parse_opts supported options. * * OUTPUT SPECIFICATIONS * Standard tst_res output format * * ENVIRONMENTAL NEEDS: * This program uses the environment variable TMPDIR for the location * of the temporary directory. * * * SPECIAL PROCEDURAL REQUIREMENTS: * The program must be linked with tst_*.o and parse_opts.o. * * INTERCASE DEPENDENCIES: * NONE. * * DETAILED DESCRIPTION: * Attempt to get some memory to work with. * Call testrun writing (BUFSIZ + 1) bytes * Call testrun writing BUFSIZ bytes * Repeated call to testrun() with decreasing write sizes * less than BUFSIZ * End * * Start testrun() * Attempt to open a temporary file. * Write the memory to the file. * Attempt to close the file which also flushes the buffers. * Now check to see if the number of bytes written is the * same as the number of bytes in the file. * Cleanup * * BUGS: * NONE. * ************************************************************/ #include #include #include #include #include #include "test.h" #include "usctest.h" #define FLAG O_RDWR | O_CREAT | O_TRUNC /* Flags used when opening temp tile */ #define MODE 0777 /* Mode to open file with */ #define WRITES 10 /* Number of times buffer is written */ #define DECR 1000 /* Number of bytes decremented between */ /* Calls to testrun() */ #define OK -1 /* Return value from testrun() */ #define FNAME1 "aio02.1" #define FNAME2 "aio02.2" #define FNAME3 "aio02.3" #define ERR_MSG1 "Bytes in file not equal to bytes written." #define ERR_MSG2 "Bytes in file (%d) not equal to bytes written (%d)." char *dp; /* pointer to area of memory */ void setup(); void cleanup(void) __attribute__((noreturn)); int testrun(int flag, int bytes, int ti); const char *TCID="asyncio02"; /* Test program identifier. */ int TST_TOTAL=6; /* Total number of test cases. */ extern int Tst_count; /* Test Case counter for tst_* routines */ extern int Tst_nobuf; /* variable used to turn off tst_res buffering */ extern int errno; int exp_enos[]={0}; /* Array of expected errnos */ char mesg[150]; const char *filename; /* name of the temporary file */ char *Progname; int Open_flags; int Flags[] = { O_RDWR | O_CREAT | O_TRUNC, O_RDWR | O_CREAT | O_TRUNC }; int Num_flags; /*********************************************************************** * MAIN ***********************************************************************/ int main(int ac, char **av) { int i; /* counter */ int ret_val; /* return value from testrun call */ int eok; /* everything is ok flag */ int lc; /* loop counter */ const char *msg; /* message returned from parse_opts */ int flag_cnt; Tst_nobuf=1; Num_flags = sizeof(Flags)/sizeof(int); TST_TOTAL= 3 * Num_flags; /*************************************************************** * parse standard options, and exit if there is an error ***************************************************************/ if ( (msg=parse_opts(ac, av, (option_t *) NULL, NULL)) != (char *) NULL ) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); tst_exit(); } /*************************************************************** * perform global setup for test ***************************************************************/ setup(); /*************************************************************** * check looping state if -c option given ***************************************************************/ for (lc=0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping. */ Tst_count=0; for (flag_cnt=0; flag_cnt= 0; i -= DECR) { if((ret_val = testrun(Flags[flag_cnt],i,3)) != OK) { char output[80]; /* local output char string */ (void)sprintf(output,ERR_MSG2,ret_val,i*WRITES); tst_resm(TFAIL,output); } } if ( eok && STD_FUNCTIONAL_TEST ) tst_resm(TPASS, "Less than BUFSIZE bytes multiple synchronous writes to a file checks out ok"); } } cleanup(); return 0; } /* end main() */ /*********************************************************** * * This function does the actual running of the tests. * ***********************************************************/ int testrun(int flag, int bytes, int ti) { void cleanup(); int fildes, /* temporary file's descriptor */ i; /* counter */ int ret; struct stat buffer; /* buffer of memory required for stat command */ /* * Attempt to open a temporary file. */ if((fildes = open(filename,flag,MODE)) == -1) { sprintf(mesg, "open failed, errno:%d", errno); tst_brkm(TBROK, cleanup, mesg); } /* * Write the memory to the file. */ for(i = 0; i < WRITES; i++) { TEST( write(fildes,dp,(unsigned)bytes) ); if( TEST_RETURN == -1) { sprintf(mesg, "write failed, errno:%d", errno); tst_brkm(TBROK, cleanup, mesg); } } /* end for() */ /* * Attempt to close the file which also flushes the buffers. */ if(close(fildes) == -1) { sprintf(mesg, "close failed, errno:%d", errno); tst_brkm(TBROK, cleanup, mesg); } ret=OK; if ( STD_FUNCTIONAL_TEST ) { /* * Now check to see if the number of bytes written is the * same as the number of bytes in the file. */ if(stat(filename,&buffer) == -1) { sprintf(mesg, "stat failed, errno:%d", errno); tst_brkm(TBROK, cleanup, mesg); } if(buffer.st_size != (off_t)(bytes * WRITES)) { ret=(int)buffer.st_size; } } if ( unlink(filename) == -1 ) { sprintf(mesg, "unlink failed, errno:%d", errno); tst_brkm(TBROK, cleanup, mesg); } return ret; } /* end testrun() */ /*************************************************************** * setup() - performs all ONE TIME setup for this test. ***************************************************************/ void setup() { /* capture signals */ tst_sig(FORK, DEF_HANDLER, cleanup); /* create a temporary directory and go to it */ tst_tmpdir(); /* Indicate which errnos are expected */ TEST_EXP_ENOS(exp_enos); /* Pause if that option was specified */ TEST_PAUSE; /* * Attempt to get some memory to work with. */ if((dp = (char *)malloc((unsigned)BUFSIZ+1)) == NULL) { sprintf(mesg, "malloc failed, errno:%d", errno); tst_brkm(TBROK, cleanup, mesg); } } /* End setup() */ /*************************************************************** * cleanup() - performs all ONE TIME cleanup for this test at * completion or premature exit. ***************************************************************/ void cleanup() { /* * print timing stats if that option was specified. * print errno log if that option was specified. */ TEST_CLEANUP; /* remove temporary directory and all files in it. */ tst_rmdir(); /* exit with return code appropriate for results */ tst_exit(); } /* End cleanup() */