static void mg_handle_tcp_read(struct mg_connection *conn) { int n = 0; char *buf = (char *) MG_MALLOC(MG_TCP_RECV_BUFFER_SIZE); if (buf == NULL) { DBG(("OOM")); return; } #if MG_ENABLE_SSL if (conn->flags & MG_F_SSL) { if (conn->flags & MG_F_SSL_HANDSHAKE_DONE) { /* SSL library may have more bytes ready to read than we ask to read. * Therefore, read in a loop until we read everything. Without the loop, * we skip to the next select() cycle which can just timeout. */ while ((n = mg_ssl_if_read(conn, buf, MG_TCP_RECV_BUFFER_SIZE)) > 0) { DBG(("%p %d bytes <- %d (SSL)", conn, n, conn->sock)); mg_if_recv_tcp_cb(conn, buf, n, 1 /* own */); buf = NULL; if (conn->flags & MG_F_CLOSE_IMMEDIATELY) break; /* buf has been freed, we need a new one. */ buf = (char *) MG_MALLOC(MG_TCP_RECV_BUFFER_SIZE); if (buf == NULL) break; } MG_FREE(buf); if (n < 0 && n != MG_SSL_WANT_READ) conn->flags |= MG_F_CLOSE_IMMEDIATELY; } else { MG_FREE(buf); mg_ssl_begin(conn); return; } } else #endif { n = (int) MG_RECV_FUNC(conn->sock, buf, recv_avail_size(conn, MG_TCP_RECV_BUFFER_SIZE), 0); DBG(("%p %d bytes (PLAIN) <- %d", conn, n, conn->sock)); if (n > 0) { mg_if_recv_tcp_cb(conn, buf, n, 1 /* own */); } else { MG_FREE(buf); } if (n == 0) { /* Orderly shutdown of the socket, try flushing output. */ conn->flags |= MG_F_SEND_AND_CLOSE; } else if (n < 0 && mg_is_error()) { conn->flags |= MG_F_CLOSE_IMMEDIATELY; } } }
void mg_lwip_ssl_recv(struct mg_connection *nc) { struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; /* Don't deliver data before connect callback */ if (nc->flags & MG_F_CONNECTING) return; while (nc->recv_mbuf.len < MG_LWIP_SSL_RECV_MBUF_LIMIT) { char *buf = (char *) MG_MALLOC(MG_LWIP_SSL_IO_SIZE); if (buf == NULL) return; int ret = mg_ssl_if_read(nc, buf, MG_LWIP_SSL_IO_SIZE); DBG(("%p %p SSL_read %u = %d", nc, cs->rx_chain, MG_LWIP_SSL_IO_SIZE, ret)); if (ret <= 0) { MG_FREE(buf); if (ret == MG_SSL_WANT_WRITE) { nc->flags |= MG_F_WANT_WRITE; return; } else if (ret == MG_SSL_WANT_READ) { /* * Nothing to do in particular, we are callback-driven. * What we definitely do not need anymore is SSL reading (nothing left). */ nc->flags &= ~MG_F_WANT_READ; cs->err = 0; return; } else { mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc); return; } } else { mg_if_recv_tcp_cb(nc, buf, ret, 1 /* own */); } } }
static int mg_recvfrom(struct mg_connection *nc, union socket_address *sa, socklen_t *sa_len, char **buf) { int n; *buf = (char *) MG_MALLOC(MG_UDP_RECV_BUFFER_SIZE); if (*buf == NULL) { DBG(("Out of memory")); return -ENOMEM; } n = recvfrom(nc->sock, *buf, MG_UDP_RECV_BUFFER_SIZE, 0, &sa->sa, sa_len); if (n <= 0) { DBG(("%p recvfrom: %s", nc, strerror(mg_get_errno()))); MG_FREE(*buf); } return n; }
DIR *opendir(const char *name) { DIR *dir = NULL; wchar_t wpath[MAX_PATH]; DWORD attrs; if (name == NULL) { SetLastError(ERROR_BAD_ARGUMENTS); } else if ((dir = (DIR *) MG_MALLOC(sizeof(*dir))) == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); } else { to_wchar(name, wpath, ARRAY_SIZE(wpath)); attrs = GetFileAttributesW(wpath); if (attrs != 0xFFFFFFFF && (attrs & FILE_ATTRIBUTE_DIRECTORY)) { (void) wcscat(wpath, L"\\*"); dir->handle = FindFirstFileW(wpath, &dir->info); dir->result.d_name[0] = '\0'; } else { MG_FREE(dir); dir = NULL; } } return dir; }