1 /* 2 * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "krb5_locl.h" 35 36 KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL 37 krb5_net_write (krb5_context context, 38 void *p_fd, 39 const void *buf, 40 size_t len) 41 { 42 krb5_socket_t fd = *((krb5_socket_t *)p_fd); 43 return net_write(fd, buf, len); 44 } 45 46 KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL 47 krb5_net_write_block(krb5_context context, 48 void *p_fd, 49 const void *buf, 50 size_t len, 51 time_t timeout) 52 { 53 krb5_socket_t fd = *((krb5_socket_t *)p_fd); 54 int ret; 55 struct timeval tv, *tvp; 56 const char *cbuf = (const char *)buf; 57 size_t rem = len; 58 ssize_t count; 59 fd_set wfds; 60 61 do { 62 FD_ZERO(&wfds); 63 FD_SET(fd, &wfds); 64 65 if (timeout != 0) { 66 tv.tv_sec = timeout; 67 tv.tv_usec = 0; 68 tvp = &tv; 69 } else 70 tvp = NULL; 71 72 ret = select(fd + 1, NULL, &wfds, NULL, tvp); 73 if (rk_IS_SOCKET_ERROR(ret)) { 74 if (rk_SOCK_ERRNO == EINTR) 75 continue; 76 return -1; 77 } 78 79 #ifdef HAVE_WINSOCK 80 if (ret == 0) { 81 WSASetLastError( WSAETIMEDOUT ); 82 return 0; 83 } 84 85 count = send (fd, cbuf, rem, 0); 86 87 if (rk_IS_SOCKET_ERROR(count)) { 88 return -1; 89 } 90 91 #else 92 if (ret == 0) { 93 return 0; 94 } 95 96 if (!FD_ISSET(fd, &wfds)) { 97 errno = ETIMEDOUT; 98 return -1; 99 } 100 101 count = write (fd, cbuf, rem); 102 103 if (count < 0) { 104 if (errno == EINTR) 105 continue; 106 else 107 return count; 108 } 109 110 #endif 111 112 cbuf += count; 113 rem -= count; 114 115 } while (rem > 0); 116 117 return len; 118 } 119