Пример #1
0
/*-------------------------------------------------------------------------*\
* Connects or returns error message
\*-------------------------------------------------------------------------*/
int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) {
    int err;
    /* don't call on closed socket */
    if (*ps == SOCKET_INVALID) return IO_CLOSED;
    /* ask system to connect */
    if (connect(*ps, addr, len) == 0) return IO_DONE;
    /* make sure the system is trying to connect */
    err = WSAGetLastError();
    if (err != WSAEWOULDBLOCK && err != WSAEINPROGRESS) return err;
    /* zero timeout case optimization */
    if (timeout_iszero(tm)) return IO_TIMEOUT;
    /* we wait until something happens */
    err = socket_waitfd(ps, WAITFD_C, tm);
    if (err == IO_CLOSED) {
        int len = sizeof(err);
        /* give windows time to set the error (yes, disgusting) */
        Sleep(10);
        /* find out why we failed */
        getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len); 
        /* we KNOW there was an error. if 'why' is 0, we will return
        * "unknown error", but it's not really our fault */
        return err > 0? err: IO_UNKNOWN; 
    } else return err;

}
Пример #2
0
int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
    int ret;
    fd_set rfds, wfds, *rp, *wp;
    struct timeval tv, *tp;
    double t;
    if (timeout_iszero(tm)) return IO_TIMEOUT;  /* optimize timeout == 0 case */
    do {
        /* must set bits within loop, because select may have modifed them */
        rp = wp = NULL;
        if (sw & WAITFD_R) { FD_ZERO(&rfds); FD_SET(*ps, &rfds); rp = &rfds; }
        if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; }
        t = timeout_getretry(tm);
        tp = NULL;
        if (t >= 0.0) {
            tv.tv_sec = (int)t;
            tv.tv_usec = (int)((t-tv.tv_sec)*1.0e6);
            tp = &tv;
        }
        ret = select(*ps+1, rp, wp, NULL, tp);
    } while (ret == -1 && errno == EINTR);
    if (ret == -1) return errno;
    if (ret == 0) return IO_TIMEOUT;
    if (sw == WAITFD_C && FD_ISSET(*ps, &rfds)) return IO_CLOSED;
    return IO_DONE;
}
Пример #3
0
int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
#if LUA_SOCKET_USE_SELECT
    int ret;
    fd_set rfds, wfds, *rp, *wp;
    struct timeval tv, *tp;
    double t;
    if (timeout_iszero(tm)) return IO_TIMEOUT;  /* optimize timeout == 0 case */
    do {
        /* must set bits within loop, because select may have modifed them */
        rp = wp = NULL;
        if (sw & WAITFD_R) { FD_ZERO(&rfds); FD_SET(*ps, &rfds); rp = &rfds; }
        if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; }
        t = timeout_getretry(tm);
        tp = NULL;
        if (t >= 0.0) {
            tv.tv_sec = (int)t;
            tv.tv_usec = (int)((t-tv.tv_sec)*1.0e6);
            tp = &tv;
        }
        #if APIABSTRACTION_PS3
			ret = socketselect(*ps+1, rp, wp, NULL, tp);
		#else
			ret = select(*ps+1, rp, wp, NULL, tp);  
		#endif
    } while (ret == -1 && peusock_errno == peusock_EINTR);
    if (ret == -1) return peusock_errno;
    if (ret == 0) return IO_TIMEOUT;
    if (sw == WAITFD_C && FD_ISSET(*ps, &rfds)) return IO_CLOSED;
    return IO_DONE;
#else
	printf("socket_waitfd is not implemented for this platform! don't call it!");
	return IO_UNKNOWN;
