diff options
author | Sam Roberts <vieuxtech@gmail.com> | 2012-02-23 17:12:37 -0800 |
---|---|---|
committer | Sam Roberts <vieuxtech@gmail.com> | 2012-04-11 13:45:59 -0700 |
commit | b1f7c349b5714ebe304f93e43576a0ff3f721fc1 (patch) | |
tree | d3c4f5539507be4fe69452f100e8843ee55567ac /src/usocket.c | |
parent | 3b19f2a7edbcde798a9cf5f1f6175d360e891744 (diff) | |
download | luasocket-b1f7c349b5714ebe304f93e43576a0ff3f721fc1.tar.gz luasocket-b1f7c349b5714ebe304f93e43576a0ff3f721fc1.tar.bz2 luasocket-b1f7c349b5714ebe304f93e43576a0ff3f721fc1.zip |
Add support for serial devices as socket streams on unix.
Diffstat (limited to 'src/usocket.c')
-rw-r--r-- | src/usocket.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/usocket.c b/src/usocket.c index e43cfa4..46087c6 100644 --- a/src/usocket.c +++ b/src/usocket.c | |||
@@ -300,6 +300,66 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, | |||
300 | return IO_UNKNOWN; | 300 | return IO_UNKNOWN; |
301 | } | 301 | } |
302 | 302 | ||
303 | |||
304 | /*-------------------------------------------------------------------------*\ | ||
305 | * Write with timeout | ||
306 | * | ||
307 | * socket_read and socket_write are cut-n-paste of socket_send and socket_recv, | ||
308 | * with send/recv replaced with write/read. We can't just use write/read | ||
309 | * in the socket version, because behaviour when size is zero is different. | ||
310 | \*-------------------------------------------------------------------------*/ | ||
311 | int socket_write(p_socket ps, const char *data, size_t count, | ||
312 | size_t *sent, p_timeout tm) | ||
313 | { | ||
314 | int err; | ||
315 | *sent = 0; | ||
316 | /* avoid making system calls on closed sockets */ | ||
317 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||
318 | /* loop until we send something or we give up on error */ | ||
319 | for ( ;; ) { | ||
320 | long put = (long) write(*ps, data, count); | ||
321 | /* if we sent anything, we are done */ | ||
322 | if (put >= 0) { | ||
323 | *sent = put; | ||
324 | return IO_DONE; | ||
325 | } | ||
326 | err = errno; | ||
327 | /* EPIPE means the connection was closed */ | ||
328 | if (err == EPIPE) return IO_CLOSED; | ||
329 | /* we call was interrupted, just try again */ | ||
330 | if (err == EINTR) continue; | ||
331 | /* if failed fatal reason, report error */ | ||
332 | if (err != EAGAIN) return err; | ||
333 | /* wait until we can send something or we timeout */ | ||
334 | if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; | ||
335 | } | ||
336 | /* can't reach here */ | ||
337 | return IO_UNKNOWN; | ||
338 | } | ||
339 | |||
340 | /*-------------------------------------------------------------------------*\ | ||
341 | * Read with timeout | ||
342 | * See note for socket_write | ||
343 | \*-------------------------------------------------------------------------*/ | ||
344 | int socket_read(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) { | ||
345 | int err; | ||
346 | *got = 0; | ||
347 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||
348 | for ( ;; ) { | ||
349 | long taken = (long) read(*ps, data, count); | ||
350 | if (taken > 0) { | ||
351 | *got = taken; | ||
352 | return IO_DONE; | ||
353 | } | ||
354 | err = errno; | ||
355 | if (taken == 0) return IO_CLOSED; | ||
356 | if (err == EINTR) continue; | ||
357 | if (err != EAGAIN) return err; | ||
358 | if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; | ||
359 | } | ||
360 | return IO_UNKNOWN; | ||
361 | } | ||
362 | |||
303 | /*-------------------------------------------------------------------------*\ | 363 | /*-------------------------------------------------------------------------*\ |
304 | * Put socket into blocking mode | 364 | * Put socket into blocking mode |
305 | \*-------------------------------------------------------------------------*/ | 365 | \*-------------------------------------------------------------------------*/ |