blob: e2905f9e8686b75a8b4ea022c80f069440009a53 [file] [log] [blame]
/*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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.6 2009/08/28 11:17:39 vapier 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"
#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";
int TST_TOTAL = 6;
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;
int ret_val;
int eok; /* everything is ok flag */
int lc;
const char *msg;
int flag_cnt;
Num_flags = sizeof(Flags) / sizeof(int);
TST_TOTAL = 3 * Num_flags;
if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
setup();
for (lc = 0; TEST_LOOPING(lc); lc++) {
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 {
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 {
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) {
tst_resm(TFAIL, ERR_MSG2, ret_val,
i * WRITES);
}
}
if (eok) {
tst_resm(TPASS,
"Less than BUFSIZE bytes multiple synchronous writes to a file checks out ok");
}
}
}
cleanup();
tst_exit();
} /* end main() */
int testrun(int flag, int bytes, int ti)
{
int fildes, i, ret;
struct stat buffer; /* buffer of memory required for stat command */
/*
* Attempt to open a temporary file.
*/
if ((fildes = open(filename, flag, MODE)) == -1) {
tst_brkm(TBROK | TERRNO, cleanup, "open(%s) failed", filename);
}
/*
* Write the memory to the file.
*/
for (i = 0; i < WRITES; i++) {
TEST(write(fildes, dp, (unsigned)bytes));
if (TEST_RETURN == -1) {
tst_brkm(TBROK | TTERRNO, cleanup, "write() failed");
}
} /* end for () */
/*
* Attempt to close the file which also flushes the buffers.
*/
if (close(fildes) == -1) {
tst_brkm(TBROK | TERRNO, cleanup, "close() failed");
}
ret = OK;
/*
* 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) {
tst_brkm(TBROK | TERRNO, cleanup, "stat() failed");
}
if (buffer.st_size != (off_t) (bytes * WRITES)) {
ret = (int)buffer.st_size;
}
if (unlink(filename) == -1) {
tst_brkm(TBROK | TERRNO, cleanup, "unlink(%s) failed",
filename);
}
return ret;
} /* end testrun() */
/***************************************************************
* setup() - performs all ONE TIME setup for this test.
***************************************************************/
void setup(void)
{
tst_sig(FORK, DEF_HANDLER, cleanup);
TEST_PAUSE;
/* create a temporary directory and go to it */
tst_tmpdir();
/*
* Attempt to get some memory to work with.
*/
if ((dp = malloc((unsigned)BUFSIZ + 1)) == NULL) {
tst_brkm(TBROK | TERRNO, cleanup, "malloc() failed");
}
}
/***************************************************************
* cleanup() - performs all ONE TIME cleanup for this test at
* completion or premature exit.
***************************************************************/
void cleanup(void)
{
tst_rmdir();
}