22 #ifndef LELY_IO_INTERN_DEFAULT_H_
23 #define LELY_IO_INTERN_DEFAULT_H_
35 #if _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);
90 if (!overlapped.hEvent) {
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 (ClearCommError(handle->
fd, NULL, NULL))
114 default: dwErrCode = GetLastError();
goto error_ReadFile;
118 && GetLastError() == ERROR_NOT_FOUND) {
119 dwErrCode = GetLastError();
120 goto error_CancelIoEx;
124 if (!GetOverlappedResult(handle->
fd, &overlapped, &dwNumberOfBytesRead,
127 dwErrCode = GetLastError();
128 goto error_GetOverlappedResult;
131 if (nbytes && !dwNumberOfBytesRead) {
135 goto error_dwNumberOfBytesRead;
139 CloseHandle(overlapped.hEvent);
140 SetLastError(dwErrCode);
141 return dwNumberOfBytesRead;
143 error_dwNumberOfBytesRead:
144 error_GetOverlappedResult:
147 CloseHandle(overlapped.hEvent);
149 SetLastError(dwErrCode);
156 result = read(handle->
fd, buf, nbytes);
157 }
while (result == -1 && errno == EINTR);
162 static inline ssize_t
163 default_write(
struct io_handle *handle,
const void *buf,
size_t nbytes)
168 DWORD dwErrCode = GetLastError();
170 OVERLAPPED overlapped = { 0 };
171 overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
172 if (!overlapped.hEvent) {
173 dwErrCode = GetLastError();
174 goto error_CreateEvent;
177 DWORD dwNumberOfBytesWritten = 0;
181 int flags = handle->
flags;
185 if (WriteFile(handle->
fd, buf, nbytes, &dwNumberOfBytesWritten,
190 switch (GetLastError()) {
191 case ERROR_IO_PENDING:
break;
192 case ERROR_OPERATION_ABORTED:
193 if (ClearCommError(handle->
fd, NULL, NULL))
196 default: dwErrCode = GetLastError();
goto error_WriteFile;
200 && GetLastError() == ERROR_NOT_FOUND) {
201 dwErrCode = GetLastError();
202 goto error_CancelIoEx;
206 if (!GetOverlappedResult(handle->
fd, &overlapped,
207 &dwNumberOfBytesWritten, TRUE)) {
209 dwErrCode = GetLastError();
210 goto error_GetOverlappedResult;
213 if (nbytes && !dwNumberOfBytesWritten) {
217 goto error_dwNumberOfBytesWritten;
221 CloseHandle(overlapped.hEvent);
222 SetLastError(dwErrCode);
223 return dwNumberOfBytesWritten;
225 error_dwNumberOfBytesWritten:
226 error_GetOverlappedResult:
229 CloseHandle(overlapped.hEvent);
231 SetLastError(dwErrCode);
238 result = write(handle->
fd, buf, nbytes);
239 }
while (result == -1 && errno == EINTR);
This header file is part of the utilities library; it contains the native and platform-independent er...
int errnum2c(errnum_t errnum)
Transforms a platform-independent error number to a native error code.
@ ERRNUM_AGAIN
Resource unavailable, try again.
void io_handle_unlock(struct io_handle *handle)
Unlocks a locked I/O device handle.
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...
This is the internal header file of the I/O handle declarations.
@ IO_FLAG_NONBLOCK
Perform I/O operations in non-blocking mode.
@ IO_FLAG_NO_CLOSE
Do not close the native file descriptor when closing an I/O device.
This is the internal header file of the Windows-specific I/O declarations.
int fd
The native file descriptor.
int flags
The I/O device flags (any combination of IO_FLAG_NO_CLOSE and IO_FLAG_NONBLOCK).