1/*
2* Disktest
3* Copyright (c) International Business Machines Corp., 2001
4*
5*
6* This program is free software; you can redistribute it and/or modify
7* it under the terms of the GNU General Public License as published by
8* the Free Software Foundation; either version 2 of the License, or
9* (at your option) any later version.
10*
11* This program is distributed in the hope that it will be useful,
12* but WITHOUT ANY WARRANTY; without even the implied warranty of
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14* GNU General Public License for more details.
15*
16* You should have received a copy of the GNU General Public License
17* along with this program; if not, write to the Free Software
18* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19*
20*  Please send e-mail to yardleyb@us.ibm.com if you have
21*  questions or comments.
22*
23*  Project Website:  TBD
24*
25* $Id: io.c,v 1.6 2008/02/14 08:22:23 subrata_modak Exp $
26*
27*/
28
29#ifdef WINDOWS
30#include <windows.h>
31#include <winioctl.h>
32#include <io.h>
33#else
34#include <sys/types.h>
35#include <unistd.h>
36#include <pthread.h>
37#include <fcntl.h>
38#endif
39
40#include "defs.h"
41#include "main.h"
42#include "io.h"
43
44long Write(fd_t fd, const void *buf, const unsigned long trsiz)
45{
46	long tcnt;
47#ifdef WINDOWS
48	WriteFile(fd, buf, trsiz, &tcnt, NULL);
49#else
50	tcnt = write(fd, buf, trsiz);
51#endif
52	return (tcnt);
53}
54
55long Read(fd_t fd, void *buf, const unsigned long trsiz)
56{
57	long tcnt;
58#ifdef WINDOWS
59	ReadFile(fd, buf, trsiz, &tcnt, NULL);
60#else
61	tcnt = read(fd, buf, trsiz);
62#endif
63	return (tcnt);
64}
65
66#ifdef WINDOWS
67/*
68 * wrapper for file seeking in WINDOWS API to hind the ugle 32 bit
69 * interface of SetFile Pointer
70 */
71OFF_T FileSeek64(HANDLE hf, OFF_T distance, DWORD MoveMethod)
72{
73	LARGE_INTEGER li;
74
75	li.QuadPart = distance;
76
77	li.LowPart = SetFilePointer(hf, li.LowPart, &li.HighPart, MoveMethod);
78
79	if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
80		li.QuadPart = -1;
81	}
82
83	return li.QuadPart;
84}
85#endif
86
87OFF_T SeekEnd(fd_t fd)
88{
89	OFF_T return_lba;
90
91#ifdef WINDOWS
92	return_lba = (OFF_T) FileSeek64(fd, 0, FILE_END);
93#else
94	return_lba = (OFF_T) lseek64(fd, 0, SEEK_END);
95#endif
96	return (return_lba);
97}
98
99OFF_T Seek(fd_t fd, OFF_T lba)
100{
101	OFF_T return_lba;
102
103#ifdef WINDOWS
104	return_lba = (OFF_T) FileSeek64(fd, lba, FILE_BEGIN);
105#else
106	return_lba = (OFF_T) lseek64(fd, lba, SEEK_SET);
107#endif
108	return (return_lba);
109}
110
111fd_t Open(const char *filespec, const OFF_T flags)
112{
113	fd_t fd;
114#ifdef WINDOWS
115	unsigned long OPEN_FLAGS = 0, OPEN_DISPO = 0, OPEN_READ_WRITE =
116	    0, OPEN_SHARE = 0;
117
118	if ((flags & CLD_FLG_R) && !(flags & CLD_FLG_W)) {
119		OPEN_READ_WRITE |= GENERIC_READ;
120		OPEN_SHARE |= FILE_SHARE_READ;
121	} else if (!(flags & CLD_FLG_R) && (flags & CLD_FLG_W)) {
122		OPEN_READ_WRITE |= GENERIC_WRITE;
123		OPEN_SHARE |= FILE_SHARE_WRITE;
124	} else {
125		OPEN_READ_WRITE |= (GENERIC_READ | GENERIC_WRITE);
126		OPEN_SHARE |= (FILE_SHARE_READ | FILE_SHARE_WRITE);
127	}
128
129#ifdef CLD_FLG_DIRECT
130	if (flags & CLD_FLG_DIRECT)
131		OPEN_FLAGS = FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
132#endif
133	OPEN_DISPO = OPEN_EXISTING;
134
135#ifdef CLD_FLG_RANDOM
136	if (flags & CLD_FLG_RANDOM)
137		OPEN_FLAGS |= FILE_FLAG_RANDOM_ACCESS;
138#endif
139#ifdef CLD_FLG_LINEAR
140	if (flags & CLD_FLG_LINEAR)
141		OPEN_FLAGS |= FILE_FLAG_SEQUENTIAL_SCAN;
142#endif
143#ifdef CLD_FLG_FILE
144	if (flags & CLD_FLG_FILE) {
145		OPEN_FLAGS |= FILE_ATTRIBUTE_ARCHIVE;
146		if (flags & CLD_FLG_W)
147			OPEN_DISPO = OPEN_ALWAYS;
148	}
149#endif
150	fd = CreateFile(filespec,
151			OPEN_READ_WRITE,
152			OPEN_SHARE, NULL, OPEN_DISPO, OPEN_FLAGS, NULL);
153#else
154	int OPEN_MASK = O_LARGEFILE;
155	if ((flags & CLD_FLG_R) && !(flags & CLD_FLG_W))
156		OPEN_MASK |= O_RDONLY;
157	else if (!(flags & CLD_FLG_R) && (flags & CLD_FLG_W))
158		OPEN_MASK |= O_WRONLY;
159	else
160		OPEN_MASK |= O_RDWR;
161#ifdef CLD_FLG_FILE
162	if (flags & CLD_FLG_FILE)
163		OPEN_MASK |= O_CREAT;
164#endif
165#ifdef CLD_FLG_DIRECT
166	if (flags & CLD_FLG_DIRECT)
167		OPEN_MASK |= O_DIRECT;
168#endif
169	fd = open(filespec, OPEN_MASK, 00600);
170#endif
171	return (fd);
172}
173
174int Sync(fd_t fd)
175{
176#ifdef WINDOWS
177	if (FlushFileBuffers(fd) != TRUE) {
178		return -1;
179	}
180	return 0;
181#else
182	return fsync(fd);
183#endif
184}
185