summaryrefslogtreecommitdiffstats
path: root/private/crt32/lowio/lseek.c
blob: bf3524e5fca9609155c9a0846fd1c6be6994db19 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/***
*lseek.c - OS/2 change file position
*
*	Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved.
*
*Purpose:
*	defines _lseek() - move the file pointer
*
*Revision History:
*	06-20-89  PHG	Module created, based on asm version
*	03-12-90  GJF	Made calling type _CALLTYPE2 (for now), added #include
*			<cruntime.h> and fixed the copyright. Also, cleaned up
*			the formatting a bit.
*	04-03-90  GJF	Now _CALLTYPE1.
*	07-24-90  SBM	Removed '32' from API names
*	08-14-90  SBM	Compiles cleanly with -W3
*	09-28-90  GJF	New-style function declarators.
*	12-04-90  GJF	Appended Win32 version with #ifdef-s. It's probably
*			worth coming back and doing a more complete merge later
*			(much later).
*	12-04-90  SRW	Changed to include <oscalls.h> instead of <doscalls.h>
*	12-06-90  SRW	Changed to use _osfile and _osfhnd instead of _osfinfo
*	01-16-91  GJF	ANSI naming.
*       02-07-91  SRW   Changed to call _get_osfhandle [_WIN32_]
*	04-09-91  PNT	Added _MAC_ conditional
*	02-13-92  GJF	Replaced _nfile by _nhandle for Win32.
*
*******************************************************************************/

#include <cruntime.h>
#include <oscalls.h>
#include <os2dll.h>
#include <io.h>
#include <internal.h>
#include <stdlib.h>
#include <errno.h>
#include <msdos.h>
#include <stdio.h>

/***
*long _lseek(fh,pos,mthd) - move the file pointer
*
*Purpose:
*	Moves the file pointer associated with fh to a new position.
*	The new position is pos bytes (pos may be negative) away
*	from the origin specified by mthd.
*
*	If mthd == SEEK_SET, the origin in the beginning of file
*	If mthd == SEEK_CUR, the origin is the current file pointer position
*	If mthd == SEEK_END, the origin is the end of the file
*
*	Multi-thread:
*	_lseek()    = locks/unlocks the file
*	_lseek_lk() = does NOT lock/unlock the file (it is assumed that
*		      the caller has the aquired the file lock,if needed).
*
*Entry:
*	int fh - file handle to move file pointer on
*	long pos - position to move to, relative to origin
*	int mthd - specifies the origin pos is relative to (see above)
*
*Exit:
*	returns the offset, in bytes, of the new position from the beginning
*	of the file.
*	returns -1L (and sets errno) if fails.
*	Note that seeking beyond the end of the file is not an error.
*	(although seeking before the beginning is.)
*
*Exceptions:
*
*******************************************************************************/

#ifdef MTHREAD

/* define locking/validating lseek */
long _CALLTYPE1 _lseek (
	int fh,
	long pos,
	int mthd
	)
{
	int r;

	/* validate fh */
#ifdef	_WIN32_
	if ( (unsigned)fh >= (unsigned)_nhandle ) {
#else
	if ((unsigned)fh >= (unsigned)_nfile) {
#endif
		/* bad file handle */
		errno = EBADF;
		_doserrno = 0;	/* not OS/2 error */
		return -1;
	}

	_lock_fh(fh);			/* lock file handle */
	r = _lseek_lk(fh, pos, mthd);	/* seek */
	_unlock_fh(fh); 		/* unlock file handle */

	return r;
}

/* define core _lseek -- doesn't lock or validate fh */
long _CALLTYPE1 _lseek_lk (
	int fh,
	long pos,
	int mthd
	)
{
	ULONG newpos;			/* new file position */
	ULONG dosretval;		/* OS/2 return value */

#else

/* define normal _lseek */
long _CALLTYPE1 _lseek (
	int fh,
	long pos,
	int mthd
	)
{
	ULONG newpos;			/* new file position */
	ULONG dosretval;		/* OS/2 return value */

	/* validate fh */
#ifdef	_WIN32_
	if ( (unsigned)fh >= (unsigned)_nhandle ) {
#else
	if ((unsigned)fh >= (unsigned)_nfile) {
#endif
		/* bad file handle */
		errno = EBADF;
		_doserrno = 0;	/* not OS/2 error */
		return -1;
	}

#endif

	/* tell OS/2 to seek */

#ifdef	_CRUISER_

#if SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END
    #error Xenix and OS/2 seek constants not compatible
#endif

	dosretval = DOSSETFILEPTR(fh, pos, mthd, &newpos);

#else	/* ndef _CRUISER_ */

#ifdef	_WIN32_

#if SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END
    #error Xenix and Win32 seek constants not compatible
#endif

	if ((newpos = SetFilePointer((HANDLE)_get_osfhandle(fh),
        pos, NULL, mthd)) == -1)
                dosretval = GetLastError();
        else
                dosretval = 0;

#else	/* ndef _WIN32_ */

#ifdef	_MAC_

	TBD();

#else	/* ndef _MAC_ */

#error ERROR - ONLY CRUISER, WIN32, OR MAC TARGET SUPPORTED!

#endif	/* _MAC_ */

#endif	/* _WIN32_ */

#endif	/* _CRUISER_ */

	if (dosretval) {
		/* OS/2 error */
		_dosmaperr(dosretval);
		return -1;
	}

	_osfile[fh] &= ~FEOFLAG;	/* clear the ctrl-z flag on the file */
	return newpos;			/* return */
}