blob: 3d99f38b4547fd173805da0b8be7e5fd5e563b7b [file] [log] [blame]
/*
* Copyright 2002 Silicon Graphics, Inc. ALL RIGHTS RESERVED
*
* U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND
*
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the
* Rights in Technical Data and Computer Software clause at DFARS 252.227-7013
* and/or in similar or successor clauses in the FAR, or the DOD or NASA FAR
* Supplement. Unpublished -- rights reserved under the Copyright Laws
* of the United States. Contractor/manufacturer is Silicon Graphics, Inc.,
* 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
*
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SGI
*
* The copyright notice above does not evidence any actual or intended
* publication or disclosure of this source code, which includes information
* that is the confidential and/or proprietary, and is a trade secret,
* of Silicon Graphics, Inc. Any use, duplication or disclosure not
* specifically authorized in writing by Silicon Graphics is strictly
* prohibited. ANY DUPLICATION, MODIFICATION, DISTRIBUTION,PUBLIC PERFORMANCE,
* OR PUBLIC DISPLAY OF THIS SOURCE CODE WITHOUT THE EXPRESS WRITTEN CONSENT
* OF SILICON GRAPHICS, INC. IS STRICTLY PROHIBITED. THE RECEIPT OR POSSESSION
* OF THIS SOURCE CODE AND/OR INFORMATION DOES NOT CONVEY ANY RIGHTS
* TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, OR TO MANUFACTURE, USE,
* OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART.
*/
/* dxm - 28/2/2 */
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
FILE *fp = NULL;
#define LL "ll"
#define PERROR(a,b) perror(a)
#define GET_LAST_ERROR errno
#define HANDLE int
#define INVALID_HANDLE -1
#define TRUNCATE_ERROR -1
#define FLUSH_ERROR EOF
#define FILE_BEGIN SEEK_SET
#define FILE_CURRENT SEEK_CUR
#define OPEN(N, F) open(N, O_CREAT|O_RDWR|F, 0644); fp = fdopen(f, "r+")
#define SEEK(H, O, F) (lseek(H, O, F))
#define READ(H, B, L) (read(H, B, L))
#define WRITE(H, B, L) (write(H, B, L))
#define CLOSE(H) (close(H))
#define DELETE_FILE(F) (unlink(F))
#define FLUSH(F) (fflush(fp))
#define TRUNCATE(F) (ftruncate(F, 0))
#define ALLOC_ALIGNED(S) (memalign(65536, S))
#define FREE_ALIGNED(P) (free(P))
#define DIRECT_IO_FLAG O_DIRECT
enum {
FLAG_OPENCLOSE = 1,
FLAG_READ = 2,
FLAG_WRITE = 4,
FLAG_VERBOSE = 8,
FLAG_TRUNCATE = 16,
FLAG_SEQUENTIAL = 32,
FLAG_FLUSH = 64,
FLAG_DELETE = 128,
FLAG_DIRECT = 256,
};
void
usage(char *argv0)
{
printf(
"Usage: %s [switches] <filename>\n"
" -i <count> = repeat count (default forever)\n"
" -o = open/close\n"
" -r = read\n"
" -w = write\n"
" -t = truncate\n"
" -d = delete\n"
" -b <size> = buffer size\n"
" -v = verbose\n"
" -s = sequential\n"
" -f = flush\n"
" -D = direct-IO\n"
" -h = usage\n",
argv0);
}
extern int optind;
extern char *optarg;
int
main(int argc, char *argv[])
{
HANDLE f = INVALID_HANDLE;
char *filename;
int i;
int c;
int count = -1;
int bufsize = 4096;
int flags = 0;
char *buf = NULL;
int64_t seek_to = 0;
while ((c = getopt(argc, argv, "i:orwb:svthfFDd?")) != EOF) {
switch (c) {
case 'i':
count = atoi(optarg);
break;
case 'o':
flags |= FLAG_OPENCLOSE;
break;
case 'r':
flags |= FLAG_READ;
break;
case 'w':
flags |= FLAG_WRITE;
break;
case 't':
flags |= FLAG_TRUNCATE;
break;
case 'v':
flags |= FLAG_VERBOSE;
break;
case 'b':
bufsize = atoi(optarg);
break;
case 's':
flags |= FLAG_SEQUENTIAL;
break;
case 'f':
flags |= FLAG_FLUSH;
break;
case 'D':
flags |= FLAG_DIRECT;
break;
case 'd':
flags |= FLAG_DELETE;
break;
case '?':
case 'h':
default:
usage(argv[0]);
return 1;
}
}
if (optind != argc - 1) {
usage(argv[0]);
return 1;
}
filename = argv[optind];
if (!flags) {
fprintf(stderr, "nothing to do!\n");
exit(1);
}
if (flags & FLAG_DIRECT)
buf = (char *)ALLOC_ALIGNED(bufsize);
else
buf = (char *)malloc(bufsize);
if (!buf)
PERROR("malloc", GET_LAST_ERROR);
for (i = 0; i < bufsize; i++) {
buf[i] = i & 127;
}
for (i = 0; count < 0 || i < count; i++) {
if ((flags & FLAG_OPENCLOSE) || !i) {
int fileflags;
if (flags & FLAG_VERBOSE)
printf("open %s\n", filename);
fileflags = 0;
if (flags & FLAG_DIRECT)
fileflags |= DIRECT_IO_FLAG;
f = OPEN(filename, fileflags);
if (f == INVALID_HANDLE)
PERROR("OPEN", GET_LAST_ERROR);
}
if ((flags & FLAG_OPENCLOSE) && (flags & FLAG_SEQUENTIAL)) {
if (flags & FLAG_VERBOSE)
printf("seek %" LL "d\n", (long long)seek_to);
if (SEEK(f, seek_to, FILE_BEGIN) < 0)
PERROR("SEEK", GET_LAST_ERROR);
}
if (flags & FLAG_WRITE) {
int sizewritten;
if (!(flags & FLAG_SEQUENTIAL)) {
if (flags & FLAG_VERBOSE)
printf("seek %" LL "d\n", (long long)seek_to);
if (SEEK(f, seek_to, FILE_BEGIN) < 0)
PERROR("SEEK", GET_LAST_ERROR);
}
if (flags & FLAG_VERBOSE)
printf("write %d\n", bufsize);
if ((sizewritten = WRITE(f, buf, bufsize)) != bufsize) {
if (sizewritten < 0)
PERROR("WRITE", GET_LAST_ERROR);
else
fprintf(stderr, "short write: %d of %d\n",
sizewritten, bufsize);
}
}
if (flags & FLAG_READ) {
int sizeread;
if (!(flags & FLAG_SEQUENTIAL) || (flags & FLAG_WRITE)) {
if (flags & FLAG_VERBOSE)
printf("seek %" LL "d\n", (long long)seek_to);
if (SEEK(f, seek_to, FILE_BEGIN) < 0)
PERROR("SEEK", GET_LAST_ERROR);
}
if (flags & FLAG_VERBOSE)
printf("read %d\n", bufsize);
if ((sizeread = READ(f, buf, bufsize)) != bufsize) {
if (sizeread < 0)
PERROR("READ", GET_LAST_ERROR);
else if (sizeread)
fprintf(stderr, "short read: %d of %d\n",
sizeread, bufsize);
else {
fprintf(stderr, "Read past EOF\n");
exit(0);
}
}
}
if (flags & FLAG_TRUNCATE) {
if (flags & FLAG_VERBOSE)
printf("seek 0\n");
if (SEEK(f, 0, FILE_BEGIN) < 0)
PERROR("SEEK", GET_LAST_ERROR);
if (flags & FLAG_VERBOSE)
printf("truncate\n");
if (TRUNCATE(f) == TRUNCATE_ERROR)
PERROR("TRUNCATE", GET_LAST_ERROR);
}
if (flags & FLAG_FLUSH) {
if (flags & FLAG_VERBOSE)
printf("flush\n");
if (FLUSH(f) == FLUSH_ERROR)
PERROR("FLUSH", GET_LAST_ERROR);
}
if (flags & FLAG_SEQUENTIAL) {
seek_to += bufsize;
if (flags & FLAG_TRUNCATE) {
if (flags & FLAG_VERBOSE)
printf("seek %" LL "d\n", (long long)seek_to);
if (SEEK(f, seek_to, FILE_BEGIN) < 0)
PERROR("SEEK", GET_LAST_ERROR);
}
}
if (flags & FLAG_OPENCLOSE) {
if (flags & FLAG_VERBOSE)
printf("close %s\n", filename);
CLOSE(f);
}
if (flags & FLAG_DELETE) {
if (flags & FLAG_VERBOSE)
printf("delete %s\n", filename);
DELETE_FILE(filename);
}
}
if (buf) {
if (flags & FLAG_DIRECT)
FREE_ALIGNED(buf);
else
free(buf);
}
return 0;
}