diff options
author | Vailin Choi <vchoi@hdfgroup.org> | 2013-06-14 20:52:54 (GMT) |
---|---|---|
committer | Vailin Choi <vchoi@hdfgroup.org> | 2013-06-14 20:52:54 (GMT) |
commit | 6e46183e3580866e77bccc2021707ac40d95fa52 (patch) | |
tree | ba7c3159f6113601ef443b664028fe6cfe41588a | |
parent | d01b40e43956e8494b7b536c8cca6246b81fe887 (diff) | |
download | hdf5-6e46183e3580866e77bccc2021707ac40d95fa52.zip hdf5-6e46183e3580866e77bccc2021707ac40d95fa52.tar.gz hdf5-6e46183e3580866e77bccc2021707ac40d95fa52.tar.bz2 |
[svn-r23774] The standalone writer & reader tests that check atomic read-write operation on the system.
-rw-r--r-- | test/Makefile.am | 4 | ||||
-rw-r--r-- | test/Makefile.in | 56 | ||||
-rw-r--r-- | test/atomic_reader.c | 347 | ||||
-rw-r--r-- | test/atomic_writer.c | 230 |
4 files changed, 616 insertions, 21 deletions
diff --git a/test/Makefile.am b/test/Makefile.am index 397d20f..50060eb 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -51,7 +51,7 @@ TEST_PROG= testhdf5 lheap ohdr stab gheap cache cache_api cache_tagging \ bin_PROGRAMS=swmr_generator swmr_reader swmr_writer swmr_remove_reader \ swmr_remove_writer swmr_addrem_writer swmr_sparse_reader swmr_sparse_writer \ - use_append_chunk use_append_mchunks + use_append_chunk use_append_mchunks atomic_writer atomic_reader # List programs to be built when testing here. error_test and err_compat are # built at the same time as the other tests, but executed by testerror.sh. @@ -162,7 +162,7 @@ CHECK_CLEANFILES+=accum.h5 cmpd_dset.h5 compact_dataset.h5 dataset.h5 \ swmr_data.h5 use_append_chunk.h5 use_append_mchunks.h5 \ flushrefresh.h5 flushrefresh_VERIFICATION_START \ flushrefresh_VERIFICATION_CHECKPOINT1 flushrefresh_VERIFICATION_CHECKPOINT2 \ - flushrefresh_VERIFICATION_DONE + flushrefresh_VERIFICATION_DONE atomic_data # Sources for testhdf5 executable testhdf5_SOURCES=testhdf5.c tarray.c tattr.c tchecksum.c tconfig.c tfile.c \ diff --git a/test/Makefile.in b/test/Makefile.in index b45746f..bbe07d5 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -83,7 +83,8 @@ bin_PROGRAMS = swmr_generator$(EXEEXT) swmr_reader$(EXEEXT) \ swmr_writer$(EXEEXT) swmr_remove_reader$(EXEEXT) \ swmr_remove_writer$(EXEEXT) swmr_addrem_writer$(EXEEXT) \ swmr_sparse_reader$(EXEEXT) swmr_sparse_writer$(EXEEXT) \ - use_append_chunk$(EXEEXT) use_append_mchunks$(EXEEXT) + use_append_chunk$(EXEEXT) use_append_mchunks$(EXEEXT) \ + atomic_writer$(EXEEXT) atomic_reader$(EXEEXT) check_PROGRAMS = $(am__EXEEXT_1) error_test$(EXEEXT) \ err_compat$(EXEEXT) tcheck_version$(EXEEXT) testmeta$(EXEEXT) \ links_env$(EXEEXT) flushrefresh$(EXEEXT) $(am__EXEEXT_2) @@ -194,6 +195,14 @@ app_ref_SOURCES = app_ref.c app_ref_OBJECTS = app_ref.$(OBJEXT) app_ref_LDADD = $(LDADD) app_ref_DEPENDENCIES = libh5test.la $(LIBHDF5) +atomic_reader_SOURCES = atomic_reader.c +atomic_reader_OBJECTS = atomic_reader.$(OBJEXT) +atomic_reader_LDADD = $(LDADD) +atomic_reader_DEPENDENCIES = libh5test.la $(LIBHDF5) +atomic_writer_SOURCES = atomic_writer.c +atomic_writer_OBJECTS = atomic_writer.$(OBJEXT) +atomic_writer_LDADD = $(LDADD) +atomic_writer_DEPENDENCIES = libh5test.la $(LIBHDF5) big_SOURCES = big.c big_OBJECTS = big.$(OBJEXT) big_LDADD = $(LDADD) @@ -583,12 +592,12 @@ am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libdynlib1_la_SOURCES) $(libdynlib2_la_SOURCES) \ $(libdynlib3_la_SOURCES) $(libh5test_la_SOURCES) accum.c \ - app_ref.c big.c bittests.c btree2.c cache.c cache_api.c \ - cache_tagging.c cmpd_dset.c cross_read.c dangle.c dsets.c \ - dt_arith.c dtransform.c dtypes.c earray.c efc.c \ - enc_dec_plist.c enc_dec_plist_with_endianess.c enum.c \ - err_compat.c error_test.c extend.c external.c farray.c fheap.c \ - file_image.c fillval.c filter_fail.c flush1.c flush2.c \ + app_ref.c atomic_reader.c atomic_writer.c big.c bittests.c \ + btree2.c cache.c cache_api.c cache_tagging.c cmpd_dset.c \ + cross_read.c dangle.c dsets.c dt_arith.c dtransform.c dtypes.c \ + earray.c efc.c enc_dec_plist.c enc_dec_plist_with_endianess.c \ + enum.c err_compat.c error_test.c extend.c external.c farray.c \ + fheap.c file_image.c fillval.c filter_fail.c flush1.c flush2.c \ flushrefresh.c freespace.c gen_bad_ohdr.c gen_bogus.c \ gen_cross.c gen_deflate.c gen_file_image.c gen_filespace.c \ gen_filters.c gen_idx.c gen_new_array.c gen_new_fill.c \ @@ -606,17 +615,18 @@ SOURCES = $(libdynlib1_la_SOURCES) $(libdynlib2_la_SOURCES) \ DIST_SOURCES = $(am__libdynlib1_la_SOURCES_DIST) \ $(am__libdynlib2_la_SOURCES_DIST) \ $(am__libdynlib3_la_SOURCES_DIST) $(libh5test_la_SOURCES) \ - accum.c app_ref.c big.c bittests.c btree2.c cache.c \ - cache_api.c cache_tagging.c cmpd_dset.c cross_read.c dangle.c \ - dsets.c dt_arith.c dtransform.c dtypes.c earray.c efc.c \ - enc_dec_plist.c enc_dec_plist_with_endianess.c enum.c \ - err_compat.c error_test.c extend.c external.c farray.c fheap.c \ - file_image.c fillval.c filter_fail.c flush1.c flush2.c \ - flushrefresh.c freespace.c gen_bad_ohdr.c gen_bogus.c \ - gen_cross.c gen_deflate.c gen_file_image.c gen_filespace.c \ - gen_filters.c gen_idx.c gen_new_array.c gen_new_fill.c \ - gen_new_group.c gen_new_mtime.c gen_new_super.c \ - gen_noencoder.c gen_nullspace.c gen_plist.c gen_sizes_lheap.c \ + accum.c app_ref.c atomic_reader.c atomic_writer.c big.c \ + bittests.c btree2.c cache.c cache_api.c cache_tagging.c \ + cmpd_dset.c cross_read.c dangle.c dsets.c dt_arith.c \ + dtransform.c dtypes.c earray.c efc.c enc_dec_plist.c \ + enc_dec_plist_with_endianess.c enum.c err_compat.c \ + error_test.c extend.c external.c farray.c fheap.c file_image.c \ + fillval.c filter_fail.c flush1.c flush2.c flushrefresh.c \ + freespace.c gen_bad_ohdr.c gen_bogus.c gen_cross.c \ + gen_deflate.c gen_file_image.c gen_filespace.c gen_filters.c \ + gen_idx.c gen_new_array.c gen_new_fill.c gen_new_group.c \ + gen_new_mtime.c gen_new_super.c gen_noencoder.c \ + gen_nullspace.c gen_plist.c gen_sizes_lheap.c \ gen_specmetaread.c gen_udlinks.c getname.c gheap.c hyperslab.c \ istore.c lheap.c links.c links_env.c mf.c mount.c mtime.c \ ntypes.c objcopy.c ohdr.c plugin.c pool.c reserved.c \ @@ -951,7 +961,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog accum.h5 cmpd_dset.h5 \ flushrefresh.h5 flushrefresh_VERIFICATION_START \ flushrefresh_VERIFICATION_CHECKPOINT1 \ flushrefresh_VERIFICATION_CHECKPOINT2 \ - flushrefresh_VERIFICATION_DONE + flushrefresh_VERIFICATION_DONE atomic_data INCLUDES = -I$(top_srcdir)/src -I$(top_builddir)/src # Test script for error_test and err_compat @@ -1216,6 +1226,12 @@ accum$(EXEEXT): $(accum_OBJECTS) $(accum_DEPENDENCIES) $(EXTRA_accum_DEPENDENCIE app_ref$(EXEEXT): $(app_ref_OBJECTS) $(app_ref_DEPENDENCIES) $(EXTRA_app_ref_DEPENDENCIES) @rm -f app_ref$(EXEEXT) $(AM_V_CCLD)$(LINK) $(app_ref_OBJECTS) $(app_ref_LDADD) $(LIBS) +atomic_reader$(EXEEXT): $(atomic_reader_OBJECTS) $(atomic_reader_DEPENDENCIES) $(EXTRA_atomic_reader_DEPENDENCIES) + @rm -f atomic_reader$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(atomic_reader_OBJECTS) $(atomic_reader_LDADD) $(LIBS) +atomic_writer$(EXEEXT): $(atomic_writer_OBJECTS) $(atomic_writer_DEPENDENCIES) $(EXTRA_atomic_writer_DEPENDENCIES) + @rm -f atomic_writer$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(atomic_writer_OBJECTS) $(atomic_writer_LDADD) $(LIBS) big$(EXEEXT): $(big_OBJECTS) $(big_DEPENDENCIES) $(EXTRA_big_DEPENDENCIES) @rm -f big$(EXEEXT) $(AM_V_CCLD)$(LINK) $(big_OBJECTS) $(big_LDADD) $(LIBS) @@ -1480,6 +1496,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/accum.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/app_ref.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomic_reader.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomic_writer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/big.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bittests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btree2.Po@am__quote@ diff --git a/test/atomic_reader.c b/test/atomic_reader.c new file mode 100644 index 0000000..5d9ea68 --- /dev/null +++ b/test/atomic_reader.c @@ -0,0 +1,347 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/*------------------------------------------------------------------------- + * + * Created: atomic_reader.c + * + * Purpose: This is the "reader" part of the standalone test to check + * atomic read-write operation on a system. + * a) atomic_reader.c--the reader (this file) + * a) atomic_writer.c--the writer + * c) atomic_data--the name of the data file used by writer and reader + * + *------------------------------------------------------------------------- + */ + +/***********/ +/* Headers */ +/***********/ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +/****************/ +/* Local Macros */ +/****************/ + +#define FILENAME "atomic_data" +#define READ_TRIES 20 +#define OPEN_TRIES 50 + +/********************/ +/* Local Prototypes */ +/********************/ + +static void usage(void); +int verify(int fd, unsigned int k); +void print_info(int *info, unsigned int lastr, unsigned iteration); + + + +/*------------------------------------------------------------------------- + * Function: usage + * + * Purpose: To print the command line options + * + * Parameters: None + * + * Return: void + * + *------------------------------------------------------------------------- + */ +static void +usage(void) +{ + printf("\n"); + printf("Usage error!\n"); + printf("Usage: atomic_reader -n <number of integers to read> -i <number of iterations for reader>\n"); + printf(" Note**The number of integers for option n has to be positive\n"); + printf(" Note**The number of integers for option i has to be positive\n"); + printf("\n"); +} /* usage() */ + + +/*------------------------------------------------------------------------- + * Function: verify + * + * Purpose: To verify that the data read is the pattern expected. + * Each integer read should be the same as the index. + * When a difference is encountered, the remaining integers + * read should be the same as the previous index. + * For example, the pattern expected should be either: + * a) 01234567....n-1 + * or + * b) if at index 4, a difference is encountered, + * the remaining integers should be all "3"s as: + * 012333333333333 + * + * Parameters: + * fd--the file descriptor + * k--the number of integers to read + * + * Return: + * positive on success + * negative on failure + * + *------------------------------------------------------------------------- + */ +int +verify(int fd, unsigned int k) +{ + unsigned int i; /* local index variable */ + ssize_t bytes_read; /* the number of bytes read */ + unsigned int *buf = NULL; /* buffer to hold data read */ + + /* Allocate buffer for data read */ + if((buf = (unsigned int *)malloc(k * sizeof(unsigned int))) == NULL) { + printf("READER: error from malloc\n"); + goto error; + } + + /* Position the file at the beginning */ + if(lseek(fd, (off_t)0, SEEK_SET) < 0) { + printf("READER: error from lseek\n"); + goto error; + } + + /* Read the whole file */ + if((bytes_read = read(fd, buf, (k * sizeof(unsigned int)))) < 0) { + printf("READER: error from read\n"); + goto error; + } + + /* Verify the bytes read are correct */ + if(bytes_read != (ssize_t)(k*sizeof(unsigned int))) { + printf("READER: error from bytes read=%lu\n", (unsigned long)bytes_read); + goto error; + } + + /* Verify data read */ + for(i=0; i < k; i++) { + if(buf[i] != i) + break; + } + + if(i < k) { + /* Compare the beginning and ending sentinel values */ + if(buf[k-1] != (i-1)) { + printf("FAIL IN READER: ...beginning sentinel value=%u, i=%u\n", (i-1), i); + printf("FAIL IN READER: buf[%u]=%u\n", i-1, buf[i-1]); + printf("FAIL IN READER: buf[%u]=%u\n", i, buf[i]); + printf("FAIL IN READER: buf[%u]=%u\n", i+1, buf[i+1]); + printf("FAIL IN READER: ...ending sentinel value=%u\n", buf[k-1]); + goto error; + } + } + + /* Free the buffer */ + if(buf) free(buf); + return(0); + +error: + /* Free the buffer */ + if(buf) free(buf); + return(-1); +} /* verify() */ + + + +/*------------------------------------------------------------------------- + * Function: print_info + * + * Purpose: To print the statistics gathered for re-reads + * + * Parameters: + * info--the array storing the statistics for re-reads + * lastr--the last read completed + * iteration--the current iteration + * + * Return: void + * + *------------------------------------------------------------------------- + */ +void +print_info(int *info, unsigned int lastr, unsigned iteration) +{ + unsigned j; /* local index variable */ + + printf("--------statistics for %u reads (iteration %u)--------\n", lastr, iteration); + + for(j = 0; j <= READ_TRIES; j++) + printf("# of %u re-tries = %u\n", j, info[j]); + + printf("--------end statistics for %u reads (iteration %u)--------\n", lastr, iteration); +} /* print_info() */ + + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: To verify that the data read is the pattern expected. + * (1) Make sure the file opens successfully and the # of bytes read is as expected + * (2) Iterate the reader with i iterations + * (3) Read and verify n integers for each iteration + * (4) On verification error, re-read the data at most READ_TRIES + * times to see if correct data can be obtained + * (5) Print out statistics for the number of re-retries for each iteration + * + * Note: + * (a) The # of integers (via -n option) used by the writer and reader should be the same. + * (b) The data file used by the writer and reader should be the same. + * + * Future enhancement: + * 1) Provide default values for n and i and allow user to run with either 0 or 1 option + * 2) Use HDF library HD<system calls> instead of the system calls + * 3) Handle large sized buffer (gigabytes) if needed + * + * Return: Success: 0 + * Failure: -1 + * + *------------------------------------------------------------------------- + */ +int +main(int argc, char *argv[]) +{ + int fd = -1; /* file descriptor */ + unsigned int j=0, i=0, m=0; /* local index variables */ + int temp; /* temporary variable */ + unsigned int iterations = 0; /* the input for "-i" */ + unsigned num = 0; /* the input for "-n" */ + int opt = 0; /* option char */ + int info[READ_TRIES+1]; /* re-tries statistics */ + + /* Ensure the expected # of arguments */ + if(argc != 5) { + usage(); + exit(-1); + } + + /* Parse command line options */ + while((opt = getopt(argc, argv, "n:i:")) != -1) { + switch(opt) { + case 'n': + if((temp = atoi(optarg)) < 0) { + usage(); + exit(-1); + } + num = (unsigned int)temp; + break; + case 'i': + if((temp = atoi(optarg)) < 0) { + usage(); + exit(-1); + } + iterations = (unsigned int)temp; + break; + default: + printf("Invalid option encountered\n"); + break; + } + } + + printf("READER: number of integers to read = %u; # of iterations = %d\n", num, iterations); + + printf("\n"); + for(i = 1; i <= iterations; i++) { /* iteration loop */ + unsigned opens = OPEN_TRIES; + + printf("READER: *****start iteration %u*****\n", i); + + /* Ensure open and file size are done properly */ + while(opens--) { /* open loop */ + struct stat sinfo; + + memset(&sinfo, 0, sizeof(sinfo)); + + if((fd = open(FILENAME, O_RDONLY, 0644)) < 0) { + printf("READER: error from open--retry open again\n"); + } else { + printf("READER: open succeed\n"); + + if((fstat(fd, &sinfo) == 0) && + (sinfo.st_size == (off_t)(num * sizeof(unsigned int)))) { + printf("READER: file size is correct--%u\n", (unsigned int)sinfo.st_size); + break; + } + + printf("READER: error from fstat or file size of %u is incorrect--retry open again\n", (unsigned int)sinfo.st_size); + if(close(fd) < 0) { + printf("READER: error from close\n"); + return(-1); + } + fd = -1; + } + + } /* end while */ + + if(fd < 0) { + printf("READER: *****open failure/incorrect file size for all %u tries, continue next iteration*****\n\n", OPEN_TRIES); + continue; + } + + memset(info, 0, sizeof(info)); + + /* Read and verify data */ + for(j = 1; j <= num; j++) { /* read loop */ + + printf("READER: doing read %u\n", j); + if(verify(fd, num) < 0) { + printf("READER: error from read %u\n", j); + + /* Perform re-read to see if correct data is obtained */ + for(m = 1; m <= READ_TRIES; m++) { /* re-read loop */ + printf("READER: ===============going to do re-read try %u\n", m); + if(verify(fd, num) < 0) + printf("READER: ===============error from re-read try %u\n", m); + else { + ++info[m]; + printf("READER: ===============SUCCESS from re-read try %u\n", m); + break; + } + } /* end for */ + + if(m > READ_TRIES) { + printf("READER: ===============error from all re-read tries: %u\n", READ_TRIES); + printf("READER:*****ERROR--stop on read %u\n", j); + break; + } + } else { + ++info[0]; + printf("READER: success from read %u\n", j); + } + + } /* end for */ + + /* Print the statistics for re-reads */ + print_info(info, j-1, i); + + /* Close the file */ + if(close(fd) < 0) { + printf("READER: error from close\n"); + return(-1); + } + + printf("READER: *****end iteration %u*****\n\n", i); + + } /* end for */ + + return(0); +} diff --git a/test/atomic_writer.c b/test/atomic_writer.c new file mode 100644 index 0000000..9f37ecc --- /dev/null +++ b/test/atomic_writer.c @@ -0,0 +1,230 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: atomic_writer.c + * + * Purpose: This is the "writer" part of the standalone test to check + * atomic read-write operation on a system. + * a) atomic_writer.c--the writer (this file) + * b) atomic_reader.c--the reader + * c) atomic_data--the name of the data file used by writer and reader + * + *------------------------------------------------------------------------- + */ + +/***********/ +/* Headers */ +/***********/ + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <fcntl.h> +#include <unistd.h> +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <errno.h> + +/****************/ +/* Local Macros */ +/****************/ + +#define FILENAME "atomic_data" + +/********************/ +/* Local Prototypes */ +/********************/ + +static void usage(void); + + +/*------------------------------------------------------------------------- + * Function: usage + * + * Purpose: To print information about the command line options + * + * Parameters: None + * + * Return: void + * + *------------------------------------------------------------------------- + */ +static void +usage(void) +{ + printf("\n"); + printf("Usage error!\n"); + printf("Usage: atomic_writer -n <number of integers to write> -i <number of iterations for writer>\n"); + printf(" Note**The number of integers for option n has to be positive\n"); + printf(" Note**The number of integers for option i has to be positive\n"); + printf("\n"); +} /* usage() */ + + + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: To write a series of integers to a file for the reader to verify the data. + * A write is atomic if the whole amount written in one operation is not interleaved + * with data from any other process. + * (1) Iterate with i iterations + * (2) Write a series of integers (0 to n-1) to the file with this pattern: + * offset 0: 0000000000000000000000000000000 + * offset 1: 111111111111111111111111111111 + * offset 2: 22222222222222222222222222222 + * offset 3: 3333333333333333333333333333 + * ... + * ... + * offset n-1: (n-1) + * + * At the end of the writes, the data in the file will be: + * 01234567........(n-1) + * + * Note: + * (a) The # of integers (via -n option) used by the writer and reader should be the same. + * (b) The data file used by the writer and reader should be the same. + * + * Future enhancement: + * 1) Provide default values for n and i and allow user to run with either 0 or 1 option + * 2) Use HDF library HD<system calls> instead of the system calls + * 3) Handle large sized buffer (gigabytes) if needed + * + * Return: Success: 0 + * Failure: -1 + * + *------------------------------------------------------------------------- + */ +int +main(int argc, char *argv[]) +{ + int fd = -1; /* file descriptor */ + ssize_t bytes_wrote; /* the nubmer of bytes written */ + unsigned int *buf = NULL; /* buffer to hold written data */ + unsigned int n, u, i; /* local index variable */ + int temp; /* temporary variable */ + unsigned int iterations = 0; /* the input for "-i" */ + unsigned int num = 0; /* the input for "-n" */ + int opt = 0; /* option char */ + + /* Ensure the # of arguments is as expected */ + if(argc != 5) { + usage(); + exit(-1); + } + + /* Parse command line options */ + while((opt = getopt(argc, argv, "n:i:")) != -1) { + switch(opt) { + case 'n': + if((temp = atoi(optarg)) < 0) { + usage(); + exit(-1); + } + num = (unsigned int)temp; + break; + case 'i': + if((temp = atoi(optarg)) < 0) { + usage(); + exit(-1); + } + iterations = (unsigned int)temp; + break; + default: + printf("Invalid option encountered\n"); + break; + } + } + + printf("WRITER: # of integers to write = %u; # of iterations = %d\n", num, iterations); + + /* Remove existing data file if needed */ + if(remove(FILENAME) < 0) { + if(errno == ENOENT) + printf("WRITER: remove %s--%s\n", FILENAME, strerror(errno)); + else { + printf("WRITER: error from remove: %d--%s\n", errno, strerror(errno)); + goto error; + } + } else + printf("WRITER: %s is removed\n", FILENAME); + + /* Create the data file */ + if((fd = open(FILENAME, O_RDWR|O_TRUNC|O_CREAT, 0664)) < 0) { + printf("WRITER: error from open\n"); + goto error; + } + + /* Allocate buffer for holding data to be written */ + if((buf = (unsigned int *)malloc(num * sizeof(unsigned int))) == NULL) { + printf("WRITER: error from malloc\n"); + if(fd >= 0 && close(fd) < 0) + printf("WRITER: error from close\n"); + goto error; + } + + printf("\n"); + + for(i = 1; i <= iterations; i++) { /* iteration loop */ + printf("WRITER: *****start iteration %u*****\n", i); + + /* Write the series of integers to the file */ + for(n = 0; n < num; n++) { /* write loop */ + + /* Set up data to be written */ + for(u=0; u < num; u++) + buf[u] = n; + + /* Position the file to the proper location */ + if(lseek(fd, (off_t)(n*sizeof(unsigned int)), SEEK_SET) < 0) { + printf("WRITER: error from lseek\n"); + goto error; + } + + /* Write the data */ + if((bytes_wrote = write(fd, buf, ((num-n) * sizeof(unsigned int)))) < 0) { + printf("WRITER: error from write\n"); + goto error; + } + + /* Verify the bytes written is correct */ + if(bytes_wrote != (ssize_t)((num-n) * sizeof(unsigned int))) { + printf("WRITER: error from bytes written\n"); + goto error; + } + } /* end for */ + + printf("WRITER: *****end iteration %u*****\n\n", i); + + } /* end for */ + + /* Close the file */ + if(close(fd) < 0) { + printf("WRITER: error from close\n"); + goto error; + } + + /* Free the buffer */ + if(buf) free(buf); + + return(0); + +error: + return(-1); +} /* main() */ |