-------------------------------------------------------------------------*\ * Write with timeout * * socket_read and socket_write are cut-n-paste of socket_send and socket_recv, * with send/recv replaced with write/read. We can't just use write/read * in the socket version, because behaviour when size is zero is different. \*-------------------------------------------------------------------------
| 306 | * in the socket version, because behaviour when size is zero is different. |
| 307 | \*-------------------------------------------------------------------------*/ |
| 308 | int socket_write(p_socket ps, const char *data, size_t count, |
| 309 | size_t *sent, p_timeout tm) |
| 310 | { |
| 311 | int err; |
| 312 | *sent = 0; |
| 313 | /* avoid making system calls on closed sockets */ |
| 314 | if (*ps == SOCKET_INVALID) return IO_CLOSED; |
| 315 | /* loop until we send something or we give up on error */ |
| 316 | for ( ;; ) { |
| 317 | long put = (long) write(*ps, data, count); |
| 318 | /* if we sent anything, we are done */ |
| 319 | if (put >= 0) { |
| 320 | *sent = put; |
| 321 | return IO_DONE; |
| 322 | } |
| 323 | err = errno; |
| 324 | /* EPIPE means the connection was closed */ |
| 325 | if (err == EPIPE) return IO_CLOSED; |
| 326 | /* we call was interrupted, just try again */ |
| 327 | if (err == EINTR) continue; |
| 328 | /* if failed fatal reason, report error */ |
| 329 | if (err != EAGAIN) return err; |
| 330 | /* wait until we can send something or we timeout */ |
| 331 | if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; |
| 332 | } |
| 333 | /* can't reach here */ |
| 334 | return IO_UNKNOWN; |
| 335 | } |
| 336 | |
| 337 | /*-------------------------------------------------------------------------*\ |
| 338 | * Read with timeout |
nothing calls this directly
no test coverage detected