| /* |
| * 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: asyncio02.c,v 1.3 2001/06/06 19:24:24 nstraz Exp $ */ |
| /************************************************************ |
| * 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 <fcntl.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <sys/signal.h> |
| #include <errno.h> |
| #include <stdlib.h> |
| #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(); |
| int testrun(int flag, int bytes, int ti); |
| |
| 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]; |
| 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 */ |
| 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<Num_flags; flag_cnt++) { |
| |
| /* |
| * call testrun writing (BUFSIZ + 1) byte chunks |
| */ |
| |
| filename=FNAME1; |
| if( testrun(Flags[flag_cnt],BUFSIZ+1,1) != OK) |
| tst_resm(TFAIL,ERR_MSG1); |
| |
| else if ( STD_FUNCTIONAL_TEST ) { |
| tst_resm(TPASS, |
| "More than BUFSIZE bytes multiple synchronous writes to a file check out ok"); |
| } |
| |
| /* |
| * call testrun writing BUFSIZ byte chunks |
| */ |
| |
| filename=FNAME2; |
| if(testrun(Flags[flag_cnt],BUFSIZ,2) != OK) { |
| tst_resm(TFAIL,ERR_MSG1); |
| } |
| else if ( STD_FUNCTIONAL_TEST ) { |
| tst_resm(TPASS, |
| "BUFSIZE bytes multiple synchronous writes to a file checks out ok"); |
| } |
| |
| /* |
| * while the byte chunks are greater than 0 |
| * call testrun() with decreasing chunk sizes |
| */ |
| |
| filename=FNAME3; |
| eok=1; |
| for(i = BUFSIZ-1; i >= 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); |
| |
| /* Pause if that option was specified */ |
| TEST_PAUSE; |
| |
| /* create a temporary directory and go to it */ |
| tst_tmpdir(); |
| |
| /* Indicate which errnos are expected */ |
| TEST_EXP_ENOS(exp_enos); |
| |
| /* |
| * 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() */ |
| |
| |