ReactOS 0.4.16-dev-853-g88d9285
lseek.cpp
Go to the documentation of this file.
1//
2// lseek.cpp
3//
4// Copyright (c) Microsoft Corporation. All rights reserved.
5//
6// Defines _lseek(), which seeks the file pointer of a file.
7//
10#include <stdlib.h>
11
12#if SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END
13 #error Xenix and Win32 seek constants not compatible
14#endif
15
16
17
18// These functions actually seek the underlying operating system file handle.
19// The logic is different for 32-bit and 64-bit seek values because a seek may
20// end up moving out of range of 32-bit values.
21static long __cdecl common_lseek_do_seek_nolock(HANDLE const os_handle, long const offset, int const origin, __crt_cached_ptd_host& ptd) throw()
22{
23 LARGE_INTEGER const origin_pos = { 0 };
24
25 LARGE_INTEGER saved_pos;
26 if (!SetFilePointerEx(os_handle, origin_pos, &saved_pos, FILE_CURRENT))
27 {
29 return -1;
30 }
31
32 LARGE_INTEGER seek_pos = { 0 };
33 seek_pos.QuadPart = offset;
34
35 LARGE_INTEGER new_pos = { 0 };
36 if (!SetFilePointerEx(os_handle, seek_pos, &new_pos, origin))
37 {
39 return -1;
40 }
41
42 // The call succeeded, but the new file pointer location is too large for
43 // the return type or is a negative value. So, restore the file pointer
44 // to the saved location and return an error:
45 if (new_pos.QuadPart > LONG_MAX)
46 {
47 SetFilePointerEx(os_handle, saved_pos, nullptr, FILE_BEGIN);
48 ptd.get_errno().set(EINVAL);
49 return -1;
50 }
51
52 return static_cast<long>(new_pos.LowPart);
53}
54
55static __int64 __cdecl common_lseek_do_seek_nolock(HANDLE const os_handle, __int64 const offset, int const origin, __crt_cached_ptd_host& ptd) throw()
56{
57 LARGE_INTEGER new_pos;
58 if (!SetFilePointerEx(os_handle, *reinterpret_cast<LARGE_INTEGER const*>(&offset), &new_pos, origin))
59 {
61 return -1;
62 }
63
64 return new_pos.QuadPart;
65}
66
67
68template <typename Integer>
69static Integer __cdecl common_lseek_nolock(int const fh, Integer const offset, int const origin, __crt_cached_ptd_host& ptd) throw()
70{
71 HANDLE const os_handle = reinterpret_cast<HANDLE>(_get_osfhandle(fh));
72 if (os_handle == reinterpret_cast<HANDLE>(-1))
73 {
74 ptd.get_errno().set(EBADF);
75 _ASSERTE(("Invalid file descriptor",0));
76 return -1;
77 }
78
79 Integer const new_position = common_lseek_do_seek_nolock(os_handle, offset, origin, ptd);
80 if (new_position == -1)
81 {
82 return -1;
83 }
84
85 // The call succeeded, so return success:
86 _osfile(fh) &= ~FEOFLAG; // Clear the Ctrl-Z flag
87 return new_position;
88}
89
90// Moves the file pointer associated with the given file to a new position. The
91// new position is 'offset' bytes (the offset may be negative) away from the
92// origin specified by 'origin'.
93//
94// If origin == SEEK_SET, the origin in the beginning of file
95// If origin == SEEK_CUR, the origin is the current file pointer position
96// If origin == SEEK_END, the origin is the end of the file
97//
98// Returns the offset, in bytes, of the new position, from the beginning of the
99// file. Returns -1 and sets errno on failure. Note that seeking beyond the
100// end of the file is not an error, but seeking before the beginning is.
101template <typename Integer>
102static Integer __cdecl common_lseek(int const fh, Integer const offset, int const origin, __crt_cached_ptd_host& ptd) throw()
103{
105 _UCRT_VALIDATE_CLEAR_OSSERR_RETURN(ptd, fh >= 0 && (unsigned)fh < (unsigned)_nhandle, EBADF, -1);
107
109 Integer result = -1;
110 __try
111 {
112 if ((_osfile(fh) & FOPEN) == 0)
113 {
114 ptd.get_errno().set(EBADF);
115 ptd.get_doserrno().set(0);
116 _ASSERTE(("Invalid file descriptor. File possibly closed by a different thread",0));
117 __leave;
118 }
119
121 }
123 {
125 }
127 return result;
128}
129
130extern "C" long __cdecl _lseek_internal(int const fh, long const offset, int const origin, __crt_cached_ptd_host& ptd)
131{
132 return common_lseek(fh, offset, origin, ptd);
133}
134
135extern "C" __int64 __cdecl _lseeki64_internal(int const fh, __int64 const offset, int const origin, __crt_cached_ptd_host& ptd)
136{
137 return common_lseek(fh, offset, origin, ptd);
138}
139
140extern "C" long __cdecl _lseek_nolock_internal(int const fh, long const offset, int const origin, __crt_cached_ptd_host& ptd)
141{
142 return common_lseek_nolock(fh, offset, origin, ptd);
143}
144
145extern "C" __int64 __cdecl _lseeki64_nolock_internal(int const fh, __int64 const offset, int const origin, __crt_cached_ptd_host& ptd)
146{
147 return common_lseek_nolock(fh, offset, origin, ptd);
148}
149
150extern "C" long __cdecl _lseek(int const fh, long const offset, int const origin)
151{
152 __crt_cached_ptd_host ptd;
153 return common_lseek(fh, offset, origin, ptd);
154}
155
156extern "C" __int64 __cdecl _lseeki64(int const fh, __int64 const offset, int const origin)
157{
158 __crt_cached_ptd_host ptd;
159 return common_lseek(fh, offset, origin, ptd);
160}
161
162extern "C" long __cdecl _lseek_nolock(int const fh, long const offset, int const origin)
163{
164 __crt_cached_ptd_host ptd;
165 return common_lseek_nolock(fh, offset, origin, ptd);
166}
167
168extern "C" __int64 __cdecl _lseeki64_nolock(int const fh, __int64 const offset, int const origin)
169{
170 __crt_cached_ptd_host ptd;
171 return common_lseek_nolock(fh, offset, origin, ptd);
172}
#define EINVAL
Definition: acclib.h:90
#define EBADF
Definition: acclib.h:82
#define __cdecl
Definition: accygwin.h:79
#define __int64
Definition: basetyps.h:16
int _nhandle
Definition: ioinit.cpp:34
void __cdecl __acrt_lowio_lock_fh(_In_ int _FileHandle)
void __cdecl __acrt_lowio_unlock_fh(_In_ int _FileHandle)
#define _UCRT_VALIDATE_CLEAR_OSSERR_RETURN(ptd, expr, errorcode, retexpr)
#define _UCRT_CHECK_FH_CLEAR_OSSERR_RETURN(ptd, handle, errorcode, retexpr)
#define _ASSERTE(expr)
Definition: crtdbg.h:114
_In_ size_t const _In_ int _In_ bool const _In_ unsigned const _In_ __acrt_rounding_mode const _Inout_ __crt_cached_ptd_host & ptd
Definition: cvt.cpp:355
#define FILE_BEGIN
Definition: compat.h:761
BOOL WINAPI SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod)
Definition: fileinfo.c:177
void __cdecl __acrt_errno_map_os_error_ptd(unsigned long const oserrno, __crt_cached_ptd_host &ptd)
Definition: errno.cpp:97
#define FOPEN
GLintptr offset
Definition: glext.h:5920
GLuint64EXT * result
Definition: glext.h:11304
#define LONG_MAX
Definition: intsafe.h:154
voidpf uLong int origin
Definition: ioapi.h:144
static Integer __cdecl common_lseek(int const fh, Integer const offset, int const origin, __crt_cached_ptd_host &ptd)
Definition: lseek.cpp:102
__int64 __cdecl _lseeki64(int const fh, __int64 const offset, int const origin)
Definition: lseek.cpp:156
__int64 __cdecl _lseeki64_nolock_internal(int const fh, __int64 const offset, int const origin, __crt_cached_ptd_host &ptd)
Definition: lseek.cpp:145
long __cdecl _lseek_nolock_internal(int const fh, long const offset, int const origin, __crt_cached_ptd_host &ptd)
Definition: lseek.cpp:140
static long __cdecl common_lseek_do_seek_nolock(HANDLE const os_handle, long const offset, int const origin, __crt_cached_ptd_host &ptd)
Definition: lseek.cpp:21
long __cdecl _lseek(int const fh, long const offset, int const origin)
Definition: lseek.cpp:150
static Integer __cdecl common_lseek_nolock(int const fh, Integer const offset, int const origin, __crt_cached_ptd_host &ptd)
Definition: lseek.cpp:69
__int64 __cdecl _lseeki64_nolock(int const fh, __int64 const offset, int const origin)
Definition: lseek.cpp:168
long __cdecl _lseek_nolock(int const fh, long const offset, int const origin)
Definition: lseek.cpp:162
long __cdecl _lseek_internal(int const fh, long const offset, int const origin, __crt_cached_ptd_host &ptd)
Definition: lseek.cpp:130
__int64 __cdecl _lseeki64_internal(int const fh, __int64 const offset, int const origin, __crt_cached_ptd_host &ptd)
Definition: lseek.cpp:135
#define __try
Definition: pseh2_64.h:172
#define __leave
Definition: pseh2_64.h:176
#define __endtry
Definition: pseh2_64.h:175
#define __finally
Definition: pseh2_64.h:174
_CRTIMP intptr_t __cdecl _get_osfhandle(_In_ int _FileHandle)
#define _osfile(i)
Definition: internal.h:72
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FILE_CURRENT
Definition: winbase.h:114
#define const
Definition: zconf.h:233