예제 #1
0
파일: net.c 프로젝트: aharisu/Gauche
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);
}
예제 #2
0
파일: net.c 프로젝트: qyqx/Gauche
ScmObj Scm_SocketGetPeerName(ScmSocket *sock)
{
    int r;
    struct sockaddr_storage addrbuf;
    socklen_t addrlen = sizeof(addrbuf);

    CLOSE_CHECK(sock->fd, "get the name of", sock);
    SCM_SYSCALL(r, getpeername(sock->fd, (struct sockaddr*)&addrbuf, &addrlen));
    if (r < 0) {
        Scm_SysError("getpeername(2) failed");
    }
    return SCM_OBJ(Scm_MakeSockAddr(NULL, (struct sockaddr*)&addrbuf, addrlen));
}
예제 #3
0
파일: net.c 프로젝트: qyqx/Gauche
ScmObj Scm_SocketRecvFrom(ScmSocket *sock, int bytes, int flags)
{
    int r;
    struct sockaddr_storage from;
    socklen_t fromlen = sizeof(from);
    CLOSE_CHECK(sock->fd, "recv from", sock);
    char *buf = SCM_NEW_ATOMIC2(char*, bytes);
    SCM_SYSCALL(r, recvfrom(sock->fd, buf, bytes, flags,
                            (struct sockaddr*)&from, &fromlen));
    if (r < 0) {
        Scm_SysError("recvfrom(2) failed");
    }
    return Scm_Values2(Scm_MakeString(buf, r, r, SCM_STRING_INCOMPLETE),
                       Scm_MakeSockAddr(NULL, (struct sockaddr*)&from, fromlen));
}
예제 #4
0
파일: net.c 프로젝트: qyqx/Gauche
ScmObj Scm_SocketBind(ScmSocket *sock, ScmSockAddr *addr)
{
    int r;
    CLOSE_CHECK(sock->fd, "bind", sock);
    SCM_SYSCALL(r, bind(sock->fd, &addr->addr, addr->addrlen));
    if (r < 0) {
        Scm_SysError("bind failed to %S", addr);
    }
    /* The system may assign different address than <addr>, especially when
       <addr> contains some 'wild card' (e.g. port=0).  We call getsockname
       to obtain the exact address.   Patch provided by ODA Hideo */
    ScmSockAddr *naddr = SCM_SOCKADDR(
                             Scm_MakeSockAddr(SCM_CLASS_OF(addr), &addr->addr, addr->addrlen));
    SCM_SYSCALL(r, getsockname(sock->fd, &naddr->addr, &naddr->addrlen));
    if (r < 0) {
        Scm_SysError("getsockname failed to %S", addr);
    }
    sock->address = naddr;
    sock->status = SCM_SOCKET_STATUS_BOUND;
    return SCM_OBJ(sock);
}