Пример #1
0
arg_t _connect(void)
{
	uint8_t flag;
	struct socket *s = sock_get(fd, &flag);
	struct sockaddr_in sin;
	if (s == NULL)
		return -1;
	if (s->s_state == SS_CONNECTING) {
		udata.u_error = EALREADY;
		return -1;
	}
	if (s->s_state == SS_UNCONNECTED && sock_autobind(s))
		return -1;
	
	if (s->s_state == SS_BOUND) {
		if (sa_getremote(uaddr, &sin) == -1)
			return -1;
		s->s_addr[SADDR_DST].addr = sin.sin_addr.s_addr;
		s->s_addr[SADDR_DST].port = sin.sin_port;
		if (net_connect(s))
			return -1;
		if (sock_wait_leave(s, 0, SS_CONNECTING)) {
			/* API oddity, thanks Berkeley */
			if (udata.u_error == EAGAIN)
				udata.u_error = EINPROGRESS;
			return -1;
		}
		return sock_error(s);
	}
	udata.u_error = EINVAL;
	return -1;
}
Пример #2
0
arg_t _connect(void)
{
	uint8_t flag;
	struct socket *s = sock_get(fd, &flag);
	struct sockaddr_in sin;
	if (s == NULL)
		return -1;
	if (s->s_state == SS_CONNECTING) {
		udata.u_error = EALREADY;
		return -1;
	}
	if (s->s_state == SS_UNCONNECTED && sock_autobind(s))
		return -1;
	
	if (s->s_state == SS_BOUND) {
		if (sa_getremote(uaddr, &sin) == -1)
			return -1;
		s->s_addr[SADDR_DST].addr = sin.sin_addr.s_addr;
		s->s_addr[SADDR_DST].port = sin.sin_port;
		s->s_state = SS_CONNECTING;
		/* Protocol op to kick off */
	}

	do {
		/* FIXME: return EINPROGRESS not EINTR for SS_CONNECTING */
		if (psleep_flags(s, flag))
			return -1;
		/* Protocol state check */
	} while (s->s_state == SS_CONNECTING);
	return sock_error(s);
}
Пример #3
0
arg_t _sendto(void)
{
	struct socket *s = sock_get(fd, NULL);
	struct sockaddr_in sin;
	uint16_t flags;
	uint16_t alen;
	uint16_t err;

	if (s == NULL)
		return -1;

	if (s->s_state == SS_UNCONNECTED) {
		err = sock_autobind(s);
		if (err)
			return err;
	}
	if (s->s_state < SS_BOUND) {
		udata.u_error = EINVAL;
		return -1;
	}
	if (s->s_state != SS_BOUND && s->s_state < SS_CONNECTED) {
		udata.u_error = ENOTCONN;
		return -1;
	}
	flags = ugetw(&uaddr->sio_flags);
	if (flags) {
		udata.u_error = EINVAL;
		return -1;
	}
	alen = ugetw(&uaddr->sio_flags);
	/* Save the address and then just do a 'write' */
	if (s->s_type != SOCKTYPE_TCP && alen) {
		if (s->s_state >= SS_CONNECTING) {
			udata.u_error = EISCONN;
			return -1;
		}
		/* Use the address in atmp */
		s->s_flag |= SFLAG_ATMP;
		if (sa_getremote(&uaddr->sio_addr, &sin) == -1)
			return -1;
		s->s_addr[SADDR_TMP].addr = sin.sin_addr.s_addr;
		s->s_addr[SADDR_TMP].port = sin.sin_port;
	} else {
		s->s_flag &= ~SFLAG_ATMP;
		if (s->s_state < SS_CONNECTED) {
			udata.u_error = EDESTADDRREQ;
			return -1;
		}
	}
	return _write();
}
Пример #4
0
arg_t _sendto(void)
{
	struct socket *s = sock_get(d, NULL);
	struct sockaddr_in sin;

	if (s == NULL)
		return -1;
	/* Save the address and then just do a 'write' */
	if (s->s_type != SOCKTYPE_TCP) {
		/* Use the address in atmp */
		s->s_flag |= SFLAG_ATMP;
		if (sa_getremote(uaddr, &sin) == -1)
			return -1;
		s->s_addr[SADDR_TMP].addr = sin.sin_addr.s_addr;
		s->s_addr[SADDR_TMP].port = sin.sin_port;
	}
	return _write();
}