22 #ifndef LELY_IO_INTERN_DEFAULT_H_ 23 #define LELY_IO_INTERN_DEFAULT_H_ 35 #if defined(_WIN32) || _POSIX_C_SOURCE >= 200112L 37 static inline void default_fini(
struct io_handle *handle);
38 static inline int default_flags(
struct io_handle *handle,
int flags);
39 static inline ssize_t default_read(
40 struct io_handle *handle,
void *buf,
size_t nbytes);
41 static inline ssize_t default_write(
42 struct io_handle *handle,
const void *buf,
size_t nbytes);
51 CloseHandle(handle->
fd);
58 default_flags(
struct io_handle *handle,
int flags)
68 int arg = fcntl(handle->
fd, F_GETFL, 0);
73 return fcntl(handle->
fd, F_SETFL, arg | O_NONBLOCK);
75 return fcntl(handle->
fd, F_SETFL, arg & ~O_NONBLOCK);
81 default_read(
struct io_handle *handle,
void *buf,
size_t nbytes)
86 DWORD dwErrCode = GetLastError();
88 OVERLAPPED overlapped = { 0 };
89 overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
91 dwErrCode = GetLastError();
92 goto error_CreateEvent;
95 DWORD dwNumberOfBytesRead = 0;
99 int flags = handle->
flags;
103 if (ReadFile(handle->
fd, buf, nbytes, &dwNumberOfBytesRead,
108 switch (GetLastError()) {
109 case ERROR_IO_PENDING:
break;
110 case ERROR_OPERATION_ABORTED:
111 if (
__likely(ClearCommError(handle->
fd, NULL, NULL)))
114 default: dwErrCode = GetLastError();
goto error_ReadFile;
119 &overlapped) && GetLastError() == ERROR_NOT_FOUND)) {
121 dwErrCode = GetLastError();
122 goto error_CancelIoEx;
126 if (
__unlikely(!GetOverlappedResult(handle->
fd, &overlapped,
127 &dwNumberOfBytesRead, TRUE))) {
129 dwErrCode = GetLastError();
130 goto error_GetOverlappedResult;
133 if (
__unlikely(nbytes && !dwNumberOfBytesRead)) {
137 goto error_dwNumberOfBytesRead;
141 CloseHandle(overlapped.hEvent);
142 SetLastError(dwErrCode);
143 return dwNumberOfBytesRead;
145 error_dwNumberOfBytesRead:
146 error_GetOverlappedResult:
149 CloseHandle(overlapped.hEvent);
151 SetLastError(dwErrCode);
158 result = read(handle->
fd, buf, nbytes);
159 }
while (
__unlikely(result == -1 && errno == EINTR));
164 static inline ssize_t
165 default_write(
struct io_handle *handle,
const void *buf,
size_t nbytes)
170 DWORD dwErrCode = GetLastError();
172 OVERLAPPED overlapped = { 0 };
173 overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
175 dwErrCode = GetLastError();
176 goto error_CreateEvent;
179 DWORD dwNumberOfBytesWritten = 0;
183 int flags = handle->
flags;
187 if (WriteFile(handle->
fd, buf, nbytes, &dwNumberOfBytesWritten,
192 switch (GetLastError()) {
193 case ERROR_IO_PENDING:
break;
194 case ERROR_OPERATION_ABORTED:
195 if (
__likely(ClearCommError(handle->
fd, NULL, NULL)))
198 default: dwErrCode = GetLastError();
goto error_WriteFile;
203 &overlapped) && GetLastError() == ERROR_NOT_FOUND)) {
205 dwErrCode = GetLastError();
206 goto error_CancelIoEx;
210 if (
__unlikely(!GetOverlappedResult(handle->
fd, &overlapped,
211 &dwNumberOfBytesWritten, TRUE))) {
213 dwErrCode = GetLastError();
214 goto error_GetOverlappedResult;
217 if (
__unlikely(nbytes && !dwNumberOfBytesWritten)) {
221 goto error_dwNumberOfBytesWritten;
225 CloseHandle(overlapped.hEvent);
226 SetLastError(dwErrCode);
227 return dwNumberOfBytesWritten;
229 error_dwNumberOfBytesWritten:
230 error_GetOverlappedResult:
233 CloseHandle(overlapped.hEvent);
235 SetLastError(dwErrCode);
242 result = write(handle->
fd, buf, nbytes);
243 }
while (
__unlikely(result == -1 && errno == EINTR));
248 #endif // _WIN32 || _POSIX_C_SOURCE >= 200112L 254 #endif // !LELY_IO_INTERN_DEFAULT_H_ int errnum2c(errnum_t errnum)
Transforms a platform-independent error number to a native error code.
void io_handle_unlock(struct io_handle *handle)
Unlocks a locked I/O device handle.
This is the internal header file of the I/O handle declarations.
This header file is part of the utilities library; it contains the native and platform-independent er...
#define __likely(x)
Indicates to the compiler that the expression is most-likely true.
Do not close the native file descriptor when closing an I/O device.
Resource unavailable, try again.
#define __unlikely(x)
Indicates to the compiler that the expression is most-likely false.
This is the internal header file of the I/O library.
int flags
The I/O device flags (any combination of IO_FLAG_NO_CLOSE and IO_FLAG_NONBLOCK).
Perform I/O operations in non-blocking mode.
int fd
The native file descriptor.
void io_handle_lock(struct io_handle *handle)
Locks an unlocked I/O device handle, so the flags (and other device-specific fields) can safely be ac...