diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2010-04-14 06:55:55 +0200 |
---|---|---|
committer | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2010-09-10 18:49:59 +1000 |
commit | 22c4fb20d407f464813ce1031308bc4c6db13bb4 (patch) | |
tree | 36a95bab7dae675a9d842c2d61ae22c602d59db8 | |
parent | bebec4ad42af0fc1ead5291769b19d12ffa0a514 (diff) | |
download | busybox-w32-22c4fb20d407f464813ce1031308bc4c6db13bb4.tar.gz busybox-w32-22c4fb20d407f464813ce1031308bc4c6db13bb4.tar.bz2 busybox-w32-22c4fb20d407f464813ce1031308bc4c6db13bb4.zip |
win32: add poll()
Only works for pipes, as commented in the source code.
-rw-r--r-- | include/mingw.h | 2 | ||||
-rw-r--r-- | win32/mingw.c | 69 |
2 files changed, 70 insertions, 1 deletions
diff --git a/include/mingw.h b/include/mingw.h index d41580da7..c2c0c7816 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
@@ -61,7 +61,7 @@ typedef unsigned long nfds_t; | |||
61 | #define POLLIN 1 | 61 | #define POLLIN 1 |
62 | #define POLLHUP 2 | 62 | #define POLLHUP 2 |
63 | 63 | ||
64 | NOIMPL(poll,struct pollfd *ufds UNUSED_PARAM, unsigned int nfds UNUSED_PARAM, int timeout UNUSED_PARAM); | 64 | int poll(struct pollfd *ufds, unsigned int nfds, int timeout); |
65 | 65 | ||
66 | /* | 66 | /* |
67 | * pwd.h | 67 | * pwd.h |
diff --git a/win32/mingw.c b/win32/mingw.c index adf2d161e..0376c9b13 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
@@ -176,6 +176,75 @@ int pipe(int filedes[2]) | |||
176 | return 0; | 176 | return 0; |
177 | } | 177 | } |
178 | 178 | ||
179 | int poll(struct pollfd *ufds, unsigned int nfds, int timeout) | ||
180 | { | ||
181 | int i, pending; | ||
182 | |||
183 | if (timeout >= 0) { | ||
184 | if (nfds == 0) { | ||
185 | Sleep(timeout); | ||
186 | return 0; | ||
187 | } | ||
188 | errno = EINVAL; | ||
189 | return -1; | ||
190 | } | ||
191 | |||
192 | /* When there is only one fd to wait for, then we pretend that | ||
193 | * input is available and let the actual wait happen when the | ||
194 | * caller invokes read(). | ||
195 | */ | ||
196 | if (nfds == 1) { | ||
197 | if (!(ufds[0].events & POLLIN)) { | ||
198 | errno = EINVAL; | ||
199 | return -1; | ||
200 | } | ||
201 | ufds[0].revents = POLLIN; | ||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | repeat: | ||
206 | pending = 0; | ||
207 | for (i = 0; i < nfds; i++) { | ||
208 | DWORD avail = 0; | ||
209 | HANDLE h = (HANDLE) _get_osfhandle(ufds[i].fd); | ||
210 | if (h == INVALID_HANDLE_VALUE) | ||
211 | return -1; /* errno was set */ | ||
212 | |||
213 | if (!(ufds[i].events & POLLIN)) { | ||
214 | errno = EINVAL; | ||
215 | return -1; | ||
216 | } | ||
217 | |||
218 | /* this emulation works only for pipes */ | ||
219 | if (!PeekNamedPipe(h, NULL, 0, NULL, &avail, NULL)) { | ||
220 | int err = GetLastError(); | ||
221 | if (err == ERROR_BROKEN_PIPE) { | ||
222 | ufds[i].revents = POLLHUP; | ||
223 | pending++; | ||
224 | } else { | ||
225 | errno = EINVAL; | ||
226 | return -1; | ||
227 | } | ||
228 | } else if (avail) { | ||
229 | ufds[i].revents = POLLIN; | ||
230 | pending++; | ||
231 | } else | ||
232 | ufds[i].revents = 0; | ||
233 | } | ||
234 | if (!pending) { | ||
235 | /* The only times that we spin here is when the process | ||
236 | * that is connected through the pipes is waiting for | ||
237 | * its own input data to become available. But since | ||
238 | * the process (pack-objects) is itself CPU intensive, | ||
239 | * it will happily pick up the time slice that we are | ||
240 | * relinguishing here. | ||
241 | */ | ||
242 | Sleep(0); | ||
243 | goto repeat; | ||
244 | } | ||
245 | return 0; | ||
246 | } | ||
247 | |||
179 | struct tm *gmtime_r(const time_t *timep, struct tm *result) | 248 | struct tm *gmtime_r(const time_t *timep, struct tm *result) |
180 | { | 249 | { |
181 | /* gmtime() in MSVCRT.DLL is thread-safe, but not reentrant */ | 250 | /* gmtime() in MSVCRT.DLL is thread-safe, but not reentrant */ |