-------------------------------------------------------------------------*\ * Send with timeout \*-------------------------------------------------------------------------*/
| 197 | * Send with timeout |
| 198 | \*-------------------------------------------------------------------------*/ |
| 199 | int socket_send(p_socket ps, const char *data, size_t count, |
| 200 | size_t *sent, p_timeout tm) |
| 201 | { |
| 202 | int err; |
| 203 | *sent = 0; |
| 204 | /* avoid making system calls on closed sockets */ |
| 205 | if (*ps == SOCKET_INVALID) return IO_CLOSED; |
| 206 | /* loop until we send something or we give up on error */ |
| 207 | for ( ;; ) { |
| 208 | long put = (long) send(*ps, data, count, 0); |
| 209 | /* if we sent anything, we are done */ |
| 210 | if (put >= 0) { |
| 211 | *sent = put; |
| 212 | return IO_DONE; |
| 213 | } |
| 214 | err = errno; |
| 215 | /* EPIPE means the connection was closed */ |
| 216 | if (err == EPIPE) return IO_CLOSED; |
| 217 | /* EPROTOTYPE means the connection is being closed (on Yosemite!)*/ |
| 218 | if (err == EPROTOTYPE) continue; |
| 219 | /* we call was interrupted, just try again */ |
| 220 | if (err == EINTR) continue; |
| 221 | /* if failed fatal reason, report error */ |
| 222 | if (err != EAGAIN) return err; |
| 223 | /* wait until we can send something or we timeout */ |
| 224 | if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; |
| 225 | } |
| 226 | /* can't reach here */ |
| 227 | return IO_UNKNOWN; |
| 228 | } |
| 229 | |
| 230 | /*-------------------------------------------------------------------------*\ |
| 231 | * Sendto with timeout |
no test coverage detected