nvlist_t * nvlist_recv(int sock, int flags) { struct nvlist_header nvlhdr; nvlist_t *nvl, *ret; unsigned char *buf; size_t nfds, size, i; int *fds; if (buf_recv(sock, &nvlhdr, sizeof(nvlhdr)) == -1) return (NULL); if (!nvlist_check_header(&nvlhdr)) return (NULL); nfds = (size_t)nvlhdr.nvlh_descriptors; size = sizeof(nvlhdr) + (size_t)nvlhdr.nvlh_size; buf = nv_malloc(size); if (buf == NULL) return (NULL); memcpy(buf, &nvlhdr, sizeof(nvlhdr)); ret = NULL; fds = NULL; if (buf_recv(sock, buf + sizeof(nvlhdr), size - sizeof(nvlhdr)) == -1) goto out; if (nfds > 0) { fds = nv_malloc(nfds * sizeof(fds[0])); if (fds == NULL) goto out; if (fd_recv(sock, fds, nfds) == -1) goto out; } nvl = nvlist_xunpack(buf, size, fds, nfds, flags); if (nvl == NULL) { ERRNO_SAVE(); for (i = 0; i < nfds; i++) close(fds[i]); ERRNO_RESTORE(); goto out; } ret = nvl; out: ERRNO_SAVE(); nv_free(buf); nv_free(fds); ERRNO_RESTORE(); return (ret); }
gint sock_peek(SockInfo *sock, gchar *buf, gint len) { g_return_val_if_fail(sock != NULL, -1); #if USE_SSL if (sock->ssl) return ssl_peek(sock->ssl, buf, len); #endif return fd_recv(sock->sock, buf, len, MSG_PEEK); }
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 }
nvlist_t * nvlist_recv(int sock) { struct nvlist_header nvlhdr; nvlist_t *nvl, *ret; unsigned char *buf; size_t nfds, size; int serrno, *fds; if (buf_recv(sock, &nvlhdr, sizeof(nvlhdr)) == -1) return (NULL); if (!nvlist_check_header(&nvlhdr)) return (NULL); nfds = (size_t)nvlhdr.nvlh_descriptors; size = sizeof(nvlhdr) + (size_t)nvlhdr.nvlh_size; buf = malloc(size); if (buf == NULL) return (NULL); memcpy(buf, &nvlhdr, sizeof(nvlhdr)); ret = NULL; fds = NULL; if (buf_recv(sock, buf + sizeof(nvlhdr), size - sizeof(nvlhdr)) == -1) goto out; if (nfds > 0) { fds = malloc(nfds * sizeof(fds[0])); if (fds == NULL) goto out; if (fd_recv(sock, fds, nfds) == -1) goto out; } nvl = nvlist_xunpack(buf, size, fds, nfds); if (nvl == NULL) goto out; ret = nvl; out: serrno = errno; free(buf); free(fds); errno = serrno; return (ret); }
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; }
gint fd_gets(gint fd, gchar *buf, gint len) { gchar *newline, *bp = buf; gint n; if (--len < 1) return -1; 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); *bp = '\0'; return bp - buf; }