ScmObj Scm_SocketAccept(ScmSocket *sock) { Socket newfd; struct sockaddr_storage addrbuf; socklen_t addrlen = sizeof(addrbuf); ScmSocket *newsock; ScmClass *addrClass = Scm_ClassOf(SCM_OBJ(sock->address)); CLOSE_CHECK(sock->fd, "accept from", sock); SCM_SYSCALL(newfd, accept(sock->fd, (struct sockaddr*)&addrbuf, &addrlen)); if (SOCKET_INVALID(newfd)) { if (errno == EAGAIN) { return SCM_FALSE; } else { Scm_SysError("accept(2) failed"); } } newsock = make_socket(newfd, sock->type); newsock->address = SCM_SOCKADDR(Scm_MakeSockAddr(addrClass, (struct sockaddr*)&addrbuf, addrlen)); newsock->status = SCM_SOCKET_STATUS_CONNECTED; return SCM_OBJ(newsock); }
ScmObj Scm_MakeSocket(int domain, int type, int protocol) { intptr_t sock; #if GAUCHE_WINDOWS /* On Windows, sockets created by socket() call sets WSA_FLAG_OVERLAPPED flag. When used in threads other than primordial thread, I/O to/from such socket fails, since it requires extra OVERLAPPED struct in win32 call (which can't be done with POSIX calls). Directly using WSASocket allows us to not set WSA_FLAG_OVERLAPPED flag. */ SCM_SYSCALL(sock, WSASocket(domain, type, protocol, NULL, 0, 0)); #else /*!GAUCHE_WINDOWS*/ SCM_SYSCALL(sock, socket(domain, type, protocol)); #endif /*!GAUCHE_WINDOWS*/ if (SOCKET_INVALID(sock)) Scm_SysError("couldn't create socket"); return SCM_OBJ(make_socket((Socket)sock, type)); }