1 /* 2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it would be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * 12 * Further, this software is distributed without any warranty that it is 13 * free of the rightful claim of any third person regarding infringement 14 * or the like. Any license provided herein, whether implied or 15 * otherwise, applies only to this software file. Patent licenses, if 16 * any, provided herein do not apply to combinations of this program with 17 * other software, or any other product whatsoever. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write the Free Software Foundation, Inc., 21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 22 * 23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 24 * Mountain View, CA 94043, or: 25 * 26 * http://www.sgi.com 27 * 28 * For further information regarding this notice, see: 29 * 30 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ 31 * 32 */ 33 /* $Id: asyncio02.c,v 1.6 2009/08/28 11:17:39 vapier Exp $ */ 34 /************************************************************ 35 * OS Test - Silicon Graphics, Inc. 36 * Mendota Heights, Minnesota 37 * 38 * TEST IDENTIFIER: aiotcs02: write/close flushes data to the file 39 * 40 * PARENT DOCUMENT: aiotds01: kernel i/o 41 * 42 * AUTHOR: Barrie Kletscher 43 * 44 * CO-PILOT: Dave Baumgartner 45 * 46 * TEST ITEMS: 47 * for each open flags set used: 48 * 1. Multiple writes to a file work as specified for 49 * more than BUFSIZ bytes. 50 * 2. Multiple writes to a file work as specified for 51 * BUFSIZ bytes. 52 * 3. Multiple writes to a file work as specified for 53 * lower than BUFSIZ bytes. 54 * 55 * INPUT SPECIFICATIONS: 56 * Standard parse_opts supported options. 57 *$ 58 * OUTPUT SPECIFICATIONS 59 * Standard tst_res output format 60 * 61 * ENVIRONMENTAL NEEDS: 62 * This program uses the environment variable TMPDIR for the location 63 * of the temporary directory. 64 * 65 * 66 * SPECIAL PROCEDURAL REQUIREMENTS: 67 * The program must be linked with tst_*.o and parse_opts.o. 68 * 69 * INTERCASE DEPENDENCIES: 70 * NONE. 71 * 72 * DETAILED DESCRIPTION: 73 * Attempt to get some memory to work with. 74 * Call testrun writing (BUFSIZ + 1) bytes 75 * Call testrun writing BUFSIZ bytes 76 * Repeated call to testrun() with decreasing write sizes 77 * less than BUFSIZ 78 * End 79 * 80 * Start testrun() 81 * Attempt to open a temporary file. 82 * Write the memory to the file. 83 * Attempt to close the file which also flushes the buffers. 84 * Now check to see if the number of bytes written is the 85 * same as the number of bytes in the file. 86 * Cleanup 87 * 88 * BUGS: 89 * NONE. 90 * 91 ************************************************************/ 92 93 #include <fcntl.h> 94 #include <sys/types.h> 95 #include <sys/stat.h> 96 #include <sys/signal.h> 97 #include <errno.h> 98 #include <stdlib.h> 99 #include "test.h" 100 #include "safe_macros.h" 101 102 #define FLAG O_RDWR | O_CREAT | O_TRUNC /* Flags used when opening temp tile */ 103 #define MODE 0777 /* Mode to open file with */ 104 #define WRITES 10 /* Number of times buffer is written */ 105 #define DECR 1000 /* Number of bytes decremented between */ 106 /* Calls to testrun() */ 107 #define OK -1 /* Return value from testrun() */ 108 109 #define FNAME1 "aio02.1" 110 #define FNAME2 "aio02.2" 111 #define FNAME3 "aio02.3" 112 113 #define ERR_MSG1 "Bytes in file not equal to bytes written." 114 #define ERR_MSG2 "Bytes in file (%d) not equal to bytes written (%d)." 115 116 char *dp; /* pointer to area of memory */ 117 118 void setup(); 119 void cleanup(); 120 int testrun(int flag, int bytes, int ti); 121 122 char *TCID = "asyncio02"; 123 int TST_TOTAL = 6; 124 125 char *filename; /* name of the temporary file */ 126 127 char *Progname; 128 int Open_flags; 129 130 int Flags[] = { 131 O_RDWR | O_CREAT | O_TRUNC, 132 O_RDWR | O_CREAT | O_TRUNC 133 }; 134 135 int Num_flags; 136 137 /*********************************************************************** 138 * MAIN 139 ***********************************************************************/ 140 int main(int ac, char **av) 141 { 142 143 int i; 144 int ret_val; 145 int eok; /* everything is ok flag */ 146 int lc; 147 int flag_cnt; 148 149 Num_flags = sizeof(Flags) / sizeof(int); 150 TST_TOTAL = 3 * Num_flags; 151 152 tst_parse_opts(ac, av, NULL, NULL); 153 154 setup(); 155 156 for (lc = 0; TEST_LOOPING(lc); lc++) { 157 158 tst_count = 0; 159 160 for (flag_cnt = 0; flag_cnt < Num_flags; flag_cnt++) { 161 162 /* 163 * call testrun writing (BUFSIZ + 1) byte chunks 164 */ 165 166 filename = FNAME1; 167 if (testrun(Flags[flag_cnt], BUFSIZ + 1, 1) != OK) { 168 tst_resm(TFAIL, ERR_MSG1); 169 } else { 170 tst_resm(TPASS, 171 "More than BUFSIZE bytes multiple synchronous writes to a file check out ok"); 172 } 173 174 /* 175 * call testrun writing BUFSIZ byte chunks 176 */ 177 178 filename = FNAME2; 179 if (testrun(Flags[flag_cnt], BUFSIZ, 2) != OK) { 180 tst_resm(TFAIL, ERR_MSG1); 181 } else { 182 tst_resm(TPASS, 183 "BUFSIZE bytes multiple synchronous writes to a file checks out ok"); 184 } 185 186 /* 187 * while the byte chunks are greater than 0 188 * call testrun() with decreasing chunk sizes 189 */ 190 191 filename = FNAME3; 192 eok = 1; 193 for (i = BUFSIZ - 1; i >= 0; i -= DECR) { 194 if ((ret_val = 195 testrun(Flags[flag_cnt], i, 3)) != OK) { 196 tst_resm(TFAIL, ERR_MSG2, ret_val, 197 i * WRITES); 198 } 199 } 200 201 if (eok) { 202 tst_resm(TPASS, 203 "Less than BUFSIZE bytes multiple synchronous writes to a file checks out ok"); 204 } 205 } 206 } 207 cleanup(); 208 tst_exit(); 209 } /* end main() */ 210 211 int testrun(int flag, int bytes, int ti) 212 { 213 214 int fildes, i, ret; 215 216 struct stat buffer; /* buffer of memory required for stat command */ 217 218 /* 219 * Attempt to open a temporary file. 220 */ 221 222 if ((fildes = open(filename, flag, MODE)) == -1) { 223 tst_brkm(TBROK | TERRNO, cleanup, "open(%s) failed", filename); 224 } 225 226 /* 227 * Write the memory to the file. 228 */ 229 230 for (i = 0; i < WRITES; i++) { 231 TEST(write(fildes, dp, (unsigned)bytes)); 232 233 if (TEST_RETURN == -1) { 234 tst_brkm(TBROK | TTERRNO, cleanup, "write() failed"); 235 } 236 } /* end for () */ 237 238 /* 239 * Attempt to close the file which also flushes the buffers. 240 */ 241 242 SAFE_CLOSE(cleanup, fildes); 243 244 ret = OK; 245 246 /* 247 * Now check to see if the number of bytes written is the 248 * same as the number of bytes in the file. 249 */ 250 251 SAFE_STAT(cleanup, filename, &buffer); 252 253 if (buffer.st_size != (off_t) (bytes * WRITES)) { 254 ret = (int)buffer.st_size; 255 } 256 257 SAFE_UNLINK(cleanup, filename); 258 259 return ret; 260 261 } /* end testrun() */ 262 263 /*************************************************************** 264 * setup() - performs all ONE TIME setup for this test. 265 ***************************************************************/ 266 void setup(void) 267 { 268 269 tst_sig(FORK, DEF_HANDLER, cleanup); 270 271 TEST_PAUSE; 272 273 /* create a temporary directory and go to it */ 274 tst_tmpdir(); 275 276 /* 277 * Attempt to get some memory to work with. 278 */ 279 280 if ((dp = malloc((unsigned)BUFSIZ + 1)) == NULL) { 281 tst_brkm(TBROK | TERRNO, cleanup, "malloc() failed"); 282 } 283 284 } 285 286 /*************************************************************** 287 * cleanup() - performs all ONE TIME cleanup for this test at 288 * completion or premature exit. 289 ***************************************************************/ 290 void cleanup(void) 291 { 292 293 tst_rmdir(); 294 } 295