static gint fd_recv(gint fd, gchar *buf, gint len, gint flags) { if (fd_check_io(fd, G_IO_IN) < 0) return -1; return recv(fd, buf, len, flags); }
gint ssl_peek(SSL *ssl, gchar *buf, gint len) { gint err, ret; if (SSL_pending(ssl) == 0) { if (fd_check_io(SSL_get_rfd(ssl), G_IO_IN) < 0) return -1; } ret = SSL_peek(ssl, buf, len); switch ((err = SSL_get_error(ssl, ret))) { case SSL_ERROR_NONE: return ret; case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: errno = EAGAIN; return -1; case SSL_ERROR_ZERO_RETURN: return 0; default: g_warning("SSL_peek() returned error %d, ret = %d\n", err, ret); if (ret == 0) return 0; return -1; } }
gint fd_write_all(gint fd, const gchar *buf, gint len) { gint n, wrlen = 0; while (len) { if (fd_check_io(fd, G_IO_OUT) < 0) return -1; #ifndef G_OS_WIN32 signal(SIGPIPE, SIG_IGN); #endif if (fd_is_w32_socket(fd)) n = send(fd, buf, len, 0); else n = write(fd, buf, len); if (n <= 0) { log_error(LOG_PROTOCOL, _("write on fd%d: %s\n"), fd, strerror(errno)); return -1; } len -= n; wrlen += n; buf += n; } return wrlen; }
static gint ssl_read(gnutls_session_t ssl, gchar *buf, gint len) { gint r; if (gnutls_record_check_pending(ssl) == 0) { if (fd_check_io(GPOINTER_TO_INT(gnutls_transport_get_ptr(ssl)), G_IO_IN) < 0) return -1; } while (1) { r = gnutls_record_recv(ssl, buf, len); if (r > 0) return r; switch (r) { case 0: /* closed connection */ return -1; case GNUTLS_E_REHANDSHAKE: do { r = gnutls_handshake(ssl); } while (r == GNUTLS_E_AGAIN || r == GNUTLS_E_INTERRUPTED); break; /* re-receive */ case GNUTLS_E_AGAIN: case GNUTLS_E_INTERRUPTED: errno = EAGAIN; return -1; default: return -1; } } }
gint fd_write(gint fd, const gchar *buf, gint len) { if (fd_check_io(fd, G_IO_OUT) < 0) return -1; if (fd_is_w32_socket (fd)) return send(fd, buf, len, 0); return write(fd, buf, len); }
static gint fd_read(gint fd, gchar *buf, gint len) { if (fd_check_io(fd, G_IO_IN) < 0) return -1; if (fd_is_w32_socket(fd)) return recv(fd, buf, len, 0); return read(fd, buf, len); }
gint fd_read(gint fd, gchar *buf, gint len) { #ifdef G_OS_WIN32 return fd_recv(fd, buf, len, 0); #else if (fd_check_io(fd, G_IO_IN) < 0) return -1; return read(fd, buf, len); #endif }
gint fd_gets(gint fd, gchar *buf, gint len) { gchar *newline, *bp = buf; gint n; if (--len < 1) return -1; #ifdef G_OS_WIN32 fd_check_io(fd, G_IO_IN); do { /* XXX:tm try nonblock MSKB Article ID: Q147714 Windows Sockets 2 Service Provider Interface Limitations Polling with recv(MSG_PEEK) to determine when a complete message has arrived. Reason and Workaround not available. Single-byte send() and recv(). Reason: Couple one-byte sends with Nagle disabled. Workaround: Send modest amounts and receive as much as possible. (still unused) */ if (recv(fd, bp, 1, 0) <= 0) return -1; if (*bp == '\n') break; bp++; len--; } while (0 < len); #else /*!G_OS_WIN32*/ do { if ((n = fd_recv(fd, bp, len, MSG_PEEK)) <= 0) return -1; if ((newline = memchr(bp, '\n', n)) != NULL) n = newline - bp + 1; if ((n = fd_read(fd, bp, n)) < 0) return -1; bp += n; len -= n; } while (!newline && len); #endif /*!G_OS_WIN32*/ *bp = '\0'; return bp - buf; }
static gint ssl_write(gnutls_session_t ssl, const gchar *buf, gint len) { gint ret; if (fd_check_io(GPOINTER_TO_INT(gnutls_transport_get_ptr(ssl)), G_IO_OUT) < 0) return -1; ret = gnutls_record_send(ssl, buf, len); switch (ret) { case 0: return -1; case GNUTLS_E_AGAIN: case GNUTLS_E_INTERRUPTED: return 0; default: return ret; } }
gint fd_recv(gint fd, gchar *buf, gint len, gint flags) { #ifdef G_OS_WIN32 gint ret; #endif if (fd_check_io(fd, G_IO_IN) < 0) return -1; #ifdef G_OS_WIN32 ret = recv(fd, buf, len, flags); if (ret == SOCKET_ERROR) { gint err; err = WSAGetLastError(); sock_set_errno_from_last_error(err); if (err != WSAEWOULDBLOCK) g_warning("fd_recv(): failed with %d (errno = %d)\n", err, errno); } return ret; #else return recv(fd, buf, len, flags); #endif }
gint fd_write(gint fd, const gchar *buf, gint len) { #ifdef G_OS_WIN32 gint ret; #endif if (fd_check_io(fd, G_IO_OUT) < 0) return -1; #ifdef G_OS_WIN32 ret = send(fd, buf, len, 0); if (ret == SOCKET_ERROR) { gint err; err = WSAGetLastError(); sock_set_errno_from_last_error(err); if (err != WSAEWOULDBLOCK) g_warning("fd_write() failed with %d (errno = %d)\n", err, errno); } return ret; #else return write(fd, buf, len); #endif }