#endif
}
Пример #4
0
int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
    int ret;
    lua_State *L = lua_this();
    int t = (int)(timeout_getretry(tm)*1e3);
    if (timeout_iszero(tm)) return IO_TIMEOUT;  /* optimize timeout == 0 case */
    ret = luaL_wait(L, *ps, (sw == WAITFD_W || sw == WAITFD_C) ? 1 : 0, t);
    if (ret == -1 && sw == WAITFD_C) return IO_CLOSED;
    if (ret == 0) return IO_TIMEOUT;
    return IO_DONE;
}
Пример #5
0
/*-------------------------------------------------------------------------*\
* Connects or returns error message
\*-------------------------------------------------------------------------*/
int lua_socket_connect(p_socket ps, SA *addr, socklen_t addr_len, p_timeout tm){
    int err;
    /* don't call on closed socket */
    if (*ps == SOCKET_INVALID) return IO_CLOSED;
#ifdef WIN32
    /* ask system to connect */
    if (connect(*ps, addr, addr_len) == 0) return IO_DONE;
    /* make sure the system is trying to connect */
    err = WSAGetLastError();
    if (err != WSAEWOULDBLOCK && err != WSAEINPROGRESS) return err;
    /* zero timeout case optimization */
    if (timeout_iszero(tm)) return IO_TIMEOUT;
    /* we wait until something happens */
    err = lua_socket_waitfd(ps, WAITFD_C, tm);
    if (err == IO_CLOSED) {
        int addr_len = sizeof(err);
        /* give windows time to set the error (yes, disgusting) */
        Sleep(10);
        /* find out why we failed */
        getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &addr_len);
        /* we KNOW there was an error. if 'why' is 0, we will return
        * "unknown error", but it's not really our fault */
        return err > 0? err: IO_UNKNOWN;
    } else return err;
#else
    /* call connect until done or failed without being interrupted */
    do if (connect(*ps, addr, addr_len) == 0) return IO_DONE;
    while ((err = errno) == EINTR);
    /* if connection failed immediately, return error code */
    if (err != EINPROGRESS && err != EAGAIN) return err;
    /* zero timeout case optimization */
    if (timeout_iszero(tm)) return IO_TIMEOUT;
    /* wait until we have the result of the connection attempt or timeout */
    err = lua_socket_waitfd(ps, WAITFD_C, tm);
    if (err == IO_CLOSED) {
        if (recv(*ps, (char *) &err, 0, 0) == 0) return IO_DONE;
        else return errno;
    } else return err;
