xref: /aosp_15_r20/external/ltp/lib/tlibio.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
3*49cdfc7eSAndroid Build Coastguard Worker  *
4*49cdfc7eSAndroid Build Coastguard Worker  * This program is free software; you can redistribute it and/or modify it
5*49cdfc7eSAndroid Build Coastguard Worker  * under the terms of version 2 of the GNU General Public License as
6*49cdfc7eSAndroid Build Coastguard Worker  * published by the Free Software Foundation.
7*49cdfc7eSAndroid Build Coastguard Worker  *
8*49cdfc7eSAndroid Build Coastguard Worker  * This program is distributed in the hope that it would be useful, but
9*49cdfc7eSAndroid Build Coastguard Worker  * WITHOUT ANY WARRANTY; without even the implied warranty of
10*49cdfc7eSAndroid Build Coastguard Worker  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11*49cdfc7eSAndroid Build Coastguard Worker  *
12*49cdfc7eSAndroid Build Coastguard Worker  * Further, this software is distributed without any warranty that it is
13*49cdfc7eSAndroid Build Coastguard Worker  * free of the rightful claim of any third person regarding infringement
14*49cdfc7eSAndroid Build Coastguard Worker  * or the like.  Any license provided herein, whether implied or
15*49cdfc7eSAndroid Build Coastguard Worker  * otherwise, applies only to this software file.  Patent licenses, if
16*49cdfc7eSAndroid Build Coastguard Worker  * any, provided herein do not apply to combinations of this program with
17*49cdfc7eSAndroid Build Coastguard Worker  * other software, or any other product whatsoever.
18*49cdfc7eSAndroid Build Coastguard Worker  *
19*49cdfc7eSAndroid Build Coastguard Worker  * You should have received a copy of the GNU General Public License along
20*49cdfc7eSAndroid Build Coastguard Worker  * with this program; if not, write the Free Software Foundation, Inc.,
21*49cdfc7eSAndroid Build Coastguard Worker  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22*49cdfc7eSAndroid Build Coastguard Worker  *
23*49cdfc7eSAndroid Build Coastguard Worker  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24*49cdfc7eSAndroid Build Coastguard Worker  * Mountain View, CA  94043, or:
25*49cdfc7eSAndroid Build Coastguard Worker  *
26*49cdfc7eSAndroid Build Coastguard Worker  * http://www.sgi.com
27*49cdfc7eSAndroid Build Coastguard Worker  *
28*49cdfc7eSAndroid Build Coastguard Worker  * For further information regarding this notice, see:
29*49cdfc7eSAndroid Build Coastguard Worker  *
30*49cdfc7eSAndroid Build Coastguard Worker  * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
31*49cdfc7eSAndroid Build Coastguard Worker  */
32*49cdfc7eSAndroid Build Coastguard Worker /*
33*49cdfc7eSAndroid Build Coastguard Worker  *
34*49cdfc7eSAndroid Build Coastguard Worker  * Lib i/o
35*49cdfc7eSAndroid Build Coastguard Worker  *
36*49cdfc7eSAndroid Build Coastguard Worker  * This file contains several functions to doing reads and writes.
37*49cdfc7eSAndroid Build Coastguard Worker  * It was written so that a single function could be called in a test
38*49cdfc7eSAndroid Build Coastguard Worker  * program and only a io type field value would have to change to
39*49cdfc7eSAndroid Build Coastguard Worker  * do different types of io.  There is even a couple of functions that
40*49cdfc7eSAndroid Build Coastguard Worker  * will allow you to parse a string to determine the iotype.
41*49cdfc7eSAndroid Build Coastguard Worker  *
42*49cdfc7eSAndroid Build Coastguard Worker  * This file contains functions for writing/reading to/from open files
43*49cdfc7eSAndroid Build Coastguard Worker  * Prototypes:
44*49cdfc7eSAndroid Build Coastguard Worker  *
45*49cdfc7eSAndroid Build Coastguard Worker  * Functions declared in this module - see individual function code for
46*49cdfc7eSAndroid Build Coastguard Worker  * usage comments:
47*49cdfc7eSAndroid Build Coastguard Worker  *
48*49cdfc7eSAndroid Build Coastguard Worker  *  int	 stride_bounds(int offset, int stride, int nstrides,
49*49cdfc7eSAndroid Build Coastguard Worker  *		      int bytes_per_stride, int *min, int *max);
50*49cdfc7eSAndroid Build Coastguard Worker 
51*49cdfc7eSAndroid Build Coastguard Worker  *  int  lio_write_buffer(int fd, int method, char *buffer, int size,
52*49cdfc7eSAndroid Build Coastguard Worker  *						char **errmsg, long wrd);
53*49cdfc7eSAndroid Build Coastguard Worker  *  int  lio_read_buffer(int fd, int method, char *buffer, int size,
54*49cdfc7eSAndroid Build Coastguard Worker  *						char **errmsg, long wrd);
55*49cdfc7eSAndroid Build Coastguard Worker  *
56*49cdfc7eSAndroid Build Coastguard Worker  *  #ifdef CRAY
57*49cdfc7eSAndroid Build Coastguard Worker  *  int  lio_wait4asyncio(int method, int fd, struct iosw **statptr)
58*49cdfc7eSAndroid Build Coastguard Worker  *  int  lio_check_asyncio(char *io_type, int size, struct iosw *status)
59*49cdfc7eSAndroid Build Coastguard Worker  *  #endif
60*49cdfc7eSAndroid Build Coastguard Worker  *  #ifdef sgi
61*49cdfc7eSAndroid Build Coastguard Worker  *  int  lio_wait4asyncio(int method, int fd, aiocb_t *aiocbp)
62*49cdfc7eSAndroid Build Coastguard Worker  *  int  lio_check_asyncio(char *io_type, int size, aiocb_t *aiocbp, int method)
63*49cdfc7eSAndroid Build Coastguard Worker  *  #endif
64*49cdfc7eSAndroid Build Coastguard Worker  *
65*49cdfc7eSAndroid Build Coastguard Worker  *  int  lio_parse_io_arg1(char *string)
66*49cdfc7eSAndroid Build Coastguard Worker  *  void lio_help1(char *prefix);
67*49cdfc7eSAndroid Build Coastguard Worker  *
68*49cdfc7eSAndroid Build Coastguard Worker  *  int  lio_parse_io_arg2(char *string, char **badtoken)
69*49cdfc7eSAndroid Build Coastguard Worker  *  void lio_help2(char *prefix);
70*49cdfc7eSAndroid Build Coastguard Worker  *
71*49cdfc7eSAndroid Build Coastguard Worker  *  int  lio_set_debug(int level);
72*49cdfc7eSAndroid Build Coastguard Worker  *
73*49cdfc7eSAndroid Build Coastguard Worker  *  char Lio_SysCall[];
74*49cdfc7eSAndroid Build Coastguard Worker  *  struct lio_info_type Lio_info1[];
75*49cdfc7eSAndroid Build Coastguard Worker  *  struct lio_info_type Lio_info2[];
76*49cdfc7eSAndroid Build Coastguard Worker  *
77*49cdfc7eSAndroid Build Coastguard Worker  *  Author : Richard Logan
78*49cdfc7eSAndroid Build Coastguard Worker  *
79*49cdfc7eSAndroid Build Coastguard Worker  */
80*49cdfc7eSAndroid Build Coastguard Worker 
81*49cdfc7eSAndroid Build Coastguard Worker #ifdef __linux__
82*49cdfc7eSAndroid Build Coastguard Worker #ifndef _GNU_SOURCE
83*49cdfc7eSAndroid Build Coastguard Worker #define _GNU_SOURCE
84*49cdfc7eSAndroid Build Coastguard Worker #endif
85*49cdfc7eSAndroid Build Coastguard Worker #define _LARGEFILE64_SOURCE
86*49cdfc7eSAndroid Build Coastguard Worker #endif
87*49cdfc7eSAndroid Build Coastguard Worker #include "config.h"
88*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
89*49cdfc7eSAndroid Build Coastguard Worker #include <ctype.h>
90*49cdfc7eSAndroid Build Coastguard Worker #include <fcntl.h>
91*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
92*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
93*49cdfc7eSAndroid Build Coastguard Worker #include <sys/stat.h>
94*49cdfc7eSAndroid Build Coastguard Worker #include <sys/time.h>
95*49cdfc7eSAndroid Build Coastguard Worker #include <sys/param.h>
96*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
97*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
98*49cdfc7eSAndroid Build Coastguard Worker #include <sys/file.h>
99*49cdfc7eSAndroid Build Coastguard Worker #include <signal.h>
100*49cdfc7eSAndroid Build Coastguard Worker #include <stdint.h>
101*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
102*49cdfc7eSAndroid Build Coastguard Worker #include <sys/secparm.h>
103*49cdfc7eSAndroid Build Coastguard Worker #include <sys/iosw.h>
104*49cdfc7eSAndroid Build Coastguard Worker #include <sys/listio.h>
105*49cdfc7eSAndroid Build Coastguard Worker #else
106*49cdfc7eSAndroid Build Coastguard Worker /* for linux or sgi */
107*49cdfc7eSAndroid Build Coastguard Worker #include <sys/uio.h>		/* readv(2)/writev(2) */
108*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
109*49cdfc7eSAndroid Build Coastguard Worker #endif
110*49cdfc7eSAndroid Build Coastguard Worker #if defined(__linux__) || defined(__sun) || defined(__hpux) || defined(_AIX)
111*49cdfc7eSAndroid Build Coastguard Worker #ifndef __UCLIBC__
112*49cdfc7eSAndroid Build Coastguard Worker #include <aio.h>
113*49cdfc7eSAndroid Build Coastguard Worker #endif
114*49cdfc7eSAndroid Build Coastguard Worker #endif
115*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>		/* atoi, abs */
116*49cdfc7eSAndroid Build Coastguard Worker 
117*49cdfc7eSAndroid Build Coastguard Worker #include "tlibio.h"		/* defines LIO* macros */
118*49cdfc7eSAndroid Build Coastguard Worker #include "random_range.h"
119*49cdfc7eSAndroid Build Coastguard Worker 
120*49cdfc7eSAndroid Build Coastguard Worker #ifndef PATH_MAX
121*49cdfc7eSAndroid Build Coastguard Worker #define PATH_MAX	MAXPATHLEN
122*49cdfc7eSAndroid Build Coastguard Worker #endif
123*49cdfc7eSAndroid Build Coastguard Worker 
124*49cdfc7eSAndroid Build Coastguard Worker #if 0				/* disabled until it's needed -- roehrich 6/11/97 */
125*49cdfc7eSAndroid Build Coastguard Worker #define BUG1_workaround	1	/* Work around a condition where aio_return gives
126*49cdfc7eSAndroid Build Coastguard Worker 				 * a value of zero but there is no errno followup
127*49cdfc7eSAndroid Build Coastguard Worker 				 * and the read/write operation actually did its
128*49cdfc7eSAndroid Build Coastguard Worker 				 * job.   spr/pv 705244
129*49cdfc7eSAndroid Build Coastguard Worker 				 */
130*49cdfc7eSAndroid Build Coastguard Worker #endif
131*49cdfc7eSAndroid Build Coastguard Worker 
132*49cdfc7eSAndroid Build Coastguard Worker 
133*49cdfc7eSAndroid Build Coastguard Worker /*
134*49cdfc7eSAndroid Build Coastguard Worker  * Define the structure as used in lio_parse_arg1 and lio_help1
135*49cdfc7eSAndroid Build Coastguard Worker  */
136*49cdfc7eSAndroid Build Coastguard Worker struct lio_info_type Lio_info1[] = {
137*49cdfc7eSAndroid Build Coastguard Worker 	{"s", LIO_IO_SYNC, "sync i/o"},
138*49cdfc7eSAndroid Build Coastguard Worker 	{"p", LIO_IO_ASYNC | LIO_WAIT_SIGACTIVE,
139*49cdfc7eSAndroid Build Coastguard Worker 	 "async i/o using a loop to wait for a signal"},
140*49cdfc7eSAndroid Build Coastguard Worker 	{"b", LIO_IO_ASYNC | LIO_WAIT_SIGPAUSE, "async i/o using pause"},
141*49cdfc7eSAndroid Build Coastguard Worker 	{"a", LIO_IO_ASYNC | LIO_WAIT_RECALL,
142*49cdfc7eSAndroid Build Coastguard Worker 	 "async i/o using recall/aio_suspend"},
143*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
144*49cdfc7eSAndroid Build Coastguard Worker 	{"r",
145*49cdfc7eSAndroid Build Coastguard Worker 	 LIO_RANDOM | LIO_IO_TYPES | LIO_WAIT_TYPES,
146*49cdfc7eSAndroid Build Coastguard Worker 	 "random sync i/o types and wait methods"},
147*49cdfc7eSAndroid Build Coastguard Worker 	{"R",
148*49cdfc7eSAndroid Build Coastguard Worker 	 LIO_RANDOM | LIO_IO_ATYPES | LIO_WAIT_ATYPES,
149*49cdfc7eSAndroid Build Coastguard Worker 	 "random i/o types and wait methods"},
150*49cdfc7eSAndroid Build Coastguard Worker #else
151*49cdfc7eSAndroid Build Coastguard Worker 	{"r",
152*49cdfc7eSAndroid Build Coastguard Worker 	 LIO_RANDOM | LIO_IO_TYPES | LIO_WAIT_TYPES,
153*49cdfc7eSAndroid Build Coastguard Worker 	 "random i/o types and wait methods"},
154*49cdfc7eSAndroid Build Coastguard Worker 	{"R",
155*49cdfc7eSAndroid Build Coastguard Worker 	 LIO_RANDOM | LIO_IO_TYPES | LIO_WAIT_TYPES,
156*49cdfc7eSAndroid Build Coastguard Worker 	 "random i/o types and wait methods"},
157*49cdfc7eSAndroid Build Coastguard Worker #endif
158*49cdfc7eSAndroid Build Coastguard Worker 	{"l", LIO_IO_SLISTIO | LIO_WAIT_RECALL, "single stride sync listio"},
159*49cdfc7eSAndroid Build Coastguard Worker 	{"L", LIO_IO_ALISTIO | LIO_WAIT_RECALL,
160*49cdfc7eSAndroid Build Coastguard Worker 	 "single stride async listio using recall"},
161*49cdfc7eSAndroid Build Coastguard Worker 	{"X", LIO_IO_ALISTIO | LIO_WAIT_SIGPAUSE,
162*49cdfc7eSAndroid Build Coastguard Worker 	 "single stride async listio using pause"},
163*49cdfc7eSAndroid Build Coastguard Worker 	{"v", LIO_IO_SYNCV, "single buffer sync readv/writev"},
164*49cdfc7eSAndroid Build Coastguard Worker 	{"P", LIO_IO_SYNCP, "sync pread/pwrite"},
165*49cdfc7eSAndroid Build Coastguard Worker };
166*49cdfc7eSAndroid Build Coastguard Worker 
167*49cdfc7eSAndroid Build Coastguard Worker /*
168*49cdfc7eSAndroid Build Coastguard Worker  * Define the structure used by lio_parse_arg2 and lio_help2
169*49cdfc7eSAndroid Build Coastguard Worker  */
170*49cdfc7eSAndroid Build Coastguard Worker struct lio_info_type Lio_info2[] = {
171*49cdfc7eSAndroid Build Coastguard Worker 	{"sync", LIO_IO_SYNC, "sync i/o (read/write)"},
172*49cdfc7eSAndroid Build Coastguard Worker 	{"async", LIO_IO_ASYNC, "async i/o (reada/writea/aio_read/aio_write)"},
173*49cdfc7eSAndroid Build Coastguard Worker 	{"slistio", LIO_IO_SLISTIO, "single stride sync listio"},
174*49cdfc7eSAndroid Build Coastguard Worker 	{"alistio", LIO_IO_ALISTIO, "single stride async listio"},
175*49cdfc7eSAndroid Build Coastguard Worker 	{"syncv", LIO_IO_SYNCV, "single buffer sync readv/writev"},
176*49cdfc7eSAndroid Build Coastguard Worker 	{"syncp", LIO_IO_SYNCP, "pread/pwrite"},
177*49cdfc7eSAndroid Build Coastguard Worker 	{"active", LIO_WAIT_ACTIVE, "spin on status/control values"},
178*49cdfc7eSAndroid Build Coastguard Worker 	{"recall", LIO_WAIT_RECALL,
179*49cdfc7eSAndroid Build Coastguard Worker 	 "use recall(2)/aio_suspend(3) to wait for i/o to complete"},
180*49cdfc7eSAndroid Build Coastguard Worker 	{"sigactive", LIO_WAIT_SIGACTIVE, "spin waiting for signal"},
181*49cdfc7eSAndroid Build Coastguard Worker 	{"sigpause", LIO_WAIT_SIGPAUSE, "call pause(2) to wait for signal"},
182*49cdfc7eSAndroid Build Coastguard Worker /* nowait is a touchy thing, it's an accident that this implementation worked at all.  6/27/97 roehrich */
183*49cdfc7eSAndroid Build Coastguard Worker /*    { "nowait",    LIO_WAIT_NONE,	"do not wait for async io to complete" },*/
184*49cdfc7eSAndroid Build Coastguard Worker 	{"random", LIO_RANDOM, "set random bit"},
185*49cdfc7eSAndroid Build Coastguard Worker 	{"randomall",
186*49cdfc7eSAndroid Build Coastguard Worker 	 LIO_RANDOM | LIO_IO_TYPES | LIO_WAIT_TYPES,
187*49cdfc7eSAndroid Build Coastguard Worker 	 "all random i/o types and wait methods (except nowait)"},
188*49cdfc7eSAndroid Build Coastguard Worker };
189*49cdfc7eSAndroid Build Coastguard Worker 
190*49cdfc7eSAndroid Build Coastguard Worker char Lio_SysCall[PATH_MAX];	/* string containing last i/o system call */
191*49cdfc7eSAndroid Build Coastguard Worker 
192*49cdfc7eSAndroid Build Coastguard Worker static volatile int Received_signal = 0;	/* number of signals received */
193*49cdfc7eSAndroid Build Coastguard Worker static volatile int Rec_signal;
194*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
195*49cdfc7eSAndroid Build Coastguard Worker static volatile int Received_callback = 0;	/* number of callbacks received */
196*49cdfc7eSAndroid Build Coastguard Worker static volatile int Rec_callback;
197*49cdfc7eSAndroid Build Coastguard Worker #endif
198*49cdfc7eSAndroid Build Coastguard Worker static char Errormsg[PATH_MAX*2];
199*49cdfc7eSAndroid Build Coastguard Worker static int Debug_level = 0;
200*49cdfc7eSAndroid Build Coastguard Worker 
201*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************************
202*49cdfc7eSAndroid Build Coastguard Worker  * stride_bounds()
203*49cdfc7eSAndroid Build Coastguard Worker  *
204*49cdfc7eSAndroid Build Coastguard Worker  * Determine the bounds of a strided request, normalized to offset.  Returns
205*49cdfc7eSAndroid Build Coastguard Worker  * the number of bytes needed to satisfy the request, and optionally sets
206*49cdfc7eSAndroid Build Coastguard Worker  * *min and *max to the mininum and maximum bytes referenced, normalized
207*49cdfc7eSAndroid Build Coastguard Worker  * around offset.
208*49cdfc7eSAndroid Build Coastguard Worker  *
209*49cdfc7eSAndroid Build Coastguard Worker  * Returns -1 on error - the only possible error conditions are illegal values
210*49cdfc7eSAndroid Build Coastguard Worker  * for nstrides and/or bytes_per_stride - both parameters must be >= 0.
211*49cdfc7eSAndroid Build Coastguard Worker  *
212*49cdfc7eSAndroid Build Coastguard Worker  * (maule, 11/16/95)
213*49cdfc7eSAndroid Build Coastguard Worker  ***********************************************************************/
214*49cdfc7eSAndroid Build Coastguard Worker 
stride_bounds(int offset,int stride,int nstrides,int bytes_per_stride,int * min,int * max)215*49cdfc7eSAndroid Build Coastguard Worker int stride_bounds(int offset, int stride, int nstrides, int bytes_per_stride,
216*49cdfc7eSAndroid Build Coastguard Worker 		int *min, int *max)
217*49cdfc7eSAndroid Build Coastguard Worker {
218*49cdfc7eSAndroid Build Coastguard Worker 	int nbytes, min_byte, max_byte;
219*49cdfc7eSAndroid Build Coastguard Worker 
220*49cdfc7eSAndroid Build Coastguard Worker 	/*
221*49cdfc7eSAndroid Build Coastguard Worker 	 * sanity checks ...
222*49cdfc7eSAndroid Build Coastguard Worker 	 */
223*49cdfc7eSAndroid Build Coastguard Worker 
224*49cdfc7eSAndroid Build Coastguard Worker 	if (nstrides < 0 || bytes_per_stride < 0) {
225*49cdfc7eSAndroid Build Coastguard Worker 		return -1;
226*49cdfc7eSAndroid Build Coastguard Worker 	}
227*49cdfc7eSAndroid Build Coastguard Worker 
228*49cdfc7eSAndroid Build Coastguard Worker 	if (stride == 0) {
229*49cdfc7eSAndroid Build Coastguard Worker 		stride = bytes_per_stride;
230*49cdfc7eSAndroid Build Coastguard Worker 	}
231*49cdfc7eSAndroid Build Coastguard Worker 
232*49cdfc7eSAndroid Build Coastguard Worker 	/*
233*49cdfc7eSAndroid Build Coastguard Worker 	 * Determine the # of bytes needed to satisfy the request.  This
234*49cdfc7eSAndroid Build Coastguard Worker 	 * value, along with the offset argument, determines the min and max
235*49cdfc7eSAndroid Build Coastguard Worker 	 * bytes referenced.
236*49cdfc7eSAndroid Build Coastguard Worker 	 */
237*49cdfc7eSAndroid Build Coastguard Worker 
238*49cdfc7eSAndroid Build Coastguard Worker 	nbytes = abs(stride) * (nstrides - 1) + bytes_per_stride;
239*49cdfc7eSAndroid Build Coastguard Worker 
240*49cdfc7eSAndroid Build Coastguard Worker 	if (stride < 0) {
241*49cdfc7eSAndroid Build Coastguard Worker 		max_byte = offset + bytes_per_stride - 1;
242*49cdfc7eSAndroid Build Coastguard Worker 		min_byte = max_byte - nbytes + 1;
243*49cdfc7eSAndroid Build Coastguard Worker 	} else {
244*49cdfc7eSAndroid Build Coastguard Worker 		min_byte = offset;
245*49cdfc7eSAndroid Build Coastguard Worker 		max_byte = min_byte + nbytes - 1;
246*49cdfc7eSAndroid Build Coastguard Worker 	}
247*49cdfc7eSAndroid Build Coastguard Worker 
248*49cdfc7eSAndroid Build Coastguard Worker 	if (min != NULL) {
249*49cdfc7eSAndroid Build Coastguard Worker 		*min = min_byte;
250*49cdfc7eSAndroid Build Coastguard Worker 	}
251*49cdfc7eSAndroid Build Coastguard Worker 
252*49cdfc7eSAndroid Build Coastguard Worker 	if (max != NULL) {
253*49cdfc7eSAndroid Build Coastguard Worker 		*max = max_byte;
254*49cdfc7eSAndroid Build Coastguard Worker 	}
255*49cdfc7eSAndroid Build Coastguard Worker 
256*49cdfc7eSAndroid Build Coastguard Worker 	return nbytes;
257*49cdfc7eSAndroid Build Coastguard Worker }
258*49cdfc7eSAndroid Build Coastguard Worker 
259*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************************
260*49cdfc7eSAndroid Build Coastguard Worker  * This function will allow someone to set the debug level.
261*49cdfc7eSAndroid Build Coastguard Worker  ***********************************************************************/
lio_set_debug(int level)262*49cdfc7eSAndroid Build Coastguard Worker int lio_set_debug(int level)
263*49cdfc7eSAndroid Build Coastguard Worker {
264*49cdfc7eSAndroid Build Coastguard Worker 	int old;
265*49cdfc7eSAndroid Build Coastguard Worker 
266*49cdfc7eSAndroid Build Coastguard Worker 	old = Debug_level;
267*49cdfc7eSAndroid Build Coastguard Worker 	Debug_level = level;
268*49cdfc7eSAndroid Build Coastguard Worker 	return old;
269*49cdfc7eSAndroid Build Coastguard Worker }
270*49cdfc7eSAndroid Build Coastguard Worker 
271*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************************
272*49cdfc7eSAndroid Build Coastguard Worker  * This function will parse a string and return desired io-method.
273*49cdfc7eSAndroid Build Coastguard Worker  * Only the first character of the string is used.
274*49cdfc7eSAndroid Build Coastguard Worker  *
275*49cdfc7eSAndroid Build Coastguard Worker  * This function does not provide for meaningful option arguments,
276*49cdfc7eSAndroid Build Coastguard Worker  * but it supports current growfiles/btlk interface.
277*49cdfc7eSAndroid Build Coastguard Worker  *
278*49cdfc7eSAndroid Build Coastguard Worker  *  (rrl 04/96)
279*49cdfc7eSAndroid Build Coastguard Worker  ***********************************************************************/
lio_parse_io_arg1(char * string)280*49cdfc7eSAndroid Build Coastguard Worker int lio_parse_io_arg1(char *string)
281*49cdfc7eSAndroid Build Coastguard Worker {
282*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int ind;
283*49cdfc7eSAndroid Build Coastguard Worker 	int found = 0;
284*49cdfc7eSAndroid Build Coastguard Worker 	int mask = 0;
285*49cdfc7eSAndroid Build Coastguard Worker 
286*49cdfc7eSAndroid Build Coastguard Worker 	/*
287*49cdfc7eSAndroid Build Coastguard Worker 	 * Determine if token is a valid string.
288*49cdfc7eSAndroid Build Coastguard Worker 	 */
289*49cdfc7eSAndroid Build Coastguard Worker 	for (ind = 0; ind < sizeof(Lio_info1) / sizeof(struct lio_info_type);
290*49cdfc7eSAndroid Build Coastguard Worker 	     ind++) {
291*49cdfc7eSAndroid Build Coastguard Worker 		if (strcmp(string, Lio_info1[ind].token) == 0) {
292*49cdfc7eSAndroid Build Coastguard Worker 			mask |= Lio_info1[ind].bits;
293*49cdfc7eSAndroid Build Coastguard Worker 			found = 1;
294*49cdfc7eSAndroid Build Coastguard Worker 			break;
295*49cdfc7eSAndroid Build Coastguard Worker 		}
296*49cdfc7eSAndroid Build Coastguard Worker 	}
297*49cdfc7eSAndroid Build Coastguard Worker 
298*49cdfc7eSAndroid Build Coastguard Worker 	if (found == 0) {
299*49cdfc7eSAndroid Build Coastguard Worker 		return -1;
300*49cdfc7eSAndroid Build Coastguard Worker 	}
301*49cdfc7eSAndroid Build Coastguard Worker 
302*49cdfc7eSAndroid Build Coastguard Worker 	return mask;
303*49cdfc7eSAndroid Build Coastguard Worker 
304*49cdfc7eSAndroid Build Coastguard Worker }
305*49cdfc7eSAndroid Build Coastguard Worker 
306*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************************
307*49cdfc7eSAndroid Build Coastguard Worker  * This function will print a help message describing the characters
308*49cdfc7eSAndroid Build Coastguard Worker  * that can be parsed by lio_parse_io_arg1().
309*49cdfc7eSAndroid Build Coastguard Worker  * They will be printed one per line.
310*49cdfc7eSAndroid Build Coastguard Worker  *  (rrl 04/96)
311*49cdfc7eSAndroid Build Coastguard Worker  ***********************************************************************/
lio_help1(char * prefix)312*49cdfc7eSAndroid Build Coastguard Worker void lio_help1(char *prefix)
313*49cdfc7eSAndroid Build Coastguard Worker {
314*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int ind;
315*49cdfc7eSAndroid Build Coastguard Worker 
316*49cdfc7eSAndroid Build Coastguard Worker 	for (ind = 0; ind < sizeof(Lio_info1) / sizeof(struct lio_info_type);
317*49cdfc7eSAndroid Build Coastguard Worker 	     ind++) {
318*49cdfc7eSAndroid Build Coastguard Worker 		printf("%s %s : %s\n", prefix, Lio_info1[ind].token,
319*49cdfc7eSAndroid Build Coastguard Worker 		       Lio_info1[ind].desc);
320*49cdfc7eSAndroid Build Coastguard Worker 	}
321*49cdfc7eSAndroid Build Coastguard Worker 
322*49cdfc7eSAndroid Build Coastguard Worker 	return;
323*49cdfc7eSAndroid Build Coastguard Worker }
324*49cdfc7eSAndroid Build Coastguard Worker 
325*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************************
326*49cdfc7eSAndroid Build Coastguard Worker  * This function will parse a string and return the desired io-method.
327*49cdfc7eSAndroid Build Coastguard Worker  * This function will take a comma separated list of io type and wait
328*49cdfc7eSAndroid Build Coastguard Worker  * method tokens as defined in Lio_info2[].  If a token does not match
329*49cdfc7eSAndroid Build Coastguard Worker  * any of the tokens in Lio_info2[], it will be coverted to a number.
330*49cdfc7eSAndroid Build Coastguard Worker  * If it was a number, those bits are also set.
331*49cdfc7eSAndroid Build Coastguard Worker  *
332*49cdfc7eSAndroid Build Coastguard Worker  *  (rrl 04/96)
333*49cdfc7eSAndroid Build Coastguard Worker  ***********************************************************************/
lio_parse_io_arg2(char * string,char ** badtoken)334*49cdfc7eSAndroid Build Coastguard Worker int lio_parse_io_arg2(char *string, char **badtoken)
335*49cdfc7eSAndroid Build Coastguard Worker {
336*49cdfc7eSAndroid Build Coastguard Worker 	char *token = string;
337*49cdfc7eSAndroid Build Coastguard Worker 	char *cc = token;
338*49cdfc7eSAndroid Build Coastguard Worker 	char savecc;
339*49cdfc7eSAndroid Build Coastguard Worker 	int found;
340*49cdfc7eSAndroid Build Coastguard Worker 	int mask = 0;
341*49cdfc7eSAndroid Build Coastguard Worker 
342*49cdfc7eSAndroid Build Coastguard Worker 	int tmp;
343*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int ind;
344*49cdfc7eSAndroid Build Coastguard Worker 	char chr;
345*49cdfc7eSAndroid Build Coastguard Worker 
346*49cdfc7eSAndroid Build Coastguard Worker 	if (token == NULL)
347*49cdfc7eSAndroid Build Coastguard Worker 		return -1;
348*49cdfc7eSAndroid Build Coastguard Worker 
349*49cdfc7eSAndroid Build Coastguard Worker 	for (;;) {
350*49cdfc7eSAndroid Build Coastguard Worker 		for (; ((*cc != ',') && (*cc != '\0')); cc++) ;
351*49cdfc7eSAndroid Build Coastguard Worker 		savecc = *cc;
352*49cdfc7eSAndroid Build Coastguard Worker 		*cc = '\0';
353*49cdfc7eSAndroid Build Coastguard Worker 
354*49cdfc7eSAndroid Build Coastguard Worker 		found = 0;
355*49cdfc7eSAndroid Build Coastguard Worker 
356*49cdfc7eSAndroid Build Coastguard Worker 		/*
357*49cdfc7eSAndroid Build Coastguard Worker 		 * Determine if token is a valid string or number and if
358*49cdfc7eSAndroid Build Coastguard Worker 		 * so, add the bits to the mask.
359*49cdfc7eSAndroid Build Coastguard Worker 		 */
360*49cdfc7eSAndroid Build Coastguard Worker 		for (ind = 0;
361*49cdfc7eSAndroid Build Coastguard Worker 		     ind < sizeof(Lio_info2) / sizeof(struct lio_info_type);
362*49cdfc7eSAndroid Build Coastguard Worker 		     ind++) {
363*49cdfc7eSAndroid Build Coastguard Worker 			if (strcmp(token, Lio_info2[ind].token) == 0) {
364*49cdfc7eSAndroid Build Coastguard Worker 				mask |= Lio_info2[ind].bits;
365*49cdfc7eSAndroid Build Coastguard Worker 				found = 1;
366*49cdfc7eSAndroid Build Coastguard Worker 				break;
367*49cdfc7eSAndroid Build Coastguard Worker 			}
368*49cdfc7eSAndroid Build Coastguard Worker 		}
369*49cdfc7eSAndroid Build Coastguard Worker 
370*49cdfc7eSAndroid Build Coastguard Worker 		/*
371*49cdfc7eSAndroid Build Coastguard Worker 		 * If token does not match one of the defined tokens, determine
372*49cdfc7eSAndroid Build Coastguard Worker 		 * if it is a number, if so, add the bits.
373*49cdfc7eSAndroid Build Coastguard Worker 		 */
374*49cdfc7eSAndroid Build Coastguard Worker 		if (!found) {
375*49cdfc7eSAndroid Build Coastguard Worker 			if (sscanf(token, "%i%c", &tmp, &chr) == 1) {
376*49cdfc7eSAndroid Build Coastguard Worker 				mask |= tmp;
377*49cdfc7eSAndroid Build Coastguard Worker 				found = 1;
378*49cdfc7eSAndroid Build Coastguard Worker 			}
379*49cdfc7eSAndroid Build Coastguard Worker 		}
380*49cdfc7eSAndroid Build Coastguard Worker 
381*49cdfc7eSAndroid Build Coastguard Worker 		*cc = savecc;
382*49cdfc7eSAndroid Build Coastguard Worker 
383*49cdfc7eSAndroid Build Coastguard Worker 		if (!found) {	/* token is not valid */
384*49cdfc7eSAndroid Build Coastguard Worker 			if (badtoken != NULL)
385*49cdfc7eSAndroid Build Coastguard Worker 				*badtoken = token;
386*49cdfc7eSAndroid Build Coastguard Worker 			return (-1);
387*49cdfc7eSAndroid Build Coastguard Worker 		}
388*49cdfc7eSAndroid Build Coastguard Worker 
389*49cdfc7eSAndroid Build Coastguard Worker 		if (savecc == '\0')
390*49cdfc7eSAndroid Build Coastguard Worker 			break;
391*49cdfc7eSAndroid Build Coastguard Worker 
392*49cdfc7eSAndroid Build Coastguard Worker 		token = ++cc;
393*49cdfc7eSAndroid Build Coastguard Worker 	}
394*49cdfc7eSAndroid Build Coastguard Worker 
395*49cdfc7eSAndroid Build Coastguard Worker 	return mask;
396*49cdfc7eSAndroid Build Coastguard Worker }
397*49cdfc7eSAndroid Build Coastguard Worker 
398*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************************
399*49cdfc7eSAndroid Build Coastguard Worker  * This function will print a help message describing the tokens
400*49cdfc7eSAndroid Build Coastguard Worker  * that can be parsed by lio_parse_io_arg2().
401*49cdfc7eSAndroid Build Coastguard Worker  * It will print them one per line.
402*49cdfc7eSAndroid Build Coastguard Worker  *
403*49cdfc7eSAndroid Build Coastguard Worker  * (rrl 04/96)
404*49cdfc7eSAndroid Build Coastguard Worker  ***********************************************************************/
lio_help2(char * prefix)405*49cdfc7eSAndroid Build Coastguard Worker void lio_help2(char *prefix)
406*49cdfc7eSAndroid Build Coastguard Worker {
407*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int ind;
408*49cdfc7eSAndroid Build Coastguard Worker 
409*49cdfc7eSAndroid Build Coastguard Worker 	for (ind = 0; ind < sizeof(Lio_info2) / sizeof(struct lio_info_type);
410*49cdfc7eSAndroid Build Coastguard Worker 	     ind++) {
411*49cdfc7eSAndroid Build Coastguard Worker 		printf("%s %s : %s\n", prefix, Lio_info2[ind].token,
412*49cdfc7eSAndroid Build Coastguard Worker 		       Lio_info2[ind].desc);
413*49cdfc7eSAndroid Build Coastguard Worker 	}
414*49cdfc7eSAndroid Build Coastguard Worker 	return;
415*49cdfc7eSAndroid Build Coastguard Worker }
416*49cdfc7eSAndroid Build Coastguard Worker 
417*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************************
418*49cdfc7eSAndroid Build Coastguard Worker  * This is an internal signal handler.
419*49cdfc7eSAndroid Build Coastguard Worker  * If the handler is called, it will increment the Received_signal
420*49cdfc7eSAndroid Build Coastguard Worker  * global variable.
421*49cdfc7eSAndroid Build Coastguard Worker  ***********************************************************************/
lio_async_signal_handler(int sig)422*49cdfc7eSAndroid Build Coastguard Worker static void lio_async_signal_handler(int sig)
423*49cdfc7eSAndroid Build Coastguard Worker {
424*49cdfc7eSAndroid Build Coastguard Worker 	if (Debug_level)
425*49cdfc7eSAndroid Build Coastguard Worker 		printf
426*49cdfc7eSAndroid Build Coastguard Worker 		    ("DEBUG %s/%d: received signal %d, a signal caught %d times\n",
427*49cdfc7eSAndroid Build Coastguard Worker 		     __FILE__, __LINE__, sig, Received_signal + 1);
428*49cdfc7eSAndroid Build Coastguard Worker 
429*49cdfc7eSAndroid Build Coastguard Worker 	Received_signal++;
430*49cdfc7eSAndroid Build Coastguard Worker 
431*49cdfc7eSAndroid Build Coastguard Worker 	return;
432*49cdfc7eSAndroid Build Coastguard Worker }
433*49cdfc7eSAndroid Build Coastguard Worker 
434*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
435*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************************
436*49cdfc7eSAndroid Build Coastguard Worker  * This is an internal callback handler.
437*49cdfc7eSAndroid Build Coastguard Worker  * If the handler is called, it will increment the Received_callback
438*49cdfc7eSAndroid Build Coastguard Worker  * global variable.
439*49cdfc7eSAndroid Build Coastguard Worker  ***********************************************************************/
lio_async_callback_handler(union sigval sigval)440*49cdfc7eSAndroid Build Coastguard Worker static void lio_async_callback_handler(union sigval sigval)
441*49cdfc7eSAndroid Build Coastguard Worker {
442*49cdfc7eSAndroid Build Coastguard Worker 	if (Debug_level)
443*49cdfc7eSAndroid Build Coastguard Worker 		printf
444*49cdfc7eSAndroid Build Coastguard Worker 		    ("DEBUG %s/%d: received callback, nbytes=%ld, a callback called %d times\n",
445*49cdfc7eSAndroid Build Coastguard Worker 		     __FILE__, __LINE__, (long)sigval.sival_int,
446*49cdfc7eSAndroid Build Coastguard Worker 		     Received_callback + 1);
447*49cdfc7eSAndroid Build Coastguard Worker 
448*49cdfc7eSAndroid Build Coastguard Worker 	Received_callback++;
449*49cdfc7eSAndroid Build Coastguard Worker 
450*49cdfc7eSAndroid Build Coastguard Worker 	return;
451*49cdfc7eSAndroid Build Coastguard Worker }
452*49cdfc7eSAndroid Build Coastguard Worker #endif /* sgi */
453*49cdfc7eSAndroid Build Coastguard Worker 
454*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************************
455*49cdfc7eSAndroid Build Coastguard Worker  * lio_random_methods
456*49cdfc7eSAndroid Build Coastguard Worker  * This function will randomly choose an io type and wait method
457*49cdfc7eSAndroid Build Coastguard Worker  * from set of io types and wait methods.  Since this information
458*49cdfc7eSAndroid Build Coastguard Worker  * is stored in a bitmask, it randomly chooses an io type from
459*49cdfc7eSAndroid Build Coastguard Worker  * the io type bits specified and does the same for wait methods.
460*49cdfc7eSAndroid Build Coastguard Worker  *
461*49cdfc7eSAndroid Build Coastguard Worker  * Return Value
462*49cdfc7eSAndroid Build Coastguard Worker  * This function will return a value with all non choosen io type
463*49cdfc7eSAndroid Build Coastguard Worker  * and wait method bits cleared.  The LIO_RANDOM bit is also
464*49cdfc7eSAndroid Build Coastguard Worker  * cleared.  All other bits are left unchanged.
465*49cdfc7eSAndroid Build Coastguard Worker  *
466*49cdfc7eSAndroid Build Coastguard Worker  * (rrl 04/96)
467*49cdfc7eSAndroid Build Coastguard Worker  ***********************************************************************/
lio_random_methods(long curr_mask)468*49cdfc7eSAndroid Build Coastguard Worker int lio_random_methods(long curr_mask)
469*49cdfc7eSAndroid Build Coastguard Worker {
470*49cdfc7eSAndroid Build Coastguard Worker 	int mask = 0;
471*49cdfc7eSAndroid Build Coastguard Worker 
472*49cdfc7eSAndroid Build Coastguard Worker 	/* remove random select, io type, and wait method bits from curr_mask */
473*49cdfc7eSAndroid Build Coastguard Worker 	mask = curr_mask & (~(LIO_IO_TYPES | LIO_WAIT_TYPES | LIO_RANDOM));
474*49cdfc7eSAndroid Build Coastguard Worker 
475*49cdfc7eSAndroid Build Coastguard Worker 	/* randomly select io type from specified io types */
476*49cdfc7eSAndroid Build Coastguard Worker 	mask = mask | random_bit(curr_mask & LIO_IO_TYPES);
477*49cdfc7eSAndroid Build Coastguard Worker 
478*49cdfc7eSAndroid Build Coastguard Worker 	/* randomly select wait methods  from specified wait methods */
479*49cdfc7eSAndroid Build Coastguard Worker 	mask = mask | random_bit(curr_mask & LIO_WAIT_TYPES);
480*49cdfc7eSAndroid Build Coastguard Worker 
481*49cdfc7eSAndroid Build Coastguard Worker 	return mask;
482*49cdfc7eSAndroid Build Coastguard Worker }
483*49cdfc7eSAndroid Build Coastguard Worker 
wait4sync_io(int fd,int read)484*49cdfc7eSAndroid Build Coastguard Worker static void wait4sync_io(int fd, int read)
485*49cdfc7eSAndroid Build Coastguard Worker {
486*49cdfc7eSAndroid Build Coastguard Worker 	fd_set s;
487*49cdfc7eSAndroid Build Coastguard Worker 	FD_ZERO(&s);
488*49cdfc7eSAndroid Build Coastguard Worker 	FD_SET(fd, &s);
489*49cdfc7eSAndroid Build Coastguard Worker 
490*49cdfc7eSAndroid Build Coastguard Worker 	select(fd + 1, read ? &s : NULL, read ? NULL : &s, NULL, NULL);
491*49cdfc7eSAndroid Build Coastguard Worker }
492*49cdfc7eSAndroid Build Coastguard Worker 
493*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************************
494*49cdfc7eSAndroid Build Coastguard Worker  * Generic write function
495*49cdfc7eSAndroid Build Coastguard Worker  * This function can be used to do a write using write(2), writea(2),
496*49cdfc7eSAndroid Build Coastguard Worker  * aio_write(3), writev(2), pwrite(2),
497*49cdfc7eSAndroid Build Coastguard Worker  * or single stride listio(2)/lio_listio(3).
498*49cdfc7eSAndroid Build Coastguard Worker  * By setting the desired bits in the method
499*49cdfc7eSAndroid Build Coastguard Worker  * bitmask, the caller can control the type of write and the wait method
500*49cdfc7eSAndroid Build Coastguard Worker  * that will be used.  If no io type bits are set, write will be used.
501*49cdfc7eSAndroid Build Coastguard Worker  *
502*49cdfc7eSAndroid Build Coastguard Worker  * If async io was attempted and no wait method bits are set then the
503*49cdfc7eSAndroid Build Coastguard Worker  * wait method is: recall(2) for writea(2) and listio(2); aio_suspend(3) for
504*49cdfc7eSAndroid Build Coastguard Worker  * aio_write(3) and lio_listio(3).
505*49cdfc7eSAndroid Build Coastguard Worker  *
506*49cdfc7eSAndroid Build Coastguard Worker  * If multiple wait methods are specified,
507*49cdfc7eSAndroid Build Coastguard Worker  * only one wait method will be used. The order is predetermined.
508*49cdfc7eSAndroid Build Coastguard Worker  *
509*49cdfc7eSAndroid Build Coastguard Worker  * If the call specifies a signal and one of the two signal wait methods,
510*49cdfc7eSAndroid Build Coastguard Worker  * a signal handler for the signal is set.  This will reset an already
511*49cdfc7eSAndroid Build Coastguard Worker  * set handler for this signal.
512*49cdfc7eSAndroid Build Coastguard Worker  *
513*49cdfc7eSAndroid Build Coastguard Worker  * If the LIO_RANDOM method bit is set, this function will randomly
514*49cdfc7eSAndroid Build Coastguard Worker  * choose a io type and wait method from bits in the method argument.
515*49cdfc7eSAndroid Build Coastguard Worker  *
516*49cdfc7eSAndroid Build Coastguard Worker  * If an error is encountered, an error message will be generated
517*49cdfc7eSAndroid Build Coastguard Worker  * in a internal static buffer.  If errmsg is not NULL, it will
518*49cdfc7eSAndroid Build Coastguard Worker  * be updated to point to the static buffer, allowing the caller
519*49cdfc7eSAndroid Build Coastguard Worker  * to print the error message.
520*49cdfc7eSAndroid Build Coastguard Worker  *
521*49cdfc7eSAndroid Build Coastguard Worker  * Return Value
522*49cdfc7eSAndroid Build Coastguard Worker  *   If a system call fails, -errno is returned.
523*49cdfc7eSAndroid Build Coastguard Worker  *   If LIO_WAIT_NONE bit is set, the return value is the return value
524*49cdfc7eSAndroid Build Coastguard Worker  *   of the system call.
525*49cdfc7eSAndroid Build Coastguard Worker  *   If the io did not fail, the amount of data written is returned.
526*49cdfc7eSAndroid Build Coastguard Worker  *	If the size the system call say was written is different
527*49cdfc7eSAndroid Build Coastguard Worker  *	then what was asked to be written, errmsg is updated for
528*49cdfc7eSAndroid Build Coastguard Worker  *	this error condition.  The return value is still the amount
529*49cdfc7eSAndroid Build Coastguard Worker  *	the system call says was written.
530*49cdfc7eSAndroid Build Coastguard Worker  *
531*49cdfc7eSAndroid Build Coastguard Worker  * (rrl 04/96)
532*49cdfc7eSAndroid Build Coastguard Worker  ***********************************************************************/
lio_write_buffer(int fd,int method,char * buffer,int size,int sig,char ** errmsg,long wrd)533*49cdfc7eSAndroid Build Coastguard Worker int lio_write_buffer(int fd,		/* open file descriptor */
534*49cdfc7eSAndroid Build Coastguard Worker 		int method,	/* contains io type and wait method bitmask */
535*49cdfc7eSAndroid Build Coastguard Worker 		char *buffer,	/* pointer to buffer */
536*49cdfc7eSAndroid Build Coastguard Worker 		int size,	/* the size of the io */
537*49cdfc7eSAndroid Build Coastguard Worker 		int sig,	/* signal to use if async io */
538*49cdfc7eSAndroid Build Coastguard Worker 		char **errmsg,	/* char pointer that will be updated to point to err message */
539*49cdfc7eSAndroid Build Coastguard Worker 		long wrd)	/* to allow future features, use zero for now */
540*49cdfc7eSAndroid Build Coastguard Worker {
541*49cdfc7eSAndroid Build Coastguard Worker 	int ret = 0;		/* syscall return or used to get random method */
542*49cdfc7eSAndroid Build Coastguard Worker 	/* as we cycle writes in case of partial writes, we have to report up
543*49cdfc7eSAndroid Build Coastguard Worker 	 * total bytes written
544*49cdfc7eSAndroid Build Coastguard Worker 	 */
545*49cdfc7eSAndroid Build Coastguard Worker 	int totally_written = 0;
546*49cdfc7eSAndroid Build Coastguard Worker 	char *io_type;		/* Holds string of type of io */
547*49cdfc7eSAndroid Build Coastguard Worker 	int omethod = method;
548*49cdfc7eSAndroid Build Coastguard Worker 	int listio_cmd;		/* Holds the listio/lio_listio cmd */
549*49cdfc7eSAndroid Build Coastguard Worker #ifdef  CRAY
550*49cdfc7eSAndroid Build Coastguard Worker 	struct listreq request;	/* Used when a listio is wanted */
551*49cdfc7eSAndroid Build Coastguard Worker 	struct iosw status, *statptr[1];
552*49cdfc7eSAndroid Build Coastguard Worker #else
553*49cdfc7eSAndroid Build Coastguard Worker 	/* for linux or sgi */
554*49cdfc7eSAndroid Build Coastguard Worker 	struct iovec iov;	/* iovec for writev(2) */
555*49cdfc7eSAndroid Build Coastguard Worker #endif
556*49cdfc7eSAndroid Build Coastguard Worker #if defined (sgi)
557*49cdfc7eSAndroid Build Coastguard Worker 	aiocb_t aiocbp;		/* POSIX aio control block */
558*49cdfc7eSAndroid Build Coastguard Worker 	aiocb_t *aiolist[1];	/* list of aio control blocks for lio_listio */
559*49cdfc7eSAndroid Build Coastguard Worker 	off64_t poffset;	/* pwrite(2) offset */
560*49cdfc7eSAndroid Build Coastguard Worker #endif
561*49cdfc7eSAndroid Build Coastguard Worker #if defined(__linux__) && !defined(__UCLIBC__)
562*49cdfc7eSAndroid Build Coastguard Worker 	struct aiocb aiocbp;	/* POSIX aio control block */
563*49cdfc7eSAndroid Build Coastguard Worker 	struct aiocb *aiolist[1];	/* list of aio control blocks for lio_listio */
564*49cdfc7eSAndroid Build Coastguard Worker 	off64_t poffset;	/* pwrite(2) offset */
565*49cdfc7eSAndroid Build Coastguard Worker #endif
566*49cdfc7eSAndroid Build Coastguard Worker 	/*
567*49cdfc7eSAndroid Build Coastguard Worker 	 * If LIO_RANDOM bit specified, get new method randomly.
568*49cdfc7eSAndroid Build Coastguard Worker 	 */
569*49cdfc7eSAndroid Build Coastguard Worker 	if (method & LIO_RANDOM) {
570*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level > 3)
571*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: method mask to choose from: %#o\n",
572*49cdfc7eSAndroid Build Coastguard Worker 			       __FILE__, __LINE__, method);
573*49cdfc7eSAndroid Build Coastguard Worker 		method = lio_random_methods(method);
574*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level > 2)
575*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: random chosen method %#o\n",
576*49cdfc7eSAndroid Build Coastguard Worker 			       __FILE__, __LINE__, method);
577*49cdfc7eSAndroid Build Coastguard Worker 	}
578*49cdfc7eSAndroid Build Coastguard Worker 
579*49cdfc7eSAndroid Build Coastguard Worker 	if (errmsg != NULL)
580*49cdfc7eSAndroid Build Coastguard Worker 		*errmsg = Errormsg;
581*49cdfc7eSAndroid Build Coastguard Worker 
582*49cdfc7eSAndroid Build Coastguard Worker 	Rec_signal = Received_signal;	/* get the current number of signals received */
583*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
584*49cdfc7eSAndroid Build Coastguard Worker 	Rec_callback = Received_callback;	/* get the current number of callbacks received */
585*49cdfc7eSAndroid Build Coastguard Worker #endif
586*49cdfc7eSAndroid Build Coastguard Worker 
587*49cdfc7eSAndroid Build Coastguard Worker #ifdef  CRAY
588*49cdfc7eSAndroid Build Coastguard Worker 	memset(&status, 0x00, sizeof(struct iosw));
589*49cdfc7eSAndroid Build Coastguard Worker 	memset(&request, 0x00, sizeof(struct listreq));
590*49cdfc7eSAndroid Build Coastguard Worker 	statptr[0] = &status;
591*49cdfc7eSAndroid Build Coastguard Worker #else
592*49cdfc7eSAndroid Build Coastguard Worker 	/* for linux or sgi */
593*49cdfc7eSAndroid Build Coastguard Worker 	memset(&iov, 0x00, sizeof(struct iovec));
594*49cdfc7eSAndroid Build Coastguard Worker 	iov.iov_base = buffer;
595*49cdfc7eSAndroid Build Coastguard Worker 	iov.iov_len = size;
596*49cdfc7eSAndroid Build Coastguard Worker #endif
597*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
598*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi)
599*49cdfc7eSAndroid Build Coastguard Worker 	memset(&aiocbp, 0x00, sizeof(aiocb_t));
600*49cdfc7eSAndroid Build Coastguard Worker #else
601*49cdfc7eSAndroid Build Coastguard Worker 	memset(&aiocbp, 0x00, sizeof(struct aiocb));
602*49cdfc7eSAndroid Build Coastguard Worker #endif
603*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_fildes = fd;
604*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_nbytes = size;
605*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_buf = buffer;
606*49cdfc7eSAndroid Build Coastguard Worker /*    aiocbp.aio_offset = lseek( fd, 0, SEEK_CUR ); -- set below */
607*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_sigevent.sigev_notify = SIGEV_NONE;
608*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_sigevent.sigev_signo = 0;
609*49cdfc7eSAndroid Build Coastguard Worker #ifdef sgi
610*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_sigevent.sigev_func = NULL;
611*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_sigevent.sigev_value.sival_int = 0;
612*49cdfc7eSAndroid Build Coastguard Worker #elif defined(__linux__) && !defined(__UCLIBC__)
613*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_sigevent.sigev_notify_function = NULL;
614*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_sigevent.sigev_notify_attributes = 0;
615*49cdfc7eSAndroid Build Coastguard Worker #endif
616*49cdfc7eSAndroid Build Coastguard Worker 	aiolist[0] = &aiocbp;
617*49cdfc7eSAndroid Build Coastguard Worker 
618*49cdfc7eSAndroid Build Coastguard Worker 	if ((ret = lseek(fd, 0, SEEK_CUR)) == -1) {
619*49cdfc7eSAndroid Build Coastguard Worker 		ret = 0;
620*49cdfc7eSAndroid Build Coastguard Worker 		/* If there is an error and it is not ESPIPE then kick out the error.
621*49cdfc7eSAndroid Build Coastguard Worker 		 * If the fd is a fifo then we have to make sure that
622*49cdfc7eSAndroid Build Coastguard Worker 		 * lio_random_methods() didn't select pwrite/pread; if it did then
623*49cdfc7eSAndroid Build Coastguard Worker 		 * switch to write/read.
624*49cdfc7eSAndroid Build Coastguard Worker 		 */
625*49cdfc7eSAndroid Build Coastguard Worker 		if (errno == ESPIPE) {
626*49cdfc7eSAndroid Build Coastguard Worker 			if (method & LIO_IO_SYNCP) {
627*49cdfc7eSAndroid Build Coastguard Worker 				if (omethod & LIO_RANDOM) {
628*49cdfc7eSAndroid Build Coastguard Worker 					method &= ~LIO_IO_SYNCP;
629*49cdfc7eSAndroid Build Coastguard Worker 					method |= LIO_IO_SYNC;
630*49cdfc7eSAndroid Build Coastguard Worker 					if (Debug_level > 2)
631*49cdfc7eSAndroid Build Coastguard Worker 						printf
632*49cdfc7eSAndroid Build Coastguard Worker 						    ("DEBUG %s/%d: random chosen method switched to %#o for fifo\n",
633*49cdfc7eSAndroid Build Coastguard Worker 						     __FILE__, __LINE__,
634*49cdfc7eSAndroid Build Coastguard Worker 						     method);
635*49cdfc7eSAndroid Build Coastguard Worker 				} else if (Debug_level) {
636*49cdfc7eSAndroid Build Coastguard Worker 					printf
637*49cdfc7eSAndroid Build Coastguard Worker 					    ("DEBUG %s/%d: pwrite will fail when it writes to a fifo\n",
638*49cdfc7eSAndroid Build Coastguard Worker 					     __FILE__, __LINE__);
639*49cdfc7eSAndroid Build Coastguard Worker 				}
640*49cdfc7eSAndroid Build Coastguard Worker 			}
641*49cdfc7eSAndroid Build Coastguard Worker 			/* else: let it ride */
642*49cdfc7eSAndroid Build Coastguard Worker 		} else {
643*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
644*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d lseek(fd=%d,0,SEEK_CUR) failed, errno=%d  %s",
645*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, fd, errno, strerror(errno));
646*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
647*49cdfc7eSAndroid Build Coastguard Worker 		}
648*49cdfc7eSAndroid Build Coastguard Worker 	}
649*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
650*49cdfc7eSAndroid Build Coastguard Worker 	poffset = (off64_t) ret;
651*49cdfc7eSAndroid Build Coastguard Worker #endif
652*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_offset = ret;
653*49cdfc7eSAndroid Build Coastguard Worker 
654*49cdfc7eSAndroid Build Coastguard Worker #endif
655*49cdfc7eSAndroid Build Coastguard Worker 
656*49cdfc7eSAndroid Build Coastguard Worker 	/*
657*49cdfc7eSAndroid Build Coastguard Worker 	 * If the LIO_USE_SIGNAL bit is not set, only use the signal
658*49cdfc7eSAndroid Build Coastguard Worker 	 * if the LIO_WAIT_SIGPAUSE or the LIO_WAIT_SIGACTIVE bits are bit.
659*49cdfc7eSAndroid Build Coastguard Worker 	 * Otherwise there is not necessary a signal handler to trap
660*49cdfc7eSAndroid Build Coastguard Worker 	 * the signal.
661*49cdfc7eSAndroid Build Coastguard Worker 	 */
662*49cdfc7eSAndroid Build Coastguard Worker 	if (sig && !(method & LIO_USE_SIGNAL) && !(method & LIO_WAIT_SIGTYPES)) {
663*49cdfc7eSAndroid Build Coastguard Worker 
664*49cdfc7eSAndroid Build Coastguard Worker 		sig = 0;	/* ignore signal parameter */
665*49cdfc7eSAndroid Build Coastguard Worker 	}
666*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
667*49cdfc7eSAndroid Build Coastguard Worker 	if (sig && (method & LIO_WAIT_CBTYPES))
668*49cdfc7eSAndroid Build Coastguard Worker 		sig = 0;	/* ignore signal parameter */
669*49cdfc7eSAndroid Build Coastguard Worker #endif
670*49cdfc7eSAndroid Build Coastguard Worker 
671*49cdfc7eSAndroid Build Coastguard Worker 	/*
672*49cdfc7eSAndroid Build Coastguard Worker 	 * only setup signal hander if sig was specified and
673*49cdfc7eSAndroid Build Coastguard Worker 	 * a sig wait method was specified.
674*49cdfc7eSAndroid Build Coastguard Worker 	 * Doing this will change the handler for this signal.  The
675*49cdfc7eSAndroid Build Coastguard Worker 	 * old signal handler will not be restored.
676*49cdfc7eSAndroid Build Coastguard Worker 	 *** restoring the signal handler could be added ***
677*49cdfc7eSAndroid Build Coastguard Worker 	 */
678*49cdfc7eSAndroid Build Coastguard Worker 
679*49cdfc7eSAndroid Build Coastguard Worker 	if (sig && (method & LIO_WAIT_SIGTYPES)) {
680*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
681*49cdfc7eSAndroid Build Coastguard Worker 		sigctl(SCTL_REG, sig, lio_async_signal_handler);
682*49cdfc7eSAndroid Build Coastguard Worker #endif
683*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
684*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
685*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_sigevent.sigev_signo = sig;
686*49cdfc7eSAndroid Build Coastguard Worker 		sigset(sig, lio_async_signal_handler);
687*49cdfc7eSAndroid Build Coastguard Worker #endif /* sgi */
688*49cdfc7eSAndroid Build Coastguard Worker 	}
689*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi)
690*49cdfc7eSAndroid Build Coastguard Worker 	else if (method & LIO_WAIT_CBTYPES) {
691*49cdfc7eSAndroid Build Coastguard Worker 		/* sival_int just has to be something that I can use
692*49cdfc7eSAndroid Build Coastguard Worker 		 * to identify the callback, and "size" happens to be handy...
693*49cdfc7eSAndroid Build Coastguard Worker 		 */
694*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_sigevent.sigev_notify = SIGEV_CALLBACK;
695*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_sigevent.sigev_func = lio_async_callback_handler;
696*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_sigevent.sigev_value.sival_int = size;
697*49cdfc7eSAndroid Build Coastguard Worker 	}
698*49cdfc7eSAndroid Build Coastguard Worker #endif
699*49cdfc7eSAndroid Build Coastguard Worker #if defined(__linux__) && !defined(__UCLIBC__)
700*49cdfc7eSAndroid Build Coastguard Worker 	else if (method & LIO_WAIT_CBTYPES) {
701*49cdfc7eSAndroid Build Coastguard Worker 		/* sival_int just has to be something that I can use
702*49cdfc7eSAndroid Build Coastguard Worker 		 * to identify the callback, and "size" happens to be handy...
703*49cdfc7eSAndroid Build Coastguard Worker 		 */
704*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_sigevent.sigev_notify = SIGEV_THREAD;
705*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_sigevent.sigev_notify_function =
706*49cdfc7eSAndroid Build Coastguard Worker 		    lio_async_callback_handler;
707*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_sigevent.sigev_notify_attributes =
708*49cdfc7eSAndroid Build Coastguard Worker 		    (void *)(uintptr_t) size;
709*49cdfc7eSAndroid Build Coastguard Worker 	}
710*49cdfc7eSAndroid Build Coastguard Worker #endif
711*49cdfc7eSAndroid Build Coastguard Worker 	/*
712*49cdfc7eSAndroid Build Coastguard Worker 	 * Determine the system call that will be called and produce
713*49cdfc7eSAndroid Build Coastguard Worker 	 * the string of the system call and place it in Lio_SysCall.
714*49cdfc7eSAndroid Build Coastguard Worker 	 * Also update the io_type char pointer to give brief description
715*49cdfc7eSAndroid Build Coastguard Worker 	 * of system call.  Execute the system call and check for
716*49cdfc7eSAndroid Build Coastguard Worker 	 * system call failure.  If sync i/o, return the number of
717*49cdfc7eSAndroid Build Coastguard Worker 	 * bytes written/read.
718*49cdfc7eSAndroid Build Coastguard Worker 	 */
719*49cdfc7eSAndroid Build Coastguard Worker 
720*49cdfc7eSAndroid Build Coastguard Worker 	if ((method & LIO_IO_SYNC)
721*49cdfc7eSAndroid Build Coastguard Worker 	    || (method & (LIO_IO_TYPES | LIO_IO_ATYPES)) == 0) {
722*49cdfc7eSAndroid Build Coastguard Worker 		/*
723*49cdfc7eSAndroid Build Coastguard Worker 		 * write(2) is used if LIO_IO_SYNC bit is set or not none
724*49cdfc7eSAndroid Build Coastguard Worker 		 * of the LIO_IO_TYPES bits are set (default).
725*49cdfc7eSAndroid Build Coastguard Worker 		 */
726*49cdfc7eSAndroid Build Coastguard Worker 
727*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall, "write(%d, buf, %d)", fd, size);
728*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "write";
729*49cdfc7eSAndroid Build Coastguard Worker 
730*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
731*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
732*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
733*49cdfc7eSAndroid Build Coastguard Worker 		}
734*49cdfc7eSAndroid Build Coastguard Worker 		while (1) {
735*49cdfc7eSAndroid Build Coastguard Worker 			if (((ret = write(fd, buffer, size)) == -1)
736*49cdfc7eSAndroid Build Coastguard Worker 			    && errno != EAGAIN && errno != EINTR) {
737*49cdfc7eSAndroid Build Coastguard Worker 				sprintf(Errormsg,
738*49cdfc7eSAndroid Build Coastguard Worker 					"%s/%d write(%d, buf, %d) ret:-1, errno=%d %s",
739*49cdfc7eSAndroid Build Coastguard Worker 					__FILE__, __LINE__, fd, size, errno,
740*49cdfc7eSAndroid Build Coastguard Worker 					strerror(errno));
741*49cdfc7eSAndroid Build Coastguard Worker 				return -errno;
742*49cdfc7eSAndroid Build Coastguard Worker 			}
743*49cdfc7eSAndroid Build Coastguard Worker 
744*49cdfc7eSAndroid Build Coastguard Worker 			if (ret != -1) {
745*49cdfc7eSAndroid Build Coastguard Worker 				if (ret != size) {
746*49cdfc7eSAndroid Build Coastguard Worker 					sprintf(Errormsg,
747*49cdfc7eSAndroid Build Coastguard Worker 						"%s/%d write(%d, buf, %d) returned=%d",
748*49cdfc7eSAndroid Build Coastguard Worker 						__FILE__, __LINE__,
749*49cdfc7eSAndroid Build Coastguard Worker 						fd, size, ret);
750*49cdfc7eSAndroid Build Coastguard Worker 					size -= ret;
751*49cdfc7eSAndroid Build Coastguard Worker 					buffer += ret;
752*49cdfc7eSAndroid Build Coastguard Worker 					totally_written += ret;
753*49cdfc7eSAndroid Build Coastguard Worker 				} else {
754*49cdfc7eSAndroid Build Coastguard Worker 					if (Debug_level > 1)
755*49cdfc7eSAndroid Build Coastguard Worker 						printf
756*49cdfc7eSAndroid Build Coastguard Worker 						    ("DEBUG %s/%d: write completed without error (ret %d)\n",
757*49cdfc7eSAndroid Build Coastguard Worker 						     __FILE__, __LINE__, ret);
758*49cdfc7eSAndroid Build Coastguard Worker 
759*49cdfc7eSAndroid Build Coastguard Worker 					return totally_written + ret;
760*49cdfc7eSAndroid Build Coastguard Worker 				}
761*49cdfc7eSAndroid Build Coastguard Worker 			}
762*49cdfc7eSAndroid Build Coastguard Worker 			wait4sync_io(fd, 0);
763*49cdfc7eSAndroid Build Coastguard Worker 		}
764*49cdfc7eSAndroid Build Coastguard Worker 
765*49cdfc7eSAndroid Build Coastguard Worker 	}
766*49cdfc7eSAndroid Build Coastguard Worker 
767*49cdfc7eSAndroid Build Coastguard Worker 	else if (method & LIO_IO_ASYNC) {
768*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
769*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall,
770*49cdfc7eSAndroid Build Coastguard Worker 			"writea(%d, buf, %d, &status, %d)", fd, size, sig);
771*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "writea";
772*49cdfc7eSAndroid Build Coastguard Worker 
773*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
774*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
775*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
776*49cdfc7eSAndroid Build Coastguard Worker 		}
777*49cdfc7eSAndroid Build Coastguard Worker 
778*49cdfc7eSAndroid Build Coastguard Worker 		sigoff();
779*49cdfc7eSAndroid Build Coastguard Worker 		if ((ret = writea(fd, buffer, size, &status, sig)) == -1) {
780*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
781*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d writea(%d, buf, %d, &stat, %d) ret:-1, errno=%d %s",
782*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__,
783*49cdfc7eSAndroid Build Coastguard Worker 				fd, size, sig, errno, strerror(errno));
784*49cdfc7eSAndroid Build Coastguard Worker 			sigon();
785*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
786*49cdfc7eSAndroid Build Coastguard Worker 		}
787*49cdfc7eSAndroid Build Coastguard Worker #endif
788*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
789*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall,
790*49cdfc7eSAndroid Build Coastguard Worker 			"aio_write(fildes=%d, buf, nbytes=%d, signo=%d)", fd,
791*49cdfc7eSAndroid Build Coastguard Worker 			size, sig);
792*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "aio_write";
793*49cdfc7eSAndroid Build Coastguard Worker 
794*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
795*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
796*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
797*49cdfc7eSAndroid Build Coastguard Worker 		}
798*49cdfc7eSAndroid Build Coastguard Worker 
799*49cdfc7eSAndroid Build Coastguard Worker 		if (sig)
800*49cdfc7eSAndroid Build Coastguard Worker 			sighold(sig);
801*49cdfc7eSAndroid Build Coastguard Worker 		if ((ret = aio_write(&aiocbp)) == -1) {
802*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
803*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d aio_write(fildes=%d, buf, nbytes=%d, signo=%d) ret:-1, errno=%d %s",
804*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__,
805*49cdfc7eSAndroid Build Coastguard Worker 				fd, size, sig, errno, strerror(errno));
806*49cdfc7eSAndroid Build Coastguard Worker 			if (sig)
807*49cdfc7eSAndroid Build Coastguard Worker 				sigrelse(sig);
808*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
809*49cdfc7eSAndroid Build Coastguard Worker 		}
810*49cdfc7eSAndroid Build Coastguard Worker #endif
811*49cdfc7eSAndroid Build Coastguard Worker 	}
812*49cdfc7eSAndroid Build Coastguard Worker 	/* LIO_IO_ASYNC */
813*49cdfc7eSAndroid Build Coastguard Worker 	else if (method & LIO_IO_SLISTIO) {
814*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
815*49cdfc7eSAndroid Build Coastguard Worker 		request.li_opcode = LO_WRITE;
816*49cdfc7eSAndroid Build Coastguard Worker 		request.li_fildes = fd;
817*49cdfc7eSAndroid Build Coastguard Worker 		request.li_buf = buffer;
818*49cdfc7eSAndroid Build Coastguard Worker 		request.li_nbyte = size;
819*49cdfc7eSAndroid Build Coastguard Worker 		request.li_status = &status;
820*49cdfc7eSAndroid Build Coastguard Worker 		request.li_signo = sig;
821*49cdfc7eSAndroid Build Coastguard Worker 		request.li_nstride = 0;
822*49cdfc7eSAndroid Build Coastguard Worker 		request.li_filstride = 0;
823*49cdfc7eSAndroid Build Coastguard Worker 		request.li_memstride = 0;
824*49cdfc7eSAndroid Build Coastguard Worker 
825*49cdfc7eSAndroid Build Coastguard Worker 		listio_cmd = LC_WAIT;
826*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "listio(2) sync write";
827*49cdfc7eSAndroid Build Coastguard Worker 
828*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall,
829*49cdfc7eSAndroid Build Coastguard Worker 			"listio(LC_WAIT, &req, 1) LO_WRITE, fd:%d, nbyte:%d",
830*49cdfc7eSAndroid Build Coastguard Worker 			fd, size);
831*49cdfc7eSAndroid Build Coastguard Worker 
832*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
833*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
834*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
835*49cdfc7eSAndroid Build Coastguard Worker 		}
836*49cdfc7eSAndroid Build Coastguard Worker 
837*49cdfc7eSAndroid Build Coastguard Worker 		sigoff();
838*49cdfc7eSAndroid Build Coastguard Worker 		if (listio(listio_cmd, &request, 1) == -1) {
839*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
840*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s",
841*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, Lio_SysCall, fd, size,
842*49cdfc7eSAndroid Build Coastguard Worker 				errno, strerror(errno));
843*49cdfc7eSAndroid Build Coastguard Worker 			sigon();
844*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
845*49cdfc7eSAndroid Build Coastguard Worker 		}
846*49cdfc7eSAndroid Build Coastguard Worker 
847*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level > 1)
848*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s did not return -1\n",
849*49cdfc7eSAndroid Build Coastguard Worker 			       __FILE__, __LINE__, Lio_SysCall);
850*49cdfc7eSAndroid Build Coastguard Worker 
851*49cdfc7eSAndroid Build Coastguard Worker 		ret = lio_check_asyncio(io_type, size, &status);
852*49cdfc7eSAndroid Build Coastguard Worker 		return ret;
853*49cdfc7eSAndroid Build Coastguard Worker 
854*49cdfc7eSAndroid Build Coastguard Worker #endif
855*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
856*49cdfc7eSAndroid Build Coastguard Worker 
857*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_lio_opcode = LIO_WRITE;
858*49cdfc7eSAndroid Build Coastguard Worker 		listio_cmd = LIO_WAIT;
859*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "lio_listio(3) sync write";
860*49cdfc7eSAndroid Build Coastguard Worker 
861*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall,
862*49cdfc7eSAndroid Build Coastguard Worker 			"lio_listio(LIO_WAIT, aiolist, 1, NULL) LIO_WRITE, fd:%d, nbyte:%d, sig:%d",
863*49cdfc7eSAndroid Build Coastguard Worker 			fd, size, sig);
864*49cdfc7eSAndroid Build Coastguard Worker 
865*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
866*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
867*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
868*49cdfc7eSAndroid Build Coastguard Worker 		}
869*49cdfc7eSAndroid Build Coastguard Worker 
870*49cdfc7eSAndroid Build Coastguard Worker 		if (sig)
871*49cdfc7eSAndroid Build Coastguard Worker 			sighold(sig);
872*49cdfc7eSAndroid Build Coastguard Worker 		if (lio_listio(listio_cmd, aiolist, 1, NULL) == -1) {
873*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
874*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s",
875*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, Lio_SysCall, fd, size,
876*49cdfc7eSAndroid Build Coastguard Worker 				errno, strerror(errno));
877*49cdfc7eSAndroid Build Coastguard Worker 			if (sig)
878*49cdfc7eSAndroid Build Coastguard Worker 				sigrelse(sig);
879*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
880*49cdfc7eSAndroid Build Coastguard Worker 		}
881*49cdfc7eSAndroid Build Coastguard Worker 
882*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level > 1)
883*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s did not return -1\n",
884*49cdfc7eSAndroid Build Coastguard Worker 			       __FILE__, __LINE__, Lio_SysCall);
885*49cdfc7eSAndroid Build Coastguard Worker 
886*49cdfc7eSAndroid Build Coastguard Worker 		ret = lio_check_asyncio(io_type, size, &aiocbp, method);
887*49cdfc7eSAndroid Build Coastguard Worker 		return ret;
888*49cdfc7eSAndroid Build Coastguard Worker #endif
889*49cdfc7eSAndroid Build Coastguard Worker 	}
890*49cdfc7eSAndroid Build Coastguard Worker 	/* LIO_IO_SLISTIO */
891*49cdfc7eSAndroid Build Coastguard Worker 	else if (method & LIO_IO_ALISTIO) {
892*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
893*49cdfc7eSAndroid Build Coastguard Worker 		request.li_opcode = LO_WRITE;
894*49cdfc7eSAndroid Build Coastguard Worker 		request.li_fildes = fd;
895*49cdfc7eSAndroid Build Coastguard Worker 		request.li_buf = buffer;
896*49cdfc7eSAndroid Build Coastguard Worker 		request.li_nbyte = size;
897*49cdfc7eSAndroid Build Coastguard Worker 		request.li_status = &status;
898*49cdfc7eSAndroid Build Coastguard Worker 		request.li_signo = sig;
899*49cdfc7eSAndroid Build Coastguard Worker 		request.li_nstride = 0;
900*49cdfc7eSAndroid Build Coastguard Worker 		request.li_filstride = 0;
901*49cdfc7eSAndroid Build Coastguard Worker 		request.li_memstride = 0;
902*49cdfc7eSAndroid Build Coastguard Worker 
903*49cdfc7eSAndroid Build Coastguard Worker 		listio_cmd = LC_START;
904*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "listio(2) async write";
905*49cdfc7eSAndroid Build Coastguard Worker 
906*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall,
907*49cdfc7eSAndroid Build Coastguard Worker 			"listio(LC_START, &req, 1) LO_WRITE, fd:%d, nbyte:%d",
908*49cdfc7eSAndroid Build Coastguard Worker 			fd, size);
909*49cdfc7eSAndroid Build Coastguard Worker 
910*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
911*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
912*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
913*49cdfc7eSAndroid Build Coastguard Worker 		}
914*49cdfc7eSAndroid Build Coastguard Worker 
915*49cdfc7eSAndroid Build Coastguard Worker 		sigoff();
916*49cdfc7eSAndroid Build Coastguard Worker 		if (listio(listio_cmd, &request, 1) == -1) {
917*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
918*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s",
919*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, Lio_SysCall, fd, size,
920*49cdfc7eSAndroid Build Coastguard Worker 				errno, strerror(errno));
921*49cdfc7eSAndroid Build Coastguard Worker 			sigon();
922*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
923*49cdfc7eSAndroid Build Coastguard Worker 		}
924*49cdfc7eSAndroid Build Coastguard Worker #endif
925*49cdfc7eSAndroid Build Coastguard Worker #if defined (sgi) || (defined(__linux__) && !defined(__UCLIBC__))
926*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_lio_opcode = LIO_WRITE;
927*49cdfc7eSAndroid Build Coastguard Worker 		listio_cmd = LIO_NOWAIT;
928*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "lio_listio(3) async write";
929*49cdfc7eSAndroid Build Coastguard Worker 
930*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall,
931*49cdfc7eSAndroid Build Coastguard Worker 			"lio_listio(LIO_NOWAIT, aiolist, 1, NULL) LIO_WRITE, fd:%d, nbyte:%d",
932*49cdfc7eSAndroid Build Coastguard Worker 			fd, size);
933*49cdfc7eSAndroid Build Coastguard Worker 
934*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
935*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
936*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
937*49cdfc7eSAndroid Build Coastguard Worker 		}
938*49cdfc7eSAndroid Build Coastguard Worker 
939*49cdfc7eSAndroid Build Coastguard Worker 		if (sig)
940*49cdfc7eSAndroid Build Coastguard Worker 			sighold(sig);
941*49cdfc7eSAndroid Build Coastguard Worker 		if (lio_listio(listio_cmd, aiolist, 1, NULL) == -1) {
942*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
943*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s",
944*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, Lio_SysCall, fd, size,
945*49cdfc7eSAndroid Build Coastguard Worker 				errno, strerror(errno));
946*49cdfc7eSAndroid Build Coastguard Worker 			if (sig)
947*49cdfc7eSAndroid Build Coastguard Worker 				sigrelse(sig);
948*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
949*49cdfc7eSAndroid Build Coastguard Worker 		}
950*49cdfc7eSAndroid Build Coastguard Worker #endif
951*49cdfc7eSAndroid Build Coastguard Worker 	}
952*49cdfc7eSAndroid Build Coastguard Worker 	/* LIO_IO_ALISTIO */
953*49cdfc7eSAndroid Build Coastguard Worker #ifndef CRAY
954*49cdfc7eSAndroid Build Coastguard Worker 	else if (method & LIO_IO_SYNCV) {
955*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "writev(2)";
956*49cdfc7eSAndroid Build Coastguard Worker 
957*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall, "writev(%d, &iov, 1) nbyte:%d", fd, size);
958*49cdfc7eSAndroid Build Coastguard Worker 
959*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
960*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
961*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
962*49cdfc7eSAndroid Build Coastguard Worker 		}
963*49cdfc7eSAndroid Build Coastguard Worker 		if ((ret = writev(fd, &iov, 1)) == -1) {
964*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
965*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d writev(%d, iov, 1) nbyte:%d ret:-1, errno=%d %s",
966*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, fd, size, errno,
967*49cdfc7eSAndroid Build Coastguard Worker 				strerror(errno));
968*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
969*49cdfc7eSAndroid Build Coastguard Worker 		}
970*49cdfc7eSAndroid Build Coastguard Worker 
971*49cdfc7eSAndroid Build Coastguard Worker 		if (ret != size) {
972*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
973*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d writev(%d, iov, 1) nbyte:%d returned=%d",
974*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, fd, size, ret);
975*49cdfc7eSAndroid Build Coastguard Worker 		} else if (Debug_level > 1)
976*49cdfc7eSAndroid Build Coastguard Worker 			printf
977*49cdfc7eSAndroid Build Coastguard Worker 			    ("DEBUG %s/%d: writev completed without error (ret %d)\n",
978*49cdfc7eSAndroid Build Coastguard Worker 			     __FILE__, __LINE__, ret);
979*49cdfc7eSAndroid Build Coastguard Worker 
980*49cdfc7eSAndroid Build Coastguard Worker 		return ret;
981*49cdfc7eSAndroid Build Coastguard Worker 	}			/* LIO_IO_SYNCV */
982*49cdfc7eSAndroid Build Coastguard Worker #endif
983*49cdfc7eSAndroid Build Coastguard Worker 
984*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
985*49cdfc7eSAndroid Build Coastguard Worker 	else if (method & LIO_IO_SYNCP) {
986*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "pwrite(2)";
987*49cdfc7eSAndroid Build Coastguard Worker 
988*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall,
989*49cdfc7eSAndroid Build Coastguard Worker 			"pwrite(%d, buf, %d, %lld)", fd, size,
990*49cdfc7eSAndroid Build Coastguard Worker 			(long long)poffset);
991*49cdfc7eSAndroid Build Coastguard Worker 
992*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
993*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
994*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
995*49cdfc7eSAndroid Build Coastguard Worker 		}
996*49cdfc7eSAndroid Build Coastguard Worker 		if ((ret = pwrite(fd, buffer, size, poffset)) == -1) {
997*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
998*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d pwrite(%d, buf, %d, %lld) ret:-1, errno=%d %s",
999*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, fd, size,
1000*49cdfc7eSAndroid Build Coastguard Worker 				(long long)poffset, errno, strerror(errno));
1001*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
1002*49cdfc7eSAndroid Build Coastguard Worker 		}
1003*49cdfc7eSAndroid Build Coastguard Worker 
1004*49cdfc7eSAndroid Build Coastguard Worker 		if (ret != size) {
1005*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
1006*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d pwrite(%d, buf, %d, %lld) returned=%d",
1007*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__,
1008*49cdfc7eSAndroid Build Coastguard Worker 				fd, size, (long long)poffset, ret);
1009*49cdfc7eSAndroid Build Coastguard Worker 		} else if (Debug_level > 1)
1010*49cdfc7eSAndroid Build Coastguard Worker 			printf
1011*49cdfc7eSAndroid Build Coastguard Worker 			    ("DEBUG %s/%d: pwrite completed without error (ret %d)\n",
1012*49cdfc7eSAndroid Build Coastguard Worker 			     __FILE__, __LINE__, ret);
1013*49cdfc7eSAndroid Build Coastguard Worker 
1014*49cdfc7eSAndroid Build Coastguard Worker 		return ret;
1015*49cdfc7eSAndroid Build Coastguard Worker 	}			/* LIO_IO_SYNCP */
1016*49cdfc7eSAndroid Build Coastguard Worker #endif
1017*49cdfc7eSAndroid Build Coastguard Worker 
1018*49cdfc7eSAndroid Build Coastguard Worker 	else {
1019*49cdfc7eSAndroid Build Coastguard Worker 		printf("DEBUG %s/%d: No I/O method chosen\n", __FILE__,
1020*49cdfc7eSAndroid Build Coastguard Worker 		       __LINE__);
1021*49cdfc7eSAndroid Build Coastguard Worker 		return -1;
1022*49cdfc7eSAndroid Build Coastguard Worker 	}
1023*49cdfc7eSAndroid Build Coastguard Worker 
1024*49cdfc7eSAndroid Build Coastguard Worker 	/*
1025*49cdfc7eSAndroid Build Coastguard Worker 	 * wait for async io to complete.
1026*49cdfc7eSAndroid Build Coastguard Worker 	 */
1027*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
1028*49cdfc7eSAndroid Build Coastguard Worker 	ret = lio_wait4asyncio(method, fd, statptr);
1029*49cdfc7eSAndroid Build Coastguard Worker #endif
1030*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
1031*49cdfc7eSAndroid Build Coastguard Worker 	ret = lio_wait4asyncio(method, fd, &aiocbp);
1032*49cdfc7eSAndroid Build Coastguard Worker #endif
1033*49cdfc7eSAndroid Build Coastguard Worker 
1034*49cdfc7eSAndroid Build Coastguard Worker 	/*
1035*49cdfc7eSAndroid Build Coastguard Worker 	 * If there was an error waiting for async i/o to complete,
1036*49cdfc7eSAndroid Build Coastguard Worker 	 * return the error value (errno) to the caller.
1037*49cdfc7eSAndroid Build Coastguard Worker 	 * Note: Errormsg should already have been updated.
1038*49cdfc7eSAndroid Build Coastguard Worker 	 */
1039*49cdfc7eSAndroid Build Coastguard Worker 	if (ret < 0) {
1040*49cdfc7eSAndroid Build Coastguard Worker 		return ret;
1041*49cdfc7eSAndroid Build Coastguard Worker 	}
1042*49cdfc7eSAndroid Build Coastguard Worker 
1043*49cdfc7eSAndroid Build Coastguard Worker 	/*
1044*49cdfc7eSAndroid Build Coastguard Worker 	 * If i/o was not waited for (may not have been completed at this time),
1045*49cdfc7eSAndroid Build Coastguard Worker 	 * return the size that was requested.
1046*49cdfc7eSAndroid Build Coastguard Worker 	 */
1047*49cdfc7eSAndroid Build Coastguard Worker 	if (ret == 1)
1048*49cdfc7eSAndroid Build Coastguard Worker 		return size;
1049*49cdfc7eSAndroid Build Coastguard Worker 
1050*49cdfc7eSAndroid Build Coastguard Worker 	/*
1051*49cdfc7eSAndroid Build Coastguard Worker 	 * check that async io was successful.
1052*49cdfc7eSAndroid Build Coastguard Worker 	 * Note:  if the there was an system call failure, -errno
1053*49cdfc7eSAndroid Build Coastguard Worker 	 * was returned and Errormsg should already have been updated.
1054*49cdfc7eSAndroid Build Coastguard Worker 	 * If amount i/o was different than size, Errormsg should already
1055*49cdfc7eSAndroid Build Coastguard Worker 	 * have been updated but the actual i/o size if returned.
1056*49cdfc7eSAndroid Build Coastguard Worker 	 */
1057*49cdfc7eSAndroid Build Coastguard Worker 
1058*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
1059*49cdfc7eSAndroid Build Coastguard Worker 	ret = lio_check_asyncio(io_type, size, &status);
1060*49cdfc7eSAndroid Build Coastguard Worker #endif
1061*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
1062*49cdfc7eSAndroid Build Coastguard Worker 	ret = lio_check_asyncio(io_type, size, &aiocbp, method);
1063*49cdfc7eSAndroid Build Coastguard Worker #endif
1064*49cdfc7eSAndroid Build Coastguard Worker 
1065*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
1066*49cdfc7eSAndroid Build Coastguard Worker }				/* end of lio_write_buffer */
1067*49cdfc7eSAndroid Build Coastguard Worker 
1068*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************************
1069*49cdfc7eSAndroid Build Coastguard Worker  * Generic read function
1070*49cdfc7eSAndroid Build Coastguard Worker  * This function can be used to do a read using read(2), reada(2),
1071*49cdfc7eSAndroid Build Coastguard Worker  * aio_read(3), readv(2), pread(2),
1072*49cdfc7eSAndroid Build Coastguard Worker  * or single stride listio(2)/lio_listio(3).
1073*49cdfc7eSAndroid Build Coastguard Worker  * By setting the desired bits in the method
1074*49cdfc7eSAndroid Build Coastguard Worker  * bitmask, the caller can control the type of read and the wait method
1075*49cdfc7eSAndroid Build Coastguard Worker  * that will be used.  If no io type bits are set, read will be used.
1076*49cdfc7eSAndroid Build Coastguard Worker  *
1077*49cdfc7eSAndroid Build Coastguard Worker  * If async io was attempted and no wait method bits are set then the
1078*49cdfc7eSAndroid Build Coastguard Worker  * wait method is: recall(2) for reada(2) and listio(2); aio_suspend(3) for
1079*49cdfc7eSAndroid Build Coastguard Worker  * aio_read(3) and lio_listio(3).
1080*49cdfc7eSAndroid Build Coastguard Worker  *
1081*49cdfc7eSAndroid Build Coastguard Worker  * If multiple wait methods are specified,
1082*49cdfc7eSAndroid Build Coastguard Worker  * only one wait method will be used. The order is predetermined.
1083*49cdfc7eSAndroid Build Coastguard Worker  *
1084*49cdfc7eSAndroid Build Coastguard Worker  * If the call specifies a signal and one of the two signal wait methods,
1085*49cdfc7eSAndroid Build Coastguard Worker  * a signal handler for the signal is set.  This will reset an already
1086*49cdfc7eSAndroid Build Coastguard Worker  * set handler for this signal.
1087*49cdfc7eSAndroid Build Coastguard Worker  *
1088*49cdfc7eSAndroid Build Coastguard Worker  * If the LIO_RANDOM method bit is set, this function will randomly
1089*49cdfc7eSAndroid Build Coastguard Worker  * choose a io type and wait method from bits in the method argument.
1090*49cdfc7eSAndroid Build Coastguard Worker  *
1091*49cdfc7eSAndroid Build Coastguard Worker  * If an error is encountered, an error message will be generated
1092*49cdfc7eSAndroid Build Coastguard Worker  * in a internal static buffer.  If errmsg is not NULL, it will
1093*49cdfc7eSAndroid Build Coastguard Worker  * be updated to point to the static buffer, allowing the caller
1094*49cdfc7eSAndroid Build Coastguard Worker  * to print the error message.
1095*49cdfc7eSAndroid Build Coastguard Worker  *
1096*49cdfc7eSAndroid Build Coastguard Worker  * Return Value
1097*49cdfc7eSAndroid Build Coastguard Worker  *   If a system call fails, -errno is returned.
1098*49cdfc7eSAndroid Build Coastguard Worker  *   If LIO_WAIT_NONE bit is set, the return value is the return value
1099*49cdfc7eSAndroid Build Coastguard Worker  *   of the system call.
1100*49cdfc7eSAndroid Build Coastguard Worker  *   If the io did not fail, the amount of data written is returned.
1101*49cdfc7eSAndroid Build Coastguard Worker  *	If the size the system call say was written is different
1102*49cdfc7eSAndroid Build Coastguard Worker  *	then what was asked to be written, errmsg is updated for
1103*49cdfc7eSAndroid Build Coastguard Worker  *	this error condition.  The return value is still the amount
1104*49cdfc7eSAndroid Build Coastguard Worker  *	the system call says was written.
1105*49cdfc7eSAndroid Build Coastguard Worker  *
1106*49cdfc7eSAndroid Build Coastguard Worker  * (rrl 04/96)
1107*49cdfc7eSAndroid Build Coastguard Worker  ***********************************************************************/
lio_read_buffer(int fd,int method,char * buffer,int size,int sig,char ** errmsg,long wrd)1108*49cdfc7eSAndroid Build Coastguard Worker int lio_read_buffer(int fd,	/* open file descriptor */
1109*49cdfc7eSAndroid Build Coastguard Worker 		int method,	/* contains io type and wait method bitmask*/
1110*49cdfc7eSAndroid Build Coastguard Worker 		char *buffer,	/* pointer to buffer */
1111*49cdfc7eSAndroid Build Coastguard Worker 		int size,	/* the size of the io */
1112*49cdfc7eSAndroid Build Coastguard Worker 		int sig,	/* signal to use if async io */
1113*49cdfc7eSAndroid Build Coastguard Worker 		char **errmsg,	/* char pointer that will be updated to point to err message */
1114*49cdfc7eSAndroid Build Coastguard Worker 		long wrd)	/* to allow future features, use zero for now */
1115*49cdfc7eSAndroid Build Coastguard Worker {
1116*49cdfc7eSAndroid Build Coastguard Worker 	int ret = 0;		/* syscall return or used to get random method */
1117*49cdfc7eSAndroid Build Coastguard Worker 	/* as we cycle reads in case of partial reads, we have to report up
1118*49cdfc7eSAndroid Build Coastguard Worker 	 * total bytes read
1119*49cdfc7eSAndroid Build Coastguard Worker 	 */
1120*49cdfc7eSAndroid Build Coastguard Worker 	int totally_read = 0;
1121*49cdfc7eSAndroid Build Coastguard Worker 	char *io_type;		/* Holds string of type of io */
1122*49cdfc7eSAndroid Build Coastguard Worker 	int listio_cmd;		/* Holds the listio/lio_listio cmd */
1123*49cdfc7eSAndroid Build Coastguard Worker 	int omethod = method;
1124*49cdfc7eSAndroid Build Coastguard Worker #ifdef  CRAY
1125*49cdfc7eSAndroid Build Coastguard Worker 	struct listreq request;	/* Used when a listio is wanted */
1126*49cdfc7eSAndroid Build Coastguard Worker 	struct iosw status, *statptr[1];
1127*49cdfc7eSAndroid Build Coastguard Worker #else
1128*49cdfc7eSAndroid Build Coastguard Worker 	/* for linux or sgi */
1129*49cdfc7eSAndroid Build Coastguard Worker 	struct iovec iov;	/* iovec for readv(2) */
1130*49cdfc7eSAndroid Build Coastguard Worker #endif
1131*49cdfc7eSAndroid Build Coastguard Worker #ifdef sgi
1132*49cdfc7eSAndroid Build Coastguard Worker 	aiocb_t aiocbp;		/* POSIX aio control block */
1133*49cdfc7eSAndroid Build Coastguard Worker 	aiocb_t *aiolist[1];	/* list of aio control blocks for lio_listio */
1134*49cdfc7eSAndroid Build Coastguard Worker 	off64_t poffset;	/* pread(2) offset */
1135*49cdfc7eSAndroid Build Coastguard Worker #endif
1136*49cdfc7eSAndroid Build Coastguard Worker #if defined (__linux__) && !defined(__UCLIBC__)
1137*49cdfc7eSAndroid Build Coastguard Worker 	struct aiocb aiocbp;	/* POSIX aio control block */
1138*49cdfc7eSAndroid Build Coastguard Worker 	struct aiocb *aiolist[1];	/* list of aio control blocks for lio_listio */
1139*49cdfc7eSAndroid Build Coastguard Worker 	off64_t poffset;	/* pread(2) offset */
1140*49cdfc7eSAndroid Build Coastguard Worker #endif
1141*49cdfc7eSAndroid Build Coastguard Worker 
1142*49cdfc7eSAndroid Build Coastguard Worker 	/*
1143*49cdfc7eSAndroid Build Coastguard Worker 	 * If LIO_RANDOM bit specified, get new method randomly.
1144*49cdfc7eSAndroid Build Coastguard Worker 	 */
1145*49cdfc7eSAndroid Build Coastguard Worker 	if (method & LIO_RANDOM) {
1146*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level > 3)
1147*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: method mask to choose from: %#o\n",
1148*49cdfc7eSAndroid Build Coastguard Worker 			       __FILE__, __LINE__, method);
1149*49cdfc7eSAndroid Build Coastguard Worker 		method = lio_random_methods(method);
1150*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level > 2)
1151*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: random chosen method %#o\n",
1152*49cdfc7eSAndroid Build Coastguard Worker 			       __FILE__, __LINE__, method);
1153*49cdfc7eSAndroid Build Coastguard Worker 	}
1154*49cdfc7eSAndroid Build Coastguard Worker 
1155*49cdfc7eSAndroid Build Coastguard Worker 	if (errmsg != NULL)
1156*49cdfc7eSAndroid Build Coastguard Worker 		*errmsg = Errormsg;
1157*49cdfc7eSAndroid Build Coastguard Worker 
1158*49cdfc7eSAndroid Build Coastguard Worker 	Rec_signal = Received_signal;	/* get the current number of signals received */
1159*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
1160*49cdfc7eSAndroid Build Coastguard Worker 	Rec_callback = Received_callback;	/* get the current number of callbacks received */
1161*49cdfc7eSAndroid Build Coastguard Worker #endif
1162*49cdfc7eSAndroid Build Coastguard Worker 
1163*49cdfc7eSAndroid Build Coastguard Worker #ifdef  CRAY
1164*49cdfc7eSAndroid Build Coastguard Worker 	memset(&status, 0x00, sizeof(struct iosw));
1165*49cdfc7eSAndroid Build Coastguard Worker 	memset(&request, 0x00, sizeof(struct listreq));
1166*49cdfc7eSAndroid Build Coastguard Worker 	statptr[0] = &status;
1167*49cdfc7eSAndroid Build Coastguard Worker #else
1168*49cdfc7eSAndroid Build Coastguard Worker 	/* for linux or sgi */
1169*49cdfc7eSAndroid Build Coastguard Worker 	memset(&iov, 0x00, sizeof(struct iovec));
1170*49cdfc7eSAndroid Build Coastguard Worker 	iov.iov_base = buffer;
1171*49cdfc7eSAndroid Build Coastguard Worker 	iov.iov_len = size;
1172*49cdfc7eSAndroid Build Coastguard Worker #endif
1173*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
1174*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi)
1175*49cdfc7eSAndroid Build Coastguard Worker 	memset(&aiocbp, 0x00, sizeof(aiocb_t));
1176*49cdfc7eSAndroid Build Coastguard Worker #else
1177*49cdfc7eSAndroid Build Coastguard Worker 	memset(&aiocbp, 0x00, sizeof(struct aiocb));
1178*49cdfc7eSAndroid Build Coastguard Worker #endif
1179*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_fildes = fd;
1180*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_nbytes = size;
1181*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_buf = buffer;
1182*49cdfc7eSAndroid Build Coastguard Worker /*    aiocbp.aio_offset = lseek( fd, 0, SEEK_CUR ); -- set below */
1183*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_sigevent.sigev_notify = SIGEV_NONE;
1184*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_sigevent.sigev_signo = 0;
1185*49cdfc7eSAndroid Build Coastguard Worker #ifdef sgi
1186*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_sigevent.sigev_func = NULL;
1187*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_sigevent.sigev_value.sival_int = 0;
1188*49cdfc7eSAndroid Build Coastguard Worker #elif defined(__linux__) && !defined(__UCLIBC__)
1189*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_sigevent.sigev_notify_function = NULL;
1190*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_sigevent.sigev_notify_attributes = 0;
1191*49cdfc7eSAndroid Build Coastguard Worker #endif
1192*49cdfc7eSAndroid Build Coastguard Worker 	aiolist[0] = &aiocbp;
1193*49cdfc7eSAndroid Build Coastguard Worker 
1194*49cdfc7eSAndroid Build Coastguard Worker 	if ((ret = lseek(fd, 0, SEEK_CUR)) == -1) {
1195*49cdfc7eSAndroid Build Coastguard Worker 		ret = 0;
1196*49cdfc7eSAndroid Build Coastguard Worker 		/* If there is an error and it is not ESPIPE then kick out the error.
1197*49cdfc7eSAndroid Build Coastguard Worker 		 * If the fd is a fifo then we have to make sure that
1198*49cdfc7eSAndroid Build Coastguard Worker 		 * lio_random_methods() didn't select pwrite/pread; if it did then
1199*49cdfc7eSAndroid Build Coastguard Worker 		 * switch to write/read.
1200*49cdfc7eSAndroid Build Coastguard Worker 		 */
1201*49cdfc7eSAndroid Build Coastguard Worker 		if (errno == ESPIPE) {
1202*49cdfc7eSAndroid Build Coastguard Worker 			if (method & LIO_IO_SYNCP) {
1203*49cdfc7eSAndroid Build Coastguard Worker 				if (omethod & LIO_RANDOM) {
1204*49cdfc7eSAndroid Build Coastguard Worker 					method &= ~LIO_IO_SYNCP;
1205*49cdfc7eSAndroid Build Coastguard Worker 					method |= LIO_IO_SYNC;
1206*49cdfc7eSAndroid Build Coastguard Worker 					if (Debug_level > 2)
1207*49cdfc7eSAndroid Build Coastguard Worker 						printf
1208*49cdfc7eSAndroid Build Coastguard Worker 						    ("DEBUG %s/%d: random chosen method switched to %#o for fifo\n",
1209*49cdfc7eSAndroid Build Coastguard Worker 						     __FILE__, __LINE__,
1210*49cdfc7eSAndroid Build Coastguard Worker 						     method);
1211*49cdfc7eSAndroid Build Coastguard Worker 				} else if (Debug_level) {
1212*49cdfc7eSAndroid Build Coastguard Worker 					printf
1213*49cdfc7eSAndroid Build Coastguard Worker 					    ("DEBUG %s/%d: pread will fail when it reads from a fifo\n",
1214*49cdfc7eSAndroid Build Coastguard Worker 					     __FILE__, __LINE__);
1215*49cdfc7eSAndroid Build Coastguard Worker 				}
1216*49cdfc7eSAndroid Build Coastguard Worker 			}
1217*49cdfc7eSAndroid Build Coastguard Worker 			/* else: let it ride */
1218*49cdfc7eSAndroid Build Coastguard Worker 		} else {
1219*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
1220*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d lseek(fd=%d,0,SEEK_CUR) failed, errno=%d  %s",
1221*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, fd, errno, strerror(errno));
1222*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
1223*49cdfc7eSAndroid Build Coastguard Worker 		}
1224*49cdfc7eSAndroid Build Coastguard Worker 	}
1225*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
1226*49cdfc7eSAndroid Build Coastguard Worker 	poffset = (off64_t) ret;
1227*49cdfc7eSAndroid Build Coastguard Worker #endif
1228*49cdfc7eSAndroid Build Coastguard Worker 	aiocbp.aio_offset = ret;
1229*49cdfc7eSAndroid Build Coastguard Worker 
1230*49cdfc7eSAndroid Build Coastguard Worker #endif
1231*49cdfc7eSAndroid Build Coastguard Worker 
1232*49cdfc7eSAndroid Build Coastguard Worker 	/*
1233*49cdfc7eSAndroid Build Coastguard Worker 	 * If the LIO_USE_SIGNAL bit is not set, only use the signal
1234*49cdfc7eSAndroid Build Coastguard Worker 	 * if the LIO_WAIT_SIGPAUSE or the LIO_WAIT_SIGACTIVE bits are set.
1235*49cdfc7eSAndroid Build Coastguard Worker 	 * Otherwise there is not necessarily a signal handler to trap
1236*49cdfc7eSAndroid Build Coastguard Worker 	 * the signal.
1237*49cdfc7eSAndroid Build Coastguard Worker 	 */
1238*49cdfc7eSAndroid Build Coastguard Worker 	if (sig && !(method & LIO_USE_SIGNAL) && !(method & LIO_WAIT_SIGTYPES)) {
1239*49cdfc7eSAndroid Build Coastguard Worker 
1240*49cdfc7eSAndroid Build Coastguard Worker 		sig = 0;	/* ignore signal parameter */
1241*49cdfc7eSAndroid Build Coastguard Worker 	}
1242*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__)&& !defined(__UCLIBC__))
1243*49cdfc7eSAndroid Build Coastguard Worker 	if (sig && (method & LIO_WAIT_CBTYPES))
1244*49cdfc7eSAndroid Build Coastguard Worker 		sig = 0;	/* ignore signal parameter */
1245*49cdfc7eSAndroid Build Coastguard Worker #endif
1246*49cdfc7eSAndroid Build Coastguard Worker 
1247*49cdfc7eSAndroid Build Coastguard Worker 	/*
1248*49cdfc7eSAndroid Build Coastguard Worker 	 * only setup signal hander if sig was specified and
1249*49cdfc7eSAndroid Build Coastguard Worker 	 * a sig wait method was specified.
1250*49cdfc7eSAndroid Build Coastguard Worker 	 * Doing this will change the handler for this signal.  The
1251*49cdfc7eSAndroid Build Coastguard Worker 	 * old signal handler will not be restored.
1252*49cdfc7eSAndroid Build Coastguard Worker 	 *** restoring the signal handler could be added ***
1253*49cdfc7eSAndroid Build Coastguard Worker 	 */
1254*49cdfc7eSAndroid Build Coastguard Worker 
1255*49cdfc7eSAndroid Build Coastguard Worker 	if (sig && (method & LIO_WAIT_SIGTYPES)) {
1256*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
1257*49cdfc7eSAndroid Build Coastguard Worker 		sigctl(SCTL_REG, sig, lio_async_signal_handler);
1258*49cdfc7eSAndroid Build Coastguard Worker #endif
1259*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
1260*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
1261*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_sigevent.sigev_signo = sig;
1262*49cdfc7eSAndroid Build Coastguard Worker 		sigset(sig, lio_async_signal_handler);
1263*49cdfc7eSAndroid Build Coastguard Worker #endif /* CRAY */
1264*49cdfc7eSAndroid Build Coastguard Worker 	}
1265*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi)
1266*49cdfc7eSAndroid Build Coastguard Worker 	else if (method & LIO_WAIT_CBTYPES) {
1267*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_sigevent.sigev_notify = SIGEV_CALLBACK;
1268*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_sigevent.sigev_func = lio_async_callback_handler;
1269*49cdfc7eSAndroid Build Coastguard Worker 		/* sival_int just has to be something that I can use
1270*49cdfc7eSAndroid Build Coastguard Worker 		 * to identify the callback, and "size" happens to be handy...
1271*49cdfc7eSAndroid Build Coastguard Worker 		 */
1272*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_sigevent.sigev_value.sival_int = size;
1273*49cdfc7eSAndroid Build Coastguard Worker 	}
1274*49cdfc7eSAndroid Build Coastguard Worker #endif
1275*49cdfc7eSAndroid Build Coastguard Worker #if defined(__linux__) && !defined(__UCLIBC__)
1276*49cdfc7eSAndroid Build Coastguard Worker 	else if (method & LIO_WAIT_CBTYPES) {
1277*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_sigevent.sigev_notify = SIGEV_THREAD;
1278*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_sigevent.sigev_notify_function =
1279*49cdfc7eSAndroid Build Coastguard Worker 		    lio_async_callback_handler;
1280*49cdfc7eSAndroid Build Coastguard Worker 		/* sival_int just has to be something that I can use
1281*49cdfc7eSAndroid Build Coastguard Worker 		 * to identify the callback, and "size" happens to be handy...
1282*49cdfc7eSAndroid Build Coastguard Worker 		 */
1283*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_sigevent.sigev_notify_attributes =
1284*49cdfc7eSAndroid Build Coastguard Worker 		    (void *)(uintptr_t) size;
1285*49cdfc7eSAndroid Build Coastguard Worker 	}
1286*49cdfc7eSAndroid Build Coastguard Worker #endif
1287*49cdfc7eSAndroid Build Coastguard Worker 
1288*49cdfc7eSAndroid Build Coastguard Worker 	/*
1289*49cdfc7eSAndroid Build Coastguard Worker 	 * Determine the system call that will be called and produce
1290*49cdfc7eSAndroid Build Coastguard Worker 	 * the string of the system call and place it in Lio_SysCall.
1291*49cdfc7eSAndroid Build Coastguard Worker 	 * Also update the io_type char pointer to give brief description
1292*49cdfc7eSAndroid Build Coastguard Worker 	 * of system call.  Execute the system call and check for
1293*49cdfc7eSAndroid Build Coastguard Worker 	 * system call failure.  If sync i/o, return the number of
1294*49cdfc7eSAndroid Build Coastguard Worker 	 * bytes written/read.
1295*49cdfc7eSAndroid Build Coastguard Worker 	 */
1296*49cdfc7eSAndroid Build Coastguard Worker 
1297*49cdfc7eSAndroid Build Coastguard Worker 	if ((method & LIO_IO_SYNC)
1298*49cdfc7eSAndroid Build Coastguard Worker 	    || (method & (LIO_IO_TYPES | LIO_IO_ATYPES)) == 0) {
1299*49cdfc7eSAndroid Build Coastguard Worker 		/*
1300*49cdfc7eSAndroid Build Coastguard Worker 		 * read(2) is used if LIO_IO_SYNC bit is set or not none
1301*49cdfc7eSAndroid Build Coastguard Worker 		 * of the LIO_IO_TYPES bits are set (default).
1302*49cdfc7eSAndroid Build Coastguard Worker 		 */
1303*49cdfc7eSAndroid Build Coastguard Worker 
1304*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall, "read(%d, buf, %d)", fd, size);
1305*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "read";
1306*49cdfc7eSAndroid Build Coastguard Worker 
1307*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
1308*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
1309*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
1310*49cdfc7eSAndroid Build Coastguard Worker 		}
1311*49cdfc7eSAndroid Build Coastguard Worker 
1312*49cdfc7eSAndroid Build Coastguard Worker 		while (1) {
1313*49cdfc7eSAndroid Build Coastguard Worker 			if (((ret = read(fd, buffer, size)) == -1)
1314*49cdfc7eSAndroid Build Coastguard Worker 			    && errno != EINTR && errno != EAGAIN) {
1315*49cdfc7eSAndroid Build Coastguard Worker 				sprintf(Errormsg,
1316*49cdfc7eSAndroid Build Coastguard Worker 					"%s/%d read(%d, buf, %d) ret:-1, errno=%d %s",
1317*49cdfc7eSAndroid Build Coastguard Worker 					__FILE__, __LINE__, fd, size, errno,
1318*49cdfc7eSAndroid Build Coastguard Worker 					strerror(errno));
1319*49cdfc7eSAndroid Build Coastguard Worker 				return -errno;
1320*49cdfc7eSAndroid Build Coastguard Worker 			}
1321*49cdfc7eSAndroid Build Coastguard Worker 
1322*49cdfc7eSAndroid Build Coastguard Worker 			if (ret == 0)
1323*49cdfc7eSAndroid Build Coastguard Worker 				return 0;
1324*49cdfc7eSAndroid Build Coastguard Worker 			if (ret != -1) {
1325*49cdfc7eSAndroid Build Coastguard Worker 				if (ret != size) {
1326*49cdfc7eSAndroid Build Coastguard Worker 					sprintf(Errormsg,
1327*49cdfc7eSAndroid Build Coastguard Worker 						"%s/%d read(%d, buf, %d) returned=%d",
1328*49cdfc7eSAndroid Build Coastguard Worker 						__FILE__, __LINE__,
1329*49cdfc7eSAndroid Build Coastguard Worker 						fd, size, ret);
1330*49cdfc7eSAndroid Build Coastguard Worker 					size -= ret;
1331*49cdfc7eSAndroid Build Coastguard Worker 					buffer += ret;
1332*49cdfc7eSAndroid Build Coastguard Worker 					totally_read += ret;
1333*49cdfc7eSAndroid Build Coastguard Worker 				} else {
1334*49cdfc7eSAndroid Build Coastguard Worker 					if (Debug_level > 1)
1335*49cdfc7eSAndroid Build Coastguard Worker 						printf
1336*49cdfc7eSAndroid Build Coastguard Worker 						    ("DEBUG %s/%d: read completed without error (ret %d)\n",
1337*49cdfc7eSAndroid Build Coastguard Worker 						     __FILE__, __LINE__, ret);
1338*49cdfc7eSAndroid Build Coastguard Worker 
1339*49cdfc7eSAndroid Build Coastguard Worker 					return totally_read + ret;
1340*49cdfc7eSAndroid Build Coastguard Worker 				}
1341*49cdfc7eSAndroid Build Coastguard Worker 			}
1342*49cdfc7eSAndroid Build Coastguard Worker 			wait4sync_io(fd, 1);
1343*49cdfc7eSAndroid Build Coastguard Worker 		}
1344*49cdfc7eSAndroid Build Coastguard Worker 
1345*49cdfc7eSAndroid Build Coastguard Worker 	}
1346*49cdfc7eSAndroid Build Coastguard Worker 
1347*49cdfc7eSAndroid Build Coastguard Worker 	else if (method & LIO_IO_ASYNC) {
1348*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
1349*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall,
1350*49cdfc7eSAndroid Build Coastguard Worker 			"reada(%d, buf, %d, &status, %d)", fd, size, sig);
1351*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "reada";
1352*49cdfc7eSAndroid Build Coastguard Worker 
1353*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
1354*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
1355*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
1356*49cdfc7eSAndroid Build Coastguard Worker 		}
1357*49cdfc7eSAndroid Build Coastguard Worker 
1358*49cdfc7eSAndroid Build Coastguard Worker 		sigoff();
1359*49cdfc7eSAndroid Build Coastguard Worker 		if ((ret = reada(fd, buffer, size, &status, sig)) == -1) {
1360*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
1361*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d reada(%d, buf, %d, &stat, %d) ret:-1, errno=%d %s",
1362*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__,
1363*49cdfc7eSAndroid Build Coastguard Worker 				fd, size, sig, errno, strerror(errno));
1364*49cdfc7eSAndroid Build Coastguard Worker 			sigon();
1365*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
1366*49cdfc7eSAndroid Build Coastguard Worker 		}
1367*49cdfc7eSAndroid Build Coastguard Worker #endif
1368*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
1369*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall,
1370*49cdfc7eSAndroid Build Coastguard Worker 			"aio_read(fildes=%d, buf, nbytes=%d, signo=%d)", fd,
1371*49cdfc7eSAndroid Build Coastguard Worker 			size, sig);
1372*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "aio_read";
1373*49cdfc7eSAndroid Build Coastguard Worker 
1374*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
1375*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
1376*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
1377*49cdfc7eSAndroid Build Coastguard Worker 		}
1378*49cdfc7eSAndroid Build Coastguard Worker 
1379*49cdfc7eSAndroid Build Coastguard Worker 		if (sig)
1380*49cdfc7eSAndroid Build Coastguard Worker 			sighold(sig);
1381*49cdfc7eSAndroid Build Coastguard Worker 		if ((ret = aio_read(&aiocbp)) == -1) {
1382*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
1383*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d aio_read(fildes=%d, buf, nbytes=%d, signo=%d) ret:-1, errno=%d %s",
1384*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__,
1385*49cdfc7eSAndroid Build Coastguard Worker 				fd, size, sig, errno, strerror(errno));
1386*49cdfc7eSAndroid Build Coastguard Worker 			if (sig)
1387*49cdfc7eSAndroid Build Coastguard Worker 				sigrelse(sig);
1388*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
1389*49cdfc7eSAndroid Build Coastguard Worker 		}
1390*49cdfc7eSAndroid Build Coastguard Worker #endif
1391*49cdfc7eSAndroid Build Coastguard Worker 	}
1392*49cdfc7eSAndroid Build Coastguard Worker 	/* LIO_IO_ASYNC */
1393*49cdfc7eSAndroid Build Coastguard Worker 	else if (method & LIO_IO_SLISTIO) {
1394*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
1395*49cdfc7eSAndroid Build Coastguard Worker 		request.li_opcode = LO_READ;
1396*49cdfc7eSAndroid Build Coastguard Worker 		request.li_fildes = fd;
1397*49cdfc7eSAndroid Build Coastguard Worker 		request.li_buf = buffer;
1398*49cdfc7eSAndroid Build Coastguard Worker 		request.li_nbyte = size;
1399*49cdfc7eSAndroid Build Coastguard Worker 		request.li_status = &status;
1400*49cdfc7eSAndroid Build Coastguard Worker 		request.li_signo = sig;
1401*49cdfc7eSAndroid Build Coastguard Worker 		request.li_nstride = 0;
1402*49cdfc7eSAndroid Build Coastguard Worker 		request.li_filstride = 0;
1403*49cdfc7eSAndroid Build Coastguard Worker 		request.li_memstride = 0;
1404*49cdfc7eSAndroid Build Coastguard Worker 
1405*49cdfc7eSAndroid Build Coastguard Worker 		listio_cmd = LC_WAIT;
1406*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "listio(2) sync read";
1407*49cdfc7eSAndroid Build Coastguard Worker 
1408*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall,
1409*49cdfc7eSAndroid Build Coastguard Worker 			"listio(LC_WAIT, &req, 1) LO_READ, fd:%d, nbyte:%d",
1410*49cdfc7eSAndroid Build Coastguard Worker 			fd, size);
1411*49cdfc7eSAndroid Build Coastguard Worker 
1412*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
1413*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
1414*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
1415*49cdfc7eSAndroid Build Coastguard Worker 		}
1416*49cdfc7eSAndroid Build Coastguard Worker 
1417*49cdfc7eSAndroid Build Coastguard Worker 		sigoff();
1418*49cdfc7eSAndroid Build Coastguard Worker 		if (listio(listio_cmd, &request, 1) == -1) {
1419*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
1420*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s",
1421*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, Lio_SysCall, fd, size,
1422*49cdfc7eSAndroid Build Coastguard Worker 				errno, strerror(errno));
1423*49cdfc7eSAndroid Build Coastguard Worker 			sigon();
1424*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
1425*49cdfc7eSAndroid Build Coastguard Worker 		}
1426*49cdfc7eSAndroid Build Coastguard Worker 
1427*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level > 1)
1428*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s did not return -1\n",
1429*49cdfc7eSAndroid Build Coastguard Worker 			       __FILE__, __LINE__, Lio_SysCall);
1430*49cdfc7eSAndroid Build Coastguard Worker 
1431*49cdfc7eSAndroid Build Coastguard Worker 		ret = lio_check_asyncio(io_type, size, &status);
1432*49cdfc7eSAndroid Build Coastguard Worker 		return ret;
1433*49cdfc7eSAndroid Build Coastguard Worker #endif
1434*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
1435*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_lio_opcode = LIO_READ;
1436*49cdfc7eSAndroid Build Coastguard Worker 		listio_cmd = LIO_WAIT;
1437*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "lio_listio(3) sync read";
1438*49cdfc7eSAndroid Build Coastguard Worker 
1439*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall,
1440*49cdfc7eSAndroid Build Coastguard Worker 			"lio_listio(LIO_WAIT, aiolist, 1, NULL) LIO_READ, fd:%d, nbyte:%d",
1441*49cdfc7eSAndroid Build Coastguard Worker 			fd, size);
1442*49cdfc7eSAndroid Build Coastguard Worker 
1443*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
1444*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
1445*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
1446*49cdfc7eSAndroid Build Coastguard Worker 		}
1447*49cdfc7eSAndroid Build Coastguard Worker 
1448*49cdfc7eSAndroid Build Coastguard Worker 		if (sig)
1449*49cdfc7eSAndroid Build Coastguard Worker 			sighold(sig);
1450*49cdfc7eSAndroid Build Coastguard Worker 		if (lio_listio(listio_cmd, aiolist, 1, NULL) == -1) {
1451*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
1452*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s",
1453*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, Lio_SysCall, fd, size,
1454*49cdfc7eSAndroid Build Coastguard Worker 				errno, strerror(errno));
1455*49cdfc7eSAndroid Build Coastguard Worker 			if (sig)
1456*49cdfc7eSAndroid Build Coastguard Worker 				sigrelse(sig);
1457*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
1458*49cdfc7eSAndroid Build Coastguard Worker 		}
1459*49cdfc7eSAndroid Build Coastguard Worker 
1460*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level > 1)
1461*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s did not return -1\n",
1462*49cdfc7eSAndroid Build Coastguard Worker 			       __FILE__, __LINE__, Lio_SysCall);
1463*49cdfc7eSAndroid Build Coastguard Worker 
1464*49cdfc7eSAndroid Build Coastguard Worker 		ret = lio_check_asyncio(io_type, size, &aiocbp, method);
1465*49cdfc7eSAndroid Build Coastguard Worker 		return ret;
1466*49cdfc7eSAndroid Build Coastguard Worker #endif
1467*49cdfc7eSAndroid Build Coastguard Worker 	}
1468*49cdfc7eSAndroid Build Coastguard Worker 	/* LIO_IO_SLISTIO */
1469*49cdfc7eSAndroid Build Coastguard Worker 	else if (method & LIO_IO_ALISTIO) {
1470*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
1471*49cdfc7eSAndroid Build Coastguard Worker 		request.li_opcode = LO_READ;
1472*49cdfc7eSAndroid Build Coastguard Worker 		request.li_fildes = fd;
1473*49cdfc7eSAndroid Build Coastguard Worker 		request.li_buf = buffer;
1474*49cdfc7eSAndroid Build Coastguard Worker 		request.li_nbyte = size;
1475*49cdfc7eSAndroid Build Coastguard Worker 		request.li_status = &status;
1476*49cdfc7eSAndroid Build Coastguard Worker 		request.li_signo = sig;
1477*49cdfc7eSAndroid Build Coastguard Worker 		request.li_nstride = 0;
1478*49cdfc7eSAndroid Build Coastguard Worker 		request.li_filstride = 0;
1479*49cdfc7eSAndroid Build Coastguard Worker 		request.li_memstride = 0;
1480*49cdfc7eSAndroid Build Coastguard Worker 
1481*49cdfc7eSAndroid Build Coastguard Worker 		listio_cmd = LC_START;
1482*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "listio(2) async read";
1483*49cdfc7eSAndroid Build Coastguard Worker 
1484*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall,
1485*49cdfc7eSAndroid Build Coastguard Worker 			"listio(LC_START, &req, 1) LO_READ, fd:%d, nbyte:%d",
1486*49cdfc7eSAndroid Build Coastguard Worker 			fd, size);
1487*49cdfc7eSAndroid Build Coastguard Worker 
1488*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
1489*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
1490*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
1491*49cdfc7eSAndroid Build Coastguard Worker 		}
1492*49cdfc7eSAndroid Build Coastguard Worker 
1493*49cdfc7eSAndroid Build Coastguard Worker 		sigoff();
1494*49cdfc7eSAndroid Build Coastguard Worker 		if (listio(listio_cmd, &request, 1) == -1) {
1495*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
1496*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s",
1497*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, Lio_SysCall, fd, size,
1498*49cdfc7eSAndroid Build Coastguard Worker 				errno, strerror(errno));
1499*49cdfc7eSAndroid Build Coastguard Worker 			sigon();
1500*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
1501*49cdfc7eSAndroid Build Coastguard Worker 		}
1502*49cdfc7eSAndroid Build Coastguard Worker #endif
1503*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
1504*49cdfc7eSAndroid Build Coastguard Worker 		aiocbp.aio_lio_opcode = LIO_READ;
1505*49cdfc7eSAndroid Build Coastguard Worker 		listio_cmd = LIO_NOWAIT;
1506*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "lio_listio(3) async read";
1507*49cdfc7eSAndroid Build Coastguard Worker 
1508*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall,
1509*49cdfc7eSAndroid Build Coastguard Worker 			"lio_listio(LIO_NOWAIT, aiolist, 1, NULL) LIO_READ, fd:%d, nbyte:%d",
1510*49cdfc7eSAndroid Build Coastguard Worker 			fd, size);
1511*49cdfc7eSAndroid Build Coastguard Worker 
1512*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
1513*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
1514*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
1515*49cdfc7eSAndroid Build Coastguard Worker 		}
1516*49cdfc7eSAndroid Build Coastguard Worker 
1517*49cdfc7eSAndroid Build Coastguard Worker 		if (sig)
1518*49cdfc7eSAndroid Build Coastguard Worker 			sighold(sig);
1519*49cdfc7eSAndroid Build Coastguard Worker 		if (lio_listio(listio_cmd, aiolist, 1, NULL) == -1) {
1520*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
1521*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s",
1522*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, Lio_SysCall, fd, size,
1523*49cdfc7eSAndroid Build Coastguard Worker 				errno, strerror(errno));
1524*49cdfc7eSAndroid Build Coastguard Worker 			if (sig)
1525*49cdfc7eSAndroid Build Coastguard Worker 				sigrelse(sig);
1526*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
1527*49cdfc7eSAndroid Build Coastguard Worker 		}
1528*49cdfc7eSAndroid Build Coastguard Worker #endif
1529*49cdfc7eSAndroid Build Coastguard Worker 	}
1530*49cdfc7eSAndroid Build Coastguard Worker 	/* LIO_IO_ALISTIO */
1531*49cdfc7eSAndroid Build Coastguard Worker #ifndef CRAY
1532*49cdfc7eSAndroid Build Coastguard Worker 	else if (method & LIO_IO_SYNCV) {
1533*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "readv(2)";
1534*49cdfc7eSAndroid Build Coastguard Worker 
1535*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall, "readv(%d, &iov, 1) nbyte:%d", fd, size);
1536*49cdfc7eSAndroid Build Coastguard Worker 
1537*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
1538*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
1539*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
1540*49cdfc7eSAndroid Build Coastguard Worker 		}
1541*49cdfc7eSAndroid Build Coastguard Worker 		if ((ret = readv(fd, &iov, 1)) == -1) {
1542*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
1543*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d readv(%d, iov, 1) nbyte:%d ret:-1, errno=%d %s",
1544*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, fd, size, errno,
1545*49cdfc7eSAndroid Build Coastguard Worker 				strerror(errno));
1546*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
1547*49cdfc7eSAndroid Build Coastguard Worker 		}
1548*49cdfc7eSAndroid Build Coastguard Worker 
1549*49cdfc7eSAndroid Build Coastguard Worker 		if (ret != size) {
1550*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
1551*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d readv(%d, iov, 1) nbyte:%d returned=%d",
1552*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, fd, size, ret);
1553*49cdfc7eSAndroid Build Coastguard Worker 		} else if (Debug_level > 1)
1554*49cdfc7eSAndroid Build Coastguard Worker 			printf
1555*49cdfc7eSAndroid Build Coastguard Worker 			    ("DEBUG %s/%d: readv completed without error (ret %d)\n",
1556*49cdfc7eSAndroid Build Coastguard Worker 			     __FILE__, __LINE__, ret);
1557*49cdfc7eSAndroid Build Coastguard Worker 
1558*49cdfc7eSAndroid Build Coastguard Worker 		return ret;
1559*49cdfc7eSAndroid Build Coastguard Worker 	}			/* LIO_IO_SYNCV */
1560*49cdfc7eSAndroid Build Coastguard Worker #endif
1561*49cdfc7eSAndroid Build Coastguard Worker 
1562*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
1563*49cdfc7eSAndroid Build Coastguard Worker 	else if (method & LIO_IO_SYNCP) {
1564*49cdfc7eSAndroid Build Coastguard Worker 		io_type = "pread(2)";
1565*49cdfc7eSAndroid Build Coastguard Worker 
1566*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Lio_SysCall,
1567*49cdfc7eSAndroid Build Coastguard Worker 			"pread(%d, buf, %d, %lld)", fd, size,
1568*49cdfc7eSAndroid Build Coastguard Worker 			(long long)poffset);
1569*49cdfc7eSAndroid Build Coastguard Worker 
1570*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level) {
1571*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__,
1572*49cdfc7eSAndroid Build Coastguard Worker 			       Lio_SysCall);
1573*49cdfc7eSAndroid Build Coastguard Worker 		}
1574*49cdfc7eSAndroid Build Coastguard Worker 		if ((ret = pread(fd, buffer, size, poffset)) == -1) {
1575*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
1576*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d pread(%d, buf, %d, %lld) ret:-1, errno=%d %s",
1577*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, fd, size,
1578*49cdfc7eSAndroid Build Coastguard Worker 				(long long)poffset, errno, strerror(errno));
1579*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
1580*49cdfc7eSAndroid Build Coastguard Worker 		}
1581*49cdfc7eSAndroid Build Coastguard Worker 
1582*49cdfc7eSAndroid Build Coastguard Worker 		if (ret != size) {
1583*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
1584*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d pread(%d, buf, %d, %lld) returned=%d",
1585*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__,
1586*49cdfc7eSAndroid Build Coastguard Worker 				fd, size, (long long)poffset, ret);
1587*49cdfc7eSAndroid Build Coastguard Worker 		} else if (Debug_level > 1)
1588*49cdfc7eSAndroid Build Coastguard Worker 			printf
1589*49cdfc7eSAndroid Build Coastguard Worker 			    ("DEBUG %s/%d: pread completed without error (ret %d)\n",
1590*49cdfc7eSAndroid Build Coastguard Worker 			     __FILE__, __LINE__, ret);
1591*49cdfc7eSAndroid Build Coastguard Worker 
1592*49cdfc7eSAndroid Build Coastguard Worker 		return ret;
1593*49cdfc7eSAndroid Build Coastguard Worker 	}			/* LIO_IO_SYNCP */
1594*49cdfc7eSAndroid Build Coastguard Worker #endif
1595*49cdfc7eSAndroid Build Coastguard Worker 
1596*49cdfc7eSAndroid Build Coastguard Worker 	else {
1597*49cdfc7eSAndroid Build Coastguard Worker 		printf("DEBUG %s/%d: No I/O method chosen\n", __FILE__,
1598*49cdfc7eSAndroid Build Coastguard Worker 		       __LINE__);
1599*49cdfc7eSAndroid Build Coastguard Worker 		return -1;
1600*49cdfc7eSAndroid Build Coastguard Worker 	}
1601*49cdfc7eSAndroid Build Coastguard Worker 
1602*49cdfc7eSAndroid Build Coastguard Worker 	/*
1603*49cdfc7eSAndroid Build Coastguard Worker 	 * wait for async io to complete.
1604*49cdfc7eSAndroid Build Coastguard Worker 	 * Note: Sync io should have returned prior to getting here.
1605*49cdfc7eSAndroid Build Coastguard Worker 	 */
1606*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
1607*49cdfc7eSAndroid Build Coastguard Worker 	ret = lio_wait4asyncio(method, fd, statptr);
1608*49cdfc7eSAndroid Build Coastguard Worker #endif
1609*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
1610*49cdfc7eSAndroid Build Coastguard Worker 	ret = lio_wait4asyncio(method, fd, &aiocbp);
1611*49cdfc7eSAndroid Build Coastguard Worker #endif
1612*49cdfc7eSAndroid Build Coastguard Worker 
1613*49cdfc7eSAndroid Build Coastguard Worker 	/*
1614*49cdfc7eSAndroid Build Coastguard Worker 	 * If there was an error waiting for async i/o to complete,
1615*49cdfc7eSAndroid Build Coastguard Worker 	 * return the error value (errno) to the caller.
1616*49cdfc7eSAndroid Build Coastguard Worker 	 * Note: Errormsg should already have been updated.
1617*49cdfc7eSAndroid Build Coastguard Worker 	 */
1618*49cdfc7eSAndroid Build Coastguard Worker 	if (ret < 0) {
1619*49cdfc7eSAndroid Build Coastguard Worker 		return ret;
1620*49cdfc7eSAndroid Build Coastguard Worker 	}
1621*49cdfc7eSAndroid Build Coastguard Worker 
1622*49cdfc7eSAndroid Build Coastguard Worker 	/*
1623*49cdfc7eSAndroid Build Coastguard Worker 	 * If i/o was not waited for (may not have been completed at this time),
1624*49cdfc7eSAndroid Build Coastguard Worker 	 * return the size that was requested.
1625*49cdfc7eSAndroid Build Coastguard Worker 	 */
1626*49cdfc7eSAndroid Build Coastguard Worker 	if (ret == 1)
1627*49cdfc7eSAndroid Build Coastguard Worker 		return size;
1628*49cdfc7eSAndroid Build Coastguard Worker 
1629*49cdfc7eSAndroid Build Coastguard Worker 	/*
1630*49cdfc7eSAndroid Build Coastguard Worker 	 * check that async io was successful.
1631*49cdfc7eSAndroid Build Coastguard Worker 	 * Note:  if the there was an system call failure, -errno
1632*49cdfc7eSAndroid Build Coastguard Worker 	 * was returned and Errormsg should already have been updated.
1633*49cdfc7eSAndroid Build Coastguard Worker 	 * If amount i/o was different than size, Errormsg should already
1634*49cdfc7eSAndroid Build Coastguard Worker 	 * have been updated but the actual i/o size if returned.
1635*49cdfc7eSAndroid Build Coastguard Worker 	 */
1636*49cdfc7eSAndroid Build Coastguard Worker 
1637*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
1638*49cdfc7eSAndroid Build Coastguard Worker 	ret = lio_check_asyncio(io_type, size, &status);
1639*49cdfc7eSAndroid Build Coastguard Worker #endif
1640*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
1641*49cdfc7eSAndroid Build Coastguard Worker 	ret = lio_check_asyncio(io_type, size, &aiocbp, method);
1642*49cdfc7eSAndroid Build Coastguard Worker #endif
1643*49cdfc7eSAndroid Build Coastguard Worker 
1644*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
1645*49cdfc7eSAndroid Build Coastguard Worker }				/* end of lio_read_buffer */
1646*49cdfc7eSAndroid Build Coastguard Worker 
1647*49cdfc7eSAndroid Build Coastguard Worker #if !defined(__sun) && !defined(__hpux) && !defined(_AIX)
1648*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************************
1649*49cdfc7eSAndroid Build Coastguard Worker  * This function will check that async io was successful.
1650*49cdfc7eSAndroid Build Coastguard Worker  * It can also be used to check sync listio since it uses the
1651*49cdfc7eSAndroid Build Coastguard Worker  * same method.
1652*49cdfc7eSAndroid Build Coastguard Worker  *
1653*49cdfc7eSAndroid Build Coastguard Worker  * Return Values
1654*49cdfc7eSAndroid Build Coastguard Worker  *  If status.sw_error is set, -status.sw_error is returned.
1655*49cdfc7eSAndroid Build Coastguard Worker  *  Otherwise sw_count's field value is returned.
1656*49cdfc7eSAndroid Build Coastguard Worker  *
1657*49cdfc7eSAndroid Build Coastguard Worker  * (rrl 04/96)
1658*49cdfc7eSAndroid Build Coastguard Worker  ***********************************************************************/
1659*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
1660*49cdfc7eSAndroid Build Coastguard Worker int lio_check_asyncio(char *io_type, int size, struct iosw *status)
1661*49cdfc7eSAndroid Build Coastguard Worker #elif defined(sgi)
1662*49cdfc7eSAndroid Build Coastguard Worker int lio_check_asyncio(char *io_type, int size, aiocb_t * aiocbp, int method)
1663*49cdfc7eSAndroid Build Coastguard Worker #elif defined(__linux__) && !defined(__UCLIBC__)
1664*49cdfc7eSAndroid Build Coastguard Worker int lio_check_asyncio(char *io_type, int size, struct aiocb *aiocbp, int method)
1665*49cdfc7eSAndroid Build Coastguard Worker {
1666*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
1667*49cdfc7eSAndroid Build Coastguard Worker 
1668*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
1669*49cdfc7eSAndroid Build Coastguard Worker 	if (status->sw_error) {
1670*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Errormsg,
1671*49cdfc7eSAndroid Build Coastguard Worker 			"%s/%d %s, sw_error set = %d %s, sw_count = %d",
1672*49cdfc7eSAndroid Build Coastguard Worker 			__FILE__, __LINE__, io_type,
1673*49cdfc7eSAndroid Build Coastguard Worker 			status->sw_error, strerror(status->sw_error),
1674*49cdfc7eSAndroid Build Coastguard Worker 			status->sw_count);
1675*49cdfc7eSAndroid Build Coastguard Worker 		return -status->sw_error;
1676*49cdfc7eSAndroid Build Coastguard Worker 	} else if (status->sw_count != size) {
1677*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Errormsg,
1678*49cdfc7eSAndroid Build Coastguard Worker 			"%s/%d %s, sw_count not as expected(%d), but actual:%d",
1679*49cdfc7eSAndroid Build Coastguard Worker 			__FILE__, __LINE__, io_type, size, status->sw_count);
1680*49cdfc7eSAndroid Build Coastguard Worker 	} else if (Debug_level > 1) {
1681*49cdfc7eSAndroid Build Coastguard Worker 		printf
1682*49cdfc7eSAndroid Build Coastguard Worker 		    ("DEBUG %s/%d: %s completed without error (sw_error == 0, sw_count == %d)\n",
1683*49cdfc7eSAndroid Build Coastguard Worker 		     __FILE__, __LINE__, io_type, status->sw_count);
1684*49cdfc7eSAndroid Build Coastguard Worker 	}
1685*49cdfc7eSAndroid Build Coastguard Worker 
1686*49cdfc7eSAndroid Build Coastguard Worker 	return status->sw_count;
1687*49cdfc7eSAndroid Build Coastguard Worker 
1688*49cdfc7eSAndroid Build Coastguard Worker #else
1689*49cdfc7eSAndroid Build Coastguard Worker 
1690*49cdfc7eSAndroid Build Coastguard Worker 	int cnt = 1;
1691*49cdfc7eSAndroid Build Coastguard Worker 
1692*49cdfc7eSAndroid Build Coastguard Worker 	/* The I/O may have been synchronous with signal completion.  It doesn't
1693*49cdfc7eSAndroid Build Coastguard Worker 	 * make sense, but the combination could be generated.  Release the
1694*49cdfc7eSAndroid Build Coastguard Worker 	 * completion signal here otherwise it'll hang around and bite us
1695*49cdfc7eSAndroid Build Coastguard Worker 	 * later.
1696*49cdfc7eSAndroid Build Coastguard Worker 	 */
1697*49cdfc7eSAndroid Build Coastguard Worker 	if (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL)
1698*49cdfc7eSAndroid Build Coastguard Worker 		sigrelse(aiocbp->aio_sigevent.sigev_signo);
1699*49cdfc7eSAndroid Build Coastguard Worker 
1700*49cdfc7eSAndroid Build Coastguard Worker 	ret = aio_error(aiocbp);
1701*49cdfc7eSAndroid Build Coastguard Worker 
1702*49cdfc7eSAndroid Build Coastguard Worker 	while (ret == EINPROGRESS) {
1703*49cdfc7eSAndroid Build Coastguard Worker 		ret = aio_error(aiocbp);
1704*49cdfc7eSAndroid Build Coastguard Worker 		++cnt;
1705*49cdfc7eSAndroid Build Coastguard Worker 	}
1706*49cdfc7eSAndroid Build Coastguard Worker 	if (cnt > 1) {
1707*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Errormsg,
1708*49cdfc7eSAndroid Build Coastguard Worker 			"%s/%d %s, aio_error had to loop on EINPROGRESS, cnt=%d; random method %#o; sigev_notify=%s",
1709*49cdfc7eSAndroid Build Coastguard Worker 			__FILE__, __LINE__, io_type, cnt, method,
1710*49cdfc7eSAndroid Build Coastguard Worker 			(aiocbp->aio_sigevent.sigev_notify ==
1711*49cdfc7eSAndroid Build Coastguard Worker 			 SIGEV_SIGNAL ? "signal" : aiocbp->aio_sigevent.
1712*49cdfc7eSAndroid Build Coastguard Worker 			 sigev_notify == SIGEV_NONE ? "none" :
1713*49cdfc7eSAndroid Build Coastguard Worker #ifdef SIGEV_CALLBACK
1714*49cdfc7eSAndroid Build Coastguard Worker 			 aiocbp->aio_sigevent.sigev_notify ==
1715*49cdfc7eSAndroid Build Coastguard Worker 			 SIGEV_CALLBACK ? "callback" :
1716*49cdfc7eSAndroid Build Coastguard Worker #endif
1717*49cdfc7eSAndroid Build Coastguard Worker 			 aiocbp->aio_sigevent.sigev_notify ==
1718*49cdfc7eSAndroid Build Coastguard Worker 			 SIGEV_THREAD ? "thread" : "unknown"));
1719*49cdfc7eSAndroid Build Coastguard Worker 		return -ret;
1720*49cdfc7eSAndroid Build Coastguard Worker 	}
1721*49cdfc7eSAndroid Build Coastguard Worker 
1722*49cdfc7eSAndroid Build Coastguard Worker 	if (ret != 0) {
1723*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Errormsg,
1724*49cdfc7eSAndroid Build Coastguard Worker 			"%s/%d %s, aio_error = %d %s; random method %#o",
1725*49cdfc7eSAndroid Build Coastguard Worker 			__FILE__, __LINE__, io_type,
1726*49cdfc7eSAndroid Build Coastguard Worker 			ret, strerror(ret), method);
1727*49cdfc7eSAndroid Build Coastguard Worker 		return -ret;
1728*49cdfc7eSAndroid Build Coastguard Worker 	}
1729*49cdfc7eSAndroid Build Coastguard Worker 	ret = aio_return(aiocbp);
1730*49cdfc7eSAndroid Build Coastguard Worker 	if (ret != size) {
1731*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Errormsg,
1732*49cdfc7eSAndroid Build Coastguard Worker 			"%s/%d %s, aio_return not as expected(%d), but actual:%d",
1733*49cdfc7eSAndroid Build Coastguard Worker 			__FILE__, __LINE__, io_type, size, ret);
1734*49cdfc7eSAndroid Build Coastguard Worker 
1735*49cdfc7eSAndroid Build Coastguard Worker #ifdef BUG1_workaround
1736*49cdfc7eSAndroid Build Coastguard Worker 		if (ret == 0) {
1737*49cdfc7eSAndroid Build Coastguard Worker 			ret = size;
1738*49cdfc7eSAndroid Build Coastguard Worker 			if (Debug_level > 1) {
1739*49cdfc7eSAndroid Build Coastguard Worker 				printf
1740*49cdfc7eSAndroid Build Coastguard Worker 				    ("WARN %s/%d: %s completed with bug1_workaround (aio_error == 0, aio_return now == %d)\n",
1741*49cdfc7eSAndroid Build Coastguard Worker 				     __FILE__, __LINE__, io_type, ret);
1742*49cdfc7eSAndroid Build Coastguard Worker 			}
1743*49cdfc7eSAndroid Build Coastguard Worker 		}
1744*49cdfc7eSAndroid Build Coastguard Worker #endif /* BUG1_workaround */
1745*49cdfc7eSAndroid Build Coastguard Worker 
1746*49cdfc7eSAndroid Build Coastguard Worker 	} else if (Debug_level > 1) {
1747*49cdfc7eSAndroid Build Coastguard Worker 		printf
1748*49cdfc7eSAndroid Build Coastguard Worker 		    ("DEBUG %s/%d: %s completed without error (aio_error == 0, aio_return == %d)\n",
1749*49cdfc7eSAndroid Build Coastguard Worker 		     __FILE__, __LINE__, io_type, ret);
1750*49cdfc7eSAndroid Build Coastguard Worker 	}
1751*49cdfc7eSAndroid Build Coastguard Worker 
1752*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
1753*49cdfc7eSAndroid Build Coastguard Worker 
1754*49cdfc7eSAndroid Build Coastguard Worker #endif
1755*49cdfc7eSAndroid Build Coastguard Worker }				/* end of lio_check_asyncio */
1756*49cdfc7eSAndroid Build Coastguard Worker #endif
1757*49cdfc7eSAndroid Build Coastguard Worker 
1758*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************************
1759*49cdfc7eSAndroid Build Coastguard Worker  *
1760*49cdfc7eSAndroid Build Coastguard Worker  * This function will wait for async io to complete.
1761*49cdfc7eSAndroid Build Coastguard Worker  * If multiple wait methods are specified, the order is predetermined
1762*49cdfc7eSAndroid Build Coastguard Worker  * to LIO_WAIT_RECALL,
1763*49cdfc7eSAndroid Build Coastguard Worker  * LIO_WAIT_ACTIVE, LIO_WAIT_SIGPAUSE, LIO_WAIT_SIGACTIVE,
1764*49cdfc7eSAndroid Build Coastguard Worker  * then LIO_WAIT_NONE.
1765*49cdfc7eSAndroid Build Coastguard Worker  *
1766*49cdfc7eSAndroid Build Coastguard Worker  * If no wait method was specified the default wait method is: recall(2)
1767*49cdfc7eSAndroid Build Coastguard Worker  * or aio_suspend(3), as appropriate.
1768*49cdfc7eSAndroid Build Coastguard Worker  *
1769*49cdfc7eSAndroid Build Coastguard Worker  * Return Values
1770*49cdfc7eSAndroid Build Coastguard Worker  *	<0: errno of failed recall
1771*49cdfc7eSAndroid Build Coastguard Worker  *	0 : async io was completed
1772*49cdfc7eSAndroid Build Coastguard Worker  *	1 : async was not waited for, io may not have completed.
1773*49cdfc7eSAndroid Build Coastguard Worker  *
1774*49cdfc7eSAndroid Build Coastguard Worker  * (rrl 04/96)
1775*49cdfc7eSAndroid Build Coastguard Worker  ***********************************************************************/
1776*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
1777*49cdfc7eSAndroid Build Coastguard Worker int lio_wait4asyncio(int method, int fd, struct iosw **statptr)
1778*49cdfc7eSAndroid Build Coastguard Worker #elif defined(sgi)
1779*49cdfc7eSAndroid Build Coastguard Worker int lio_wait4asyncio(int method, int fd, aiocb_t * aiocbp)
1780*49cdfc7eSAndroid Build Coastguard Worker #elif defined(__linux__) && !defined(__UCLIBC__)
1781*49cdfc7eSAndroid Build Coastguard Worker int lio_wait4asyncio(int method, int fd, struct aiocb *aiocbp)
1782*49cdfc7eSAndroid Build Coastguard Worker {
1783*49cdfc7eSAndroid Build Coastguard Worker 	int cnt;
1784*49cdfc7eSAndroid Build Coastguard Worker #ifdef sgi
1785*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
1786*49cdfc7eSAndroid Build Coastguard Worker 	const aiocb_t *aioary[1];
1787*49cdfc7eSAndroid Build Coastguard Worker #endif
1788*49cdfc7eSAndroid Build Coastguard Worker #if defined(__linux__)&& !defined(__UCLIBC__)
1789*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
1790*49cdfc7eSAndroid Build Coastguard Worker 	const struct aiocb *aioary[1];
1791*49cdfc7eSAndroid Build Coastguard Worker #endif
1792*49cdfc7eSAndroid Build Coastguard Worker 
1793*49cdfc7eSAndroid Build Coastguard Worker 	if ((method & LIO_WAIT_RECALL)
1794*49cdfc7eSAndroid Build Coastguard Worker #if defined(sgi) || (defined(__linux__)&& !defined(__UCLIBC__))
1795*49cdfc7eSAndroid Build Coastguard Worker 	    || (method & LIO_WAIT_CBSUSPEND)
1796*49cdfc7eSAndroid Build Coastguard Worker 	    || (method & LIO_WAIT_SIGSUSPEND)
1797*49cdfc7eSAndroid Build Coastguard Worker #endif
1798*49cdfc7eSAndroid Build Coastguard Worker 	    || ((method & LIO_WAIT_TYPES) == 0)) {
1799*49cdfc7eSAndroid Build Coastguard Worker 		/*
1800*49cdfc7eSAndroid Build Coastguard Worker 		 * If method has LIO_WAIT_RECALL bit set or method does
1801*49cdfc7eSAndroid Build Coastguard Worker 		 * not have any wait method bits set (default), use recall/aio_suspend.
1802*49cdfc7eSAndroid Build Coastguard Worker 		 */
1803*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
1804*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level > 2)
1805*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: wait method : recall\n", __FILE__,
1806*49cdfc7eSAndroid Build Coastguard Worker 			       __LINE__);
1807*49cdfc7eSAndroid Build Coastguard Worker 		sigon();
1808*49cdfc7eSAndroid Build Coastguard Worker 		if (recall(fd, 1, statptr)) {
1809*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
1810*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d recall(%d, 1, stat) failed, errno:%d %s",
1811*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, fd, errno, strerror(errno));
1812*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
1813*49cdfc7eSAndroid Build Coastguard Worker 		}
1814*49cdfc7eSAndroid Build Coastguard Worker #else
1815*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level > 2)
1816*49cdfc7eSAndroid Build Coastguard Worker 			printf
1817*49cdfc7eSAndroid Build Coastguard Worker 			    ("DEBUG %s/%d: wait method : aio_suspend, sigev_notify=%s\n",
1818*49cdfc7eSAndroid Build Coastguard Worker 			     __FILE__, __LINE__,
1819*49cdfc7eSAndroid Build Coastguard Worker 			     (aiocbp->aio_sigevent.sigev_notify ==
1820*49cdfc7eSAndroid Build Coastguard Worker 			      SIGEV_SIGNAL ? "signal" : aiocbp->aio_sigevent.
1821*49cdfc7eSAndroid Build Coastguard Worker 			      sigev_notify == SIGEV_NONE ? "none" :
1822*49cdfc7eSAndroid Build Coastguard Worker #ifdef SIGEV_CALLBACK
1823*49cdfc7eSAndroid Build Coastguard Worker 			      aiocbp->aio_sigevent.sigev_notify ==
1824*49cdfc7eSAndroid Build Coastguard Worker 			      SIGEV_CALLBACK ? "callback" :
1825*49cdfc7eSAndroid Build Coastguard Worker #endif
1826*49cdfc7eSAndroid Build Coastguard Worker 			      aiocbp->aio_sigevent.sigev_notify ==
1827*49cdfc7eSAndroid Build Coastguard Worker 			      SIGEV_THREAD ? "thread" : "unknown"));
1828*49cdfc7eSAndroid Build Coastguard Worker 
1829*49cdfc7eSAndroid Build Coastguard Worker 		aioary[0] = aiocbp;
1830*49cdfc7eSAndroid Build Coastguard Worker 		ret = aio_suspend(aioary, 1, NULL);
1831*49cdfc7eSAndroid Build Coastguard Worker 		if ((ret == -1) && (errno == EINTR)) {
1832*49cdfc7eSAndroid Build Coastguard Worker 			if (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL) {
1833*49cdfc7eSAndroid Build Coastguard Worker 				if (Debug_level > 2) {
1834*49cdfc7eSAndroid Build Coastguard Worker 					printf
1835*49cdfc7eSAndroid Build Coastguard Worker 					    ("DEBUG %s/%d: aio_suspend received EINTR, sigev_notify=SIGEV_SIGNAL -- ok\n",
1836*49cdfc7eSAndroid Build Coastguard Worker 					     __FILE__, __LINE__);
1837*49cdfc7eSAndroid Build Coastguard Worker 				}
1838*49cdfc7eSAndroid Build Coastguard Worker 			} else {
1839*49cdfc7eSAndroid Build Coastguard Worker 				sprintf(Errormsg,
1840*49cdfc7eSAndroid Build Coastguard Worker 					"%s/%d aio_suspend received EINTR, sigev_notify=%s, not ok\n",
1841*49cdfc7eSAndroid Build Coastguard Worker 					__FILE__, __LINE__,
1842*49cdfc7eSAndroid Build Coastguard Worker 					(aiocbp->aio_sigevent.sigev_notify ==
1843*49cdfc7eSAndroid Build Coastguard Worker 					 SIGEV_SIGNAL ? "signal" : aiocbp->
1844*49cdfc7eSAndroid Build Coastguard Worker 					 aio_sigevent.sigev_notify ==
1845*49cdfc7eSAndroid Build Coastguard Worker 					 SIGEV_NONE ? "none" :
1846*49cdfc7eSAndroid Build Coastguard Worker #ifdef SIGEV_CALLBACK
1847*49cdfc7eSAndroid Build Coastguard Worker 					 aiocbp->aio_sigevent.sigev_notify ==
1848*49cdfc7eSAndroid Build Coastguard Worker 					 SIGEV_CALLBACK ? "callback" :
1849*49cdfc7eSAndroid Build Coastguard Worker #endif
1850*49cdfc7eSAndroid Build Coastguard Worker 					 aiocbp->aio_sigevent.sigev_notify ==
1851*49cdfc7eSAndroid Build Coastguard Worker 					 SIGEV_THREAD ? "thread" : "unknown"));
1852*49cdfc7eSAndroid Build Coastguard Worker 				return -errno;
1853*49cdfc7eSAndroid Build Coastguard Worker 			}
1854*49cdfc7eSAndroid Build Coastguard Worker 		} else if (ret) {
1855*49cdfc7eSAndroid Build Coastguard Worker 			sprintf(Errormsg,
1856*49cdfc7eSAndroid Build Coastguard Worker 				"%s/%d aio_suspend(fildes=%d, aioary, 1, NULL) failed, errno:%d %s",
1857*49cdfc7eSAndroid Build Coastguard Worker 				__FILE__, __LINE__, fd, errno, strerror(errno));
1858*49cdfc7eSAndroid Build Coastguard Worker 			return -errno;
1859*49cdfc7eSAndroid Build Coastguard Worker 		}
1860*49cdfc7eSAndroid Build Coastguard Worker #endif
1861*49cdfc7eSAndroid Build Coastguard Worker 
1862*49cdfc7eSAndroid Build Coastguard Worker 	} else if (method & LIO_WAIT_ACTIVE) {
1863*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level > 2)
1864*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: wait method : active\n", __FILE__,
1865*49cdfc7eSAndroid Build Coastguard Worker 			       __LINE__);
1866*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
1867*49cdfc7eSAndroid Build Coastguard Worker 		sigon();
1868*49cdfc7eSAndroid Build Coastguard Worker 		/*
1869*49cdfc7eSAndroid Build Coastguard Worker 		 * loop until sw_flag, sw_count or sw_error field elements
1870*49cdfc7eSAndroid Build Coastguard Worker 		 * change to non-zero.
1871*49cdfc7eSAndroid Build Coastguard Worker 		 */
1872*49cdfc7eSAndroid Build Coastguard Worker 		cnt = 0;
1873*49cdfc7eSAndroid Build Coastguard Worker 		while ((*statptr)->sw_flag == 0 &&
1874*49cdfc7eSAndroid Build Coastguard Worker 		       (*statptr)->sw_count == 0 && (*statptr)->sw_error == 0) {
1875*49cdfc7eSAndroid Build Coastguard Worker 			cnt++;
1876*49cdfc7eSAndroid Build Coastguard Worker 		}
1877*49cdfc7eSAndroid Build Coastguard Worker #else
1878*49cdfc7eSAndroid Build Coastguard Worker 		/* loop while aio_error() returns EINPROGRESS */
1879*49cdfc7eSAndroid Build Coastguard Worker 		cnt = 0;
1880*49cdfc7eSAndroid Build Coastguard Worker 		while (1) {
1881*49cdfc7eSAndroid Build Coastguard Worker 			ret = aio_error(aiocbp);
1882*49cdfc7eSAndroid Build Coastguard Worker 			if (ret != EINPROGRESS) {
1883*49cdfc7eSAndroid Build Coastguard Worker 				break;
1884*49cdfc7eSAndroid Build Coastguard Worker 			}
1885*49cdfc7eSAndroid Build Coastguard Worker 			++cnt;
1886*49cdfc7eSAndroid Build Coastguard Worker 		}
1887*49cdfc7eSAndroid Build Coastguard Worker 
1888*49cdfc7eSAndroid Build Coastguard Worker #endif
1889*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level > 5 && cnt && (cnt % 50) == 0)
1890*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: wait active cnt = %d\n",
1891*49cdfc7eSAndroid Build Coastguard Worker 			       __FILE__, __LINE__, cnt);
1892*49cdfc7eSAndroid Build Coastguard Worker 
1893*49cdfc7eSAndroid Build Coastguard Worker 	} else if (method & LIO_WAIT_SIGPAUSE) {
1894*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level > 2)
1895*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: wait method : sigpause\n",
1896*49cdfc7eSAndroid Build Coastguard Worker 			       __FILE__, __LINE__);
1897*49cdfc7eSAndroid Build Coastguard Worker #ifdef sgi
1898*49cdfc7eSAndroid Build Coastguard Worker 		/* note: don't do the sigon() for CRAY in this case.  why? -- roehrich 6/11/97 */
1899*49cdfc7eSAndroid Build Coastguard Worker 		if (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL)
1900*49cdfc7eSAndroid Build Coastguard Worker 			sigrelse(aiocbp->aio_sigevent.sigev_signo);
1901*49cdfc7eSAndroid Build Coastguard Worker 		else {
1902*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: sigev_notify != SIGEV_SIGNAL\n",
1903*49cdfc7eSAndroid Build Coastguard Worker 			       __FILE__, __LINE__);
1904*49cdfc7eSAndroid Build Coastguard Worker 			return -1;
1905*49cdfc7eSAndroid Build Coastguard Worker 		}
1906*49cdfc7eSAndroid Build Coastguard Worker #endif
1907*49cdfc7eSAndroid Build Coastguard Worker 		pause();
1908*49cdfc7eSAndroid Build Coastguard Worker 
1909*49cdfc7eSAndroid Build Coastguard Worker 	} else if (method & LIO_WAIT_SIGACTIVE) {
1910*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level > 2)
1911*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: wait method : sigactive\n",
1912*49cdfc7eSAndroid Build Coastguard Worker 			       __FILE__, __LINE__);
1913*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
1914*49cdfc7eSAndroid Build Coastguard Worker 		sigon();
1915*49cdfc7eSAndroid Build Coastguard Worker #else
1916*49cdfc7eSAndroid Build Coastguard Worker 		if (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL)
1917*49cdfc7eSAndroid Build Coastguard Worker 			sigrelse(aiocbp->aio_sigevent.sigev_signo);
1918*49cdfc7eSAndroid Build Coastguard Worker 		else {
1919*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: sigev_notify != SIGEV_SIGNAL\n",
1920*49cdfc7eSAndroid Build Coastguard Worker 			       __FILE__, __LINE__);
1921*49cdfc7eSAndroid Build Coastguard Worker 			return -1;
1922*49cdfc7eSAndroid Build Coastguard Worker 		}
1923*49cdfc7eSAndroid Build Coastguard Worker #endif
1924*49cdfc7eSAndroid Build Coastguard Worker 		/* loop waiting for signal */
1925*49cdfc7eSAndroid Build Coastguard Worker 		while (Received_signal == Rec_signal) {
1926*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
1927*49cdfc7eSAndroid Build Coastguard Worker 			sigon();
1928*49cdfc7eSAndroid Build Coastguard Worker #else
1929*49cdfc7eSAndroid Build Coastguard Worker 			sigrelse(aiocbp->aio_sigevent.sigev_signo);
1930*49cdfc7eSAndroid Build Coastguard Worker #endif
1931*49cdfc7eSAndroid Build Coastguard Worker 		}
1932*49cdfc7eSAndroid Build Coastguard Worker 
1933*49cdfc7eSAndroid Build Coastguard Worker 	} else if (method & LIO_WAIT_NONE) {
1934*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level > 2)
1935*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: wait method : none\n", __FILE__,
1936*49cdfc7eSAndroid Build Coastguard Worker 			       __LINE__);
1937*49cdfc7eSAndroid Build Coastguard Worker 		/* It's broken because the aiocb/iosw is an automatic variable in
1938*49cdfc7eSAndroid Build Coastguard Worker 		 * lio_{read,write}_buffer, so when the function returns and the
1939*49cdfc7eSAndroid Build Coastguard Worker 		 * I/O completes there will be nowhere to write the I/O status.
1940*49cdfc7eSAndroid Build Coastguard Worker 		 * It doesn't cause a problem on unicos--probably because of some
1941*49cdfc7eSAndroid Build Coastguard Worker 		 * compiler quirk, or an accident.  It causes POSIX async I/O
1942*49cdfc7eSAndroid Build Coastguard Worker 		 * to core dump some threads.   spr/pv 705909.  6/27/97 roehrich
1943*49cdfc7eSAndroid Build Coastguard Worker 		 */
1944*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Errormsg,
1945*49cdfc7eSAndroid Build Coastguard Worker 			"%s/%d LIO_WAIT_NONE was selected (this is broken)\n",
1946*49cdfc7eSAndroid Build Coastguard Worker 			__FILE__, __LINE__);
1947*49cdfc7eSAndroid Build Coastguard Worker #ifdef CRAY
1948*49cdfc7eSAndroid Build Coastguard Worker 		sigon();
1949*49cdfc7eSAndroid Build Coastguard Worker #endif
1950*49cdfc7eSAndroid Build Coastguard Worker /*        return 1;*/
1951*49cdfc7eSAndroid Build Coastguard Worker 		return -1;
1952*49cdfc7eSAndroid Build Coastguard Worker 	} else {
1953*49cdfc7eSAndroid Build Coastguard Worker 		if (Debug_level > 2)
1954*49cdfc7eSAndroid Build Coastguard Worker 			printf("DEBUG %s/%d: no wait method was chosen\n",
1955*49cdfc7eSAndroid Build Coastguard Worker 			       __FILE__, __LINE__);
1956*49cdfc7eSAndroid Build Coastguard Worker 		return -1;
1957*49cdfc7eSAndroid Build Coastguard Worker 	}
1958*49cdfc7eSAndroid Build Coastguard Worker 
1959*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
1960*49cdfc7eSAndroid Build Coastguard Worker 
1961*49cdfc7eSAndroid Build Coastguard Worker }				/* end of lio_wait4asyncio */
1962*49cdfc7eSAndroid Build Coastguard Worker 
1963*49cdfc7eSAndroid Build Coastguard Worker #endif /* ifndef linux */
1964*49cdfc7eSAndroid Build Coastguard Worker #endif
1965*49cdfc7eSAndroid Build Coastguard Worker 
1966*49cdfc7eSAndroid Build Coastguard Worker #if UNIT_TEST
1967*49cdfc7eSAndroid Build Coastguard Worker /***********************************************************************
1968*49cdfc7eSAndroid Build Coastguard Worker  * The following code is provided as unit test.
1969*49cdfc7eSAndroid Build Coastguard Worker  * Just define add "-DUNIT_TEST=1" to the cc line.
1970*49cdfc7eSAndroid Build Coastguard Worker  *
1971*49cdfc7eSAndroid Build Coastguard Worker  * (rrl 04/96)
1972*49cdfc7eSAndroid Build Coastguard Worker  ***********************************************************************/
1973*49cdfc7eSAndroid Build Coastguard Worker struct unit_info_t {
1974*49cdfc7eSAndroid Build Coastguard Worker 	int method;
1975*49cdfc7eSAndroid Build Coastguard Worker 	int sig;
1976*49cdfc7eSAndroid Build Coastguard Worker 	char *str;
1977*49cdfc7eSAndroid Build Coastguard Worker } Unit_info[] = {
1978*49cdfc7eSAndroid Build Coastguard Worker 	{
1979*49cdfc7eSAndroid Build Coastguard Worker 	LIO_IO_SYNC, 0, "sync io"}, {
1980*49cdfc7eSAndroid Build Coastguard Worker 	LIO_IO_SYNCV, 0, "sync readv/writev"}, {
1981*49cdfc7eSAndroid Build Coastguard Worker 	LIO_IO_SYNCP, 0, "sync pread/pwrite"}, {
1982*49cdfc7eSAndroid Build Coastguard Worker 	LIO_IO_ASYNC, 0, "async io, def wait"}, {
1983*49cdfc7eSAndroid Build Coastguard Worker 	LIO_IO_SLISTIO, 0, "sync listio"}, {
1984*49cdfc7eSAndroid Build Coastguard Worker 	LIO_IO_ALISTIO, 0, "async listio, def wait"}, {
1985*49cdfc7eSAndroid Build Coastguard Worker 	LIO_IO_ASYNC | LIO_WAIT_ACTIVE, 0, "async active"}, {
1986*49cdfc7eSAndroid Build Coastguard Worker 	LIO_IO_ASYNC | LIO_WAIT_RECALL, 0, "async recall/suspend"}, {
1987*49cdfc7eSAndroid Build Coastguard Worker 	LIO_IO_ASYNC | LIO_WAIT_SIGPAUSE, SIGUSR1, "async sigpause"}, {
1988*49cdfc7eSAndroid Build Coastguard Worker 	LIO_IO_ASYNC | LIO_WAIT_SIGACTIVE, SIGUSR1, "async sigactive"}, {
1989*49cdfc7eSAndroid Build Coastguard Worker 	LIO_IO_ALISTIO | LIO_WAIT_ACTIVE, 0, "async listio active"}, {
1990*49cdfc7eSAndroid Build Coastguard Worker 	LIO_IO_ALISTIO | LIO_WAIT_RECALL, 0, "async listio recall"}, {
1991*49cdfc7eSAndroid Build Coastguard Worker 	LIO_IO_ALISTIO | LIO_WAIT_SIGACTIVE, SIGUSR1, "async listio sigactive"},
1992*49cdfc7eSAndroid Build Coastguard Worker 	{
1993*49cdfc7eSAndroid Build Coastguard Worker 	LIO_IO_ALISTIO | LIO_WAIT_SIGPAUSE, SIGUSR1, "async listio sigpause"},
1994*49cdfc7eSAndroid Build Coastguard Worker 	{
1995*49cdfc7eSAndroid Build Coastguard Worker 	LIO_IO_ASYNC, SIGUSR2, "async io, def wait, sigusr2"}, {
1996*49cdfc7eSAndroid Build Coastguard Worker LIO_IO_ALISTIO, SIGUSR2, "async listio, def wait, sigusr2"},};
1997*49cdfc7eSAndroid Build Coastguard Worker 
main(argc,argv)1998*49cdfc7eSAndroid Build Coastguard Worker int main(argc, argv)
1999*49cdfc7eSAndroid Build Coastguard Worker int argc;
2000*49cdfc7eSAndroid Build Coastguard Worker char **argv;
2001*49cdfc7eSAndroid Build Coastguard Worker {
2002*49cdfc7eSAndroid Build Coastguard Worker 	extern char *optarg;
2003*49cdfc7eSAndroid Build Coastguard Worker 	extern int optind;
2004*49cdfc7eSAndroid Build Coastguard Worker 
2005*49cdfc7eSAndroid Build Coastguard Worker 	int fd;
2006*49cdfc7eSAndroid Build Coastguard Worker 	char *err;
2007*49cdfc7eSAndroid Build Coastguard Worker 	char buffer[4096];
2008*49cdfc7eSAndroid Build Coastguard Worker 	int size = 4096;
2009*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
2010*49cdfc7eSAndroid Build Coastguard Worker 	int ind;
2011*49cdfc7eSAndroid Build Coastguard Worker 	int iter = 3;
2012*49cdfc7eSAndroid Build Coastguard Worker 	int method;
2013*49cdfc7eSAndroid Build Coastguard Worker 	int exit_status = 0;
2014*49cdfc7eSAndroid Build Coastguard Worker 	int c;
2015*49cdfc7eSAndroid Build Coastguard Worker 	int i;
2016*49cdfc7eSAndroid Build Coastguard Worker 	char *symbols = NULL;
2017*49cdfc7eSAndroid Build Coastguard Worker 	int die_on_err = 0;
2018*49cdfc7eSAndroid Build Coastguard Worker 
2019*49cdfc7eSAndroid Build Coastguard Worker 	while ((c = getopt(argc, argv, "s:di:")) != -1) {
2020*49cdfc7eSAndroid Build Coastguard Worker 		switch (c) {
2021*49cdfc7eSAndroid Build Coastguard Worker 		case 's':
2022*49cdfc7eSAndroid Build Coastguard Worker 			symbols = optarg;
2023*49cdfc7eSAndroid Build Coastguard Worker 			break;
2024*49cdfc7eSAndroid Build Coastguard Worker 		case 'd':
2025*49cdfc7eSAndroid Build Coastguard Worker 			++die_on_err;
2026*49cdfc7eSAndroid Build Coastguard Worker 			break;
2027*49cdfc7eSAndroid Build Coastguard Worker 		case 'i':
2028*49cdfc7eSAndroid Build Coastguard Worker 			iter = atoi(optarg);
2029*49cdfc7eSAndroid Build Coastguard Worker 			break;
2030*49cdfc7eSAndroid Build Coastguard Worker 		}
2031*49cdfc7eSAndroid Build Coastguard Worker 	}
2032*49cdfc7eSAndroid Build Coastguard Worker 
2033*49cdfc7eSAndroid Build Coastguard Worker 	if ((fd =
2034*49cdfc7eSAndroid Build Coastguard Worker 	     open("unit_test_file", O_CREAT | O_RDWR | O_TRUNC, 0777)) == -1) {
2035*49cdfc7eSAndroid Build Coastguard Worker 		perror
2036*49cdfc7eSAndroid Build Coastguard Worker 		    ("open(unit_test_file, O_CREAT|O_RDWR|O_TRUNC, 0777) failed");
2037*49cdfc7eSAndroid Build Coastguard Worker 		exit(1);
2038*49cdfc7eSAndroid Build Coastguard Worker 	}
2039*49cdfc7eSAndroid Build Coastguard Worker 
2040*49cdfc7eSAndroid Build Coastguard Worker 	Debug_level = 9;
2041*49cdfc7eSAndroid Build Coastguard Worker 
2042*49cdfc7eSAndroid Build Coastguard Worker 	if (symbols != NULL) {
2043*49cdfc7eSAndroid Build Coastguard Worker 		if ((method = lio_parse_io_arg2(symbols, &err)) == -1) {
2044*49cdfc7eSAndroid Build Coastguard Worker 			printf
2045*49cdfc7eSAndroid Build Coastguard Worker 			    ("lio_parse_io_arg2(%s, &err) failed, bad token starting at %s\n",
2046*49cdfc7eSAndroid Build Coastguard Worker 			     symbols, err);
2047*49cdfc7eSAndroid Build Coastguard Worker 			if (die_on_err)
2048*49cdfc7eSAndroid Build Coastguard Worker 				exit(1);
2049*49cdfc7eSAndroid Build Coastguard Worker 		} else
2050*49cdfc7eSAndroid Build Coastguard Worker 			printf("lio_parse_io_arg2(%s, &err) returned %#o\n",
2051*49cdfc7eSAndroid Build Coastguard Worker 			       symbols, method);
2052*49cdfc7eSAndroid Build Coastguard Worker 
2053*49cdfc7eSAndroid Build Coastguard Worker 		exit_status = 0;
2054*49cdfc7eSAndroid Build Coastguard Worker 		for (ind = 0; ind < iter; ind++) {
2055*49cdfc7eSAndroid Build Coastguard Worker 			memset(buffer, 'A', 4096);
2056*49cdfc7eSAndroid Build Coastguard Worker 			if (lseek(fd, 0, 0) == -1) {
2057*49cdfc7eSAndroid Build Coastguard Worker 				printf("lseek(fd,0,0), %d, failed, errno %d\n",
2058*49cdfc7eSAndroid Build Coastguard Worker 				       __LINE__, errno);
2059*49cdfc7eSAndroid Build Coastguard Worker 				++exit_status;
2060*49cdfc7eSAndroid Build Coastguard Worker 			}
2061*49cdfc7eSAndroid Build Coastguard Worker 			if ((ret = lio_write_buffer(fd, method, buffer,
2062*49cdfc7eSAndroid Build Coastguard Worker 						    size, SIGUSR1, &err,
2063*49cdfc7eSAndroid Build Coastguard Worker 						    0)) != size) {
2064*49cdfc7eSAndroid Build Coastguard Worker 				printf
2065*49cdfc7eSAndroid Build Coastguard Worker 				    ("lio_write_buffer returned -1, err = %s\n",
2066*49cdfc7eSAndroid Build Coastguard Worker 				     err);
2067*49cdfc7eSAndroid Build Coastguard Worker 			} else
2068*49cdfc7eSAndroid Build Coastguard Worker 				printf("lio_write_buffer returned %d\n", ret);
2069*49cdfc7eSAndroid Build Coastguard Worker 
2070*49cdfc7eSAndroid Build Coastguard Worker 			memset(buffer, 'B', 4096);
2071*49cdfc7eSAndroid Build Coastguard Worker 			if (lseek(fd, 0, 0) == -1) {
2072*49cdfc7eSAndroid Build Coastguard Worker 				printf("lseek(fd,0,0), %d, failed, errno %d\n",
2073*49cdfc7eSAndroid Build Coastguard Worker 				       __LINE__, errno);
2074*49cdfc7eSAndroid Build Coastguard Worker 				++exit_status;
2075*49cdfc7eSAndroid Build Coastguard Worker 			}
2076*49cdfc7eSAndroid Build Coastguard Worker 			if ((ret = lio_read_buffer(fd, method, buffer,
2077*49cdfc7eSAndroid Build Coastguard Worker 						   size, SIGUSR2, &err,
2078*49cdfc7eSAndroid Build Coastguard Worker 						   0)) != size) {
2079*49cdfc7eSAndroid Build Coastguard Worker 				printf
2080*49cdfc7eSAndroid Build Coastguard Worker 				    ("lio_read_buffer returned -1, err = %s\n",
2081*49cdfc7eSAndroid Build Coastguard Worker 				     err);
2082*49cdfc7eSAndroid Build Coastguard Worker 			} else
2083*49cdfc7eSAndroid Build Coastguard Worker 				printf("lio_read_buffer returned %d\n", ret);
2084*49cdfc7eSAndroid Build Coastguard Worker 
2085*49cdfc7eSAndroid Build Coastguard Worker 			for (i = 0; i < 4096; ++i) {
2086*49cdfc7eSAndroid Build Coastguard Worker 				if (buffer[i] != 'A') {
2087*49cdfc7eSAndroid Build Coastguard Worker 					printf("  buffer[%d] = %d\n", i,
2088*49cdfc7eSAndroid Build Coastguard Worker 					       buffer[i]);
2089*49cdfc7eSAndroid Build Coastguard Worker 					++exit_status;
2090*49cdfc7eSAndroid Build Coastguard Worker 					break;
2091*49cdfc7eSAndroid Build Coastguard Worker 				}
2092*49cdfc7eSAndroid Build Coastguard Worker 			}
2093*49cdfc7eSAndroid Build Coastguard Worker 
2094*49cdfc7eSAndroid Build Coastguard Worker 			if (exit_status)
2095*49cdfc7eSAndroid Build Coastguard Worker 				exit(exit_status);
2096*49cdfc7eSAndroid Build Coastguard Worker 
2097*49cdfc7eSAndroid Build Coastguard Worker 		}
2098*49cdfc7eSAndroid Build Coastguard Worker 
2099*49cdfc7eSAndroid Build Coastguard Worker 		unlink("unit_test_file");
2100*49cdfc7eSAndroid Build Coastguard Worker 		exit(0);
2101*49cdfc7eSAndroid Build Coastguard Worker 	}
2102*49cdfc7eSAndroid Build Coastguard Worker 
2103*49cdfc7eSAndroid Build Coastguard Worker 	for (ind = 0; ind < sizeof(Unit_info) / sizeof(struct unit_info_t);
2104*49cdfc7eSAndroid Build Coastguard Worker 	     ind++) {
2105*49cdfc7eSAndroid Build Coastguard Worker 
2106*49cdfc7eSAndroid Build Coastguard Worker 		printf("\n********* write %s ***************\n",
2107*49cdfc7eSAndroid Build Coastguard Worker 		       Unit_info[ind].str);
2108*49cdfc7eSAndroid Build Coastguard Worker 		if (lseek(fd, 0, 0) == -1) {
2109*49cdfc7eSAndroid Build Coastguard Worker 			printf("lseek(fd,0,0), %d, failed, errno %d\n",
2110*49cdfc7eSAndroid Build Coastguard Worker 			       __LINE__, errno);
2111*49cdfc7eSAndroid Build Coastguard Worker 			++exit_status;
2112*49cdfc7eSAndroid Build Coastguard Worker 		}
2113*49cdfc7eSAndroid Build Coastguard Worker 
2114*49cdfc7eSAndroid Build Coastguard Worker 		memset(buffer, 'A', 4096);
2115*49cdfc7eSAndroid Build Coastguard Worker 		if ((ret = lio_write_buffer(fd, Unit_info[ind].method, buffer,
2116*49cdfc7eSAndroid Build Coastguard Worker 					    size, Unit_info[ind].sig, &err,
2117*49cdfc7eSAndroid Build Coastguard Worker 					    0)) != size) {
2118*49cdfc7eSAndroid Build Coastguard Worker 			printf
2119*49cdfc7eSAndroid Build Coastguard Worker 			    (">>>>> lio_write_buffer(fd,0%x,buffer,%d,%d,err,0) returned -1,\n   err = %s\n",
2120*49cdfc7eSAndroid Build Coastguard Worker 			     Unit_info[ind].method, size, Unit_info[ind].sig,
2121*49cdfc7eSAndroid Build Coastguard Worker 			     err);
2122*49cdfc7eSAndroid Build Coastguard Worker 			++exit_status;
2123*49cdfc7eSAndroid Build Coastguard Worker 			if (die_on_err)
2124*49cdfc7eSAndroid Build Coastguard Worker 				exit(exit_status);
2125*49cdfc7eSAndroid Build Coastguard Worker 		} else {
2126*49cdfc7eSAndroid Build Coastguard Worker 			printf("lio_write_buffer returned %d\n", ret);
2127*49cdfc7eSAndroid Build Coastguard Worker 		}
2128*49cdfc7eSAndroid Build Coastguard Worker 
2129*49cdfc7eSAndroid Build Coastguard Worker 		printf("\n********* read %s ***************\n",
2130*49cdfc7eSAndroid Build Coastguard Worker 		       Unit_info[ind].str);
2131*49cdfc7eSAndroid Build Coastguard Worker 		if (lseek(fd, 0, 0) == -1) {
2132*49cdfc7eSAndroid Build Coastguard Worker 			printf("lseek(fd,0,0), %d, failed, errno %d\n",
2133*49cdfc7eSAndroid Build Coastguard Worker 			       __LINE__, errno);
2134*49cdfc7eSAndroid Build Coastguard Worker 			++exit_status;
2135*49cdfc7eSAndroid Build Coastguard Worker 		}
2136*49cdfc7eSAndroid Build Coastguard Worker 		memset(buffer, 'B', 4096);
2137*49cdfc7eSAndroid Build Coastguard Worker 		if ((ret = lio_read_buffer(fd, Unit_info[ind].method, buffer,
2138*49cdfc7eSAndroid Build Coastguard Worker 					   size, Unit_info[ind].sig, &err,
2139*49cdfc7eSAndroid Build Coastguard Worker 					   0)) != size) {
2140*49cdfc7eSAndroid Build Coastguard Worker 			printf
2141*49cdfc7eSAndroid Build Coastguard Worker 			    (">>>>> lio_read_buffer(fd,0%x,buffer,%d,%d,err,0) returned -1,\n   err = %s\n",
2142*49cdfc7eSAndroid Build Coastguard Worker 			     Unit_info[ind].method, size, Unit_info[ind].sig,
2143*49cdfc7eSAndroid Build Coastguard Worker 			     err);
2144*49cdfc7eSAndroid Build Coastguard Worker 			++exit_status;
2145*49cdfc7eSAndroid Build Coastguard Worker 			if (die_on_err)
2146*49cdfc7eSAndroid Build Coastguard Worker 				exit(exit_status);
2147*49cdfc7eSAndroid Build Coastguard Worker 		} else {
2148*49cdfc7eSAndroid Build Coastguard Worker 			printf("lio_read_buffer returned %d\n", ret);
2149*49cdfc7eSAndroid Build Coastguard Worker 		}
2150*49cdfc7eSAndroid Build Coastguard Worker 
2151*49cdfc7eSAndroid Build Coastguard Worker 		for (i = 0; i < 4096; ++i) {
2152*49cdfc7eSAndroid Build Coastguard Worker 			if (buffer[i] != 'A') {
2153*49cdfc7eSAndroid Build Coastguard Worker 				printf("  buffer[%d] = %d\n", i, buffer[i]);
2154*49cdfc7eSAndroid Build Coastguard Worker 				++exit_status;
2155*49cdfc7eSAndroid Build Coastguard Worker 				if (die_on_err)
2156*49cdfc7eSAndroid Build Coastguard Worker 					exit(exit_status);
2157*49cdfc7eSAndroid Build Coastguard Worker 				break;
2158*49cdfc7eSAndroid Build Coastguard Worker 			}
2159*49cdfc7eSAndroid Build Coastguard Worker 		}
2160*49cdfc7eSAndroid Build Coastguard Worker 
2161*49cdfc7eSAndroid Build Coastguard Worker 		fflush(stdout);
2162*49cdfc7eSAndroid Build Coastguard Worker 		fflush(stderr);
2163*49cdfc7eSAndroid Build Coastguard Worker 		sleep(1);
2164*49cdfc7eSAndroid Build Coastguard Worker 
2165*49cdfc7eSAndroid Build Coastguard Worker 	}
2166*49cdfc7eSAndroid Build Coastguard Worker 
2167*49cdfc7eSAndroid Build Coastguard Worker 	unlink("unit_test_file");
2168*49cdfc7eSAndroid Build Coastguard Worker 
2169*49cdfc7eSAndroid Build Coastguard Worker 	exit(exit_status);
2170*49cdfc7eSAndroid Build Coastguard Worker }
2171*49cdfc7eSAndroid Build Coastguard Worker #endif
2172