2000-09-03 11:58:18 +08:00
|
|
|
/*
|
|
|
|
* 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 <fcntl.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/signal.h>
|
|
|
|
#include <errno.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();
|
2003-01-24 09:09:40 +08:00
|
|
|
void cleanup(void) __attribute__((noreturn));
|
2000-09-03 11:58:18 +08:00
|
|
|
int testrun(int flag, int bytes, int ti);
|
|
|
|
|
2003-01-24 09:09:40 +08:00
|
|
|
const char *TCID="asyncio02"; /* Test program identifier. */
|
2000-09-03 11:58:18 +08:00
|
|
|
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];
|
2003-01-24 09:09:40 +08:00
|
|
|
const char *filename; /* name of the temporary file */
|
2000-09-03 11:58:18 +08:00
|
|
|
|
|
|
|
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 */
|
2000-09-06 22:21:53 +08:00
|
|
|
const char *msg; /* message returned from parse_opts */
|
2000-09-03 11:58:18 +08:00
|
|
|
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);
|
|
|
|
|
|
|
|
/* 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() */
|
|
|
|
|
|
|
|
|