#endif
}
Пример #6
0
int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
    int ret;
    struct pollfd pfd;
    pfd.fd = *ps;
    pfd.events = sw;
    pfd.revents = 0;
    if (timeout_iszero(tm)) return IO_TIMEOUT;  /* optimize timeout == 0 case */
    do {
		int t = (int)(timeout_getretry(tm)*1e3);
		ret = poll(&pfd, 1, t >= 0? t: -1);
	} while (ret == -1 && peusock_errno == peusock_EINTR);
    if (ret == -1) return peusock_errno;
    if (ret == 0) return IO_TIMEOUT;
    if (sw == WAITFD_C && (pfd.revents & (POLLIN|POLLERR))) return IO_CLOSED;
    return IO_DONE;
}
Пример #7
0
/*-------------------------------------------------------------------------*\
* Tries to connect to remote address (address, port)
\*-------------------------------------------------------------------------*/
const char *inet_tryconnect(p_socket ps, int *family, const char *address,
        const char *serv, p_timeout tm, struct addrinfo *connecthints)
{
#ifdef LUASOCKET_SECURITY_SANDBOX
    if (luasocket_ip_allowed(address))
        return "connect restricted";
#endif // LUASOCKET_SECURITY_SANDBOX
    struct addrinfo *iterator = NULL, *resolved = NULL;
    const char *err = NULL;
    int current_family = *family;
    /* try resolving */
    err = socket_gaistrerror(getaddrinfo(address, serv,
                connecthints, &resolved));
    if (err != NULL) {
        if (resolved) freeaddrinfo(resolved);
        return err;
    }
    for (iterator = resolved; iterator; iterator = iterator->ai_next) {
        timeout_markstart(tm);
        /* create new socket if necessary. if there was no
         * bind, we need to create one for every new family
         * that shows up while iterating. if there was a
         * bind, all families will be the same and we will
         * not enter this branch. */
        if (current_family != iterator->ai_family || *ps == SOCKET_INVALID) {
            socket_destroy(ps);
            err = inet_trycreate(ps, iterator->ai_family,
                iterator->ai_socktype, iterator->ai_protocol);
            if (err) continue;
            current_family = iterator->ai_family;
            /* set non-blocking before connect */
            socket_setnonblocking(ps);
        }
        /* try connecting to remote address */
        err = socket_strerror(socket_connect(ps, (SA *) iterator->ai_addr,
            (socklen_t) iterator->ai_addrlen, tm));
        /* if success or timeout is zero, break out of loop */
        if (err == NULL || timeout_iszero(tm)) {
            *family = current_family;
            break;
        }
    }
    freeaddrinfo(resolved);
    /* here, if err is set, we failed */
    return err;
}
Пример #8
0
/*-------------------------------------------------------------------------*\
* Connects or returns error message
\*-------------------------------------------------------------------------*/
int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) {
    int err;
    /* avoid calling on closed sockets */
    if (*ps == SOCKET_INVALID) return IO_CLOSED;
    /* call connect until done or failed without being interrupted */
    do if (connect(*ps, addr, len) == 0) return IO_DONE;
    while ((err = peusock_errno) == peusock_EINTR);
    /* if connection failed immediately, return error code */
    if (err != peusock_EINPROGRESS && err != peusock_EAGAIN) return err; 
    /* zero timeout case optimization */
    if (timeout_iszero(tm)) return IO_TIMEOUT;
    /* wait until we have the result of the connection attempt or timeout */
    err = socket_waitfd(ps, WAITFD_C, tm);
    if (err == IO_CLOSED) {
        if (recv(*ps, (char *) &err, 0, 0) == 0) return IO_DONE;
        else return peusock_errno;
    } else return err;
}
Пример #9
0
int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
    int ret;
    fd_set rfds, wfds, efds, *rp = NULL, *wp = NULL, *ep = NULL;
    struct timeval tv, *tp = NULL;
    double t;
    if (timeout_iszero(tm)) return IO_TIMEOUT;  /* optimize timeout == 0 case */
    if (sw & WAITFD_R) { 
        FD_ZERO(&rfds); 
        FD_SET(*ps, &rfds);
        rp = &rfds; 
    }
    if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; }
    if (sw & WAITFD_C) { FD_ZERO(&efds); FD_SET(*ps, &efds); ep = &efds; }
    if ((t = timeout_get(tm)) >= 0.0) {
        tv.tv_sec = (int) t;
        tv.tv_usec = (int) ((t-tv.tv_sec)*1.0e6);
        tp = &tv;
    }
    ret = select(0, rp, wp, ep, tp);
    if (ret == -1) return WSAGetLastError();
    if (ret == 0) return IO_TIMEOUT;
    if (sw == WAITFD_C && FD_ISSET(*ps, &efds)) return IO_CLOSED;
    return IO_DONE;
}
Пример #10
0
int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
	/*fd_set rfds, wfds, *rp, *wp;*/
	/*struct timeval tv, *tp;*/
	double t;
	SceNetId eid = -1;
	SceNetEpollEvent ev;
	int nevents;
	SceNetEpollEvent events[MAX_EVENTS];
	int ret;

	if (timeout_iszero(tm)) return IO_TIMEOUT;  /* optimize timeout == 0 case */
	do {
		eid = sceNetEpollCreate("waitfd", 0);
		if (eid < 0) {
			printf("sceNetEpollCreate() failed (errno=%d)\n", peusock_errno);
			return sce_net_errno;
		}

		/* must set bits within loop, because select may have modifed them */
		memset(&ev, 0, sizeof(ev));
		if (sw & WAITFD_R)
			ev.events = SCE_NET_EPOLLIN;
		if (sw & WAITFD_W)
			ev.events = ev.events | SCE_NET_EPOLLOUT;
		ev.data.ext.id = *ps;

		ret = sceNetEpollControl(eid, SCE_NET_EPOLL_CTL_ADD, *ps, &ev);
		if (ret < 0) {
			printf("sceNetEpollControl(ADD) failed (errno=%d)\n", sce_net_errno);
			return sce_net_errno;
		}

		/*do stuff*/
		
		t = timeout_getretry(tm); /* time left for the call*/
		/*
		tp = NULL;
		if (t >= 0.0) {
			tv.tv_sec = (int)t;
			tv.tv_usec = (int)((t-tv.tv_sec)*1.0e6);
			tp = &tv;
		}
		*/
		/*ret = socketselect(*ps+1, rp, wp, NULL, tp);*/
		nevents = sceNetEpollWait(eid, events, MAX_EVENTS, t >= 0? t: -1);

		/* reference code for deleting events from epoll */
#if 0
		/* delete SCE_NET_EPOLLOUT */
		memset(&ev, 0, sizeof(ev));
		ev.events = SCE_NET_EPOLLIN;
		ev.data.ext.id = s;
		ret = sceNetEpollControl(eid, SCE_NET_EPOLL_CTL_MOD, *ps, &ev);
		if (ret < 0) {
			printf("sceNetEpollControl(MOD) failed (errno=%d)\n",
				sce_net_errno);
			return sce_net_errno;
		}
#endif
		/* destroy epoll object*/
		sceNetEpollDestroy(eid);

	} while (nevents == -1 && peusock_errno == peusock_EINTR);
	if (nevents == -1) return peusock_errno;
	if (nevents == 0) return IO_TIMEOUT;
	/*if (sw == WAITFD_C && FD_ISSET(*ps, &rfds)) return IO_CLOSED;*/
	return IO_DONE;
}
Пример #11
0
int lua_socket_waitfd(p_socket ps, int sw, p_timeout tm){
    int ret;
#ifdef WIN32
#define WAITFD_E        4

    fd_set rfds, wfds, efds, *rp = NULL, *wp = NULL, *ep = NULL;
    struct timeval tv, *tp = NULL;
    double t;
    if (timeout_iszero(tm)) return IO_TIMEOUT;  /* optimize timeout == 0 case */
    if (sw & WAITFD_R) {
        FD_ZERO(&rfds);
		FD_SET(*ps, &rfds);
        rp = &rfds;
    }
    if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; }
    if (sw & WAITFD_C) { FD_ZERO(&efds); FD_SET(*ps, &efds); ep = &efds; }
    if ((t = lua_timeout_get(tm)) >= 0.0) {
        tv.tv_sec = (int) t;
        tv.tv_usec = (int) ((t-tv.tv_sec)*1.0e6);
        tp = &tv;
    }
    ret = select(0, rp, wp, ep, tp);
    if (ret == -1) return WSAGetLastError();
    if (ret == 0) return IO_TIMEOUT;
    if (sw == WAITFD_C && FD_ISSET(*ps, &efds)) return IO_CLOSED;
