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; }
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); }
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(); }
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(); }