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);
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;
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;
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);
244 #endif // _WIN32 || _POSIX_C_SOURCE >= 200112L
250 #endif // !LELY_IO_INTERN_DEFAULT_H_