#else
#ifdef SOCKET_POLL
    struct pollfd pfd;
    pfd.fd = *ps;
    pfd.events = sw;
    pfd.revents = 0;
    if (timeout_iszero(tm)) return IO_TIMEOUT;  /* optimize timeout == 0 case */
    do {
		int t = (int)(timeout_getretry(tm)*1e3);
		ret = poll(&pfd, 1, t >= 0? t: -1);
	} while (ret == -1 && errno == EINTR);
    if (ret == -1) return errno;
    if (ret == 0) return IO_TIMEOUT;
    if (sw == WAITFD_C && (pfd.revents & (POLLIN|POLLERR))) return IO_CLOSED;
#else
    fd_set rfds, wfds, *rp, *wp;
    struct timeval tv, *tp;
    double t;
    if (timeout_iszero(tm)) return IO_TIMEOUT;  /* optimize timeout == 0 case */
    do {
        /* must set bits within loop, because select may have modifed them */
        rp = wp = NULL;
        if (sw & WAITFD_R) { FD_ZERO(&rfds); FD_SET(*ps, &rfds); rp = &rfds; }
        if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; }
        t = lua_timeout_getretry(tm);
        tp = NULL;
        if (t >= 0.0) {
            tv.tv_sec = (int)t;
            tv.tv_usec = (int)((t-tv.tv_sec)*1.0e6);
            tp = &tv;
        }
        ret = select(*ps+1, rp, wp, NULL, tp);
    } while (ret == -1 && errno == EINTR);
    if (ret == -1) return errno;
    if (ret == 0) return IO_TIMEOUT;
    if (sw == WAITFD_C && FD_ISSET(*ps, &rfds)) return IO_CLOSED;
#endif
#endif
    return IO_DONE;
}