Use connect() from FreeBSD

This commit is contained in:
Sebastian Huber 2013-10-14 09:48:56 +02:00
parent e5393a3267
commit 6676de488a
5 changed files with 95 additions and 82 deletions

View File

@ -608,10 +608,17 @@ oaccept(td, uap)
return (accept1(td, uap, 1));
}
#endif /* COMPAT_OLDSOCK */
#endif /* __rtems__ */
/* ARGSUSED */
#ifndef __rtems__
int
connect(td, uap)
#else /* __rtems__ */
static int kern_connect(struct thread *, int, struct sockaddr *);
static int
rtems_bsd_connect(td, uap)
#endif /* __rtems__ */
struct thread *td;
struct connect_args /* {
int s;
@ -630,6 +637,27 @@ connect(td, uap)
free(sa, M_SONAME);
return (error);
}
#ifdef __rtems__
int
connect(int socket, const struct sockaddr *address, socklen_t address_len)
{
struct thread *td = rtems_bsd_get_curthread_or_null();
struct connect_args ua = {
.s = socket,
.name = (caddr_t) address,
.namelen = address_len
};
int error;
if (td != NULL) {
error = rtems_bsd_connect(td, &ua);
} else {
error = ENOMEM;
}
return rtems_bsd_error_to_status_and_errno(error);
}
#endif /* __rtems__ */
int
@ -693,6 +721,7 @@ done1:
return (error);
}
#ifndef __rtems__
int
kern_socketpair(struct thread *td, int domain, int type, int protocol,
int *rsv)

View File

@ -356,12 +356,16 @@ struct socket_args {
char type_l_[PADL_(int)]; int type; char type_r_[PADR_(int)];
char protocol_l_[PADL_(int)]; int protocol; char protocol_r_[PADR_(int)];
};
#ifndef __rtems__
struct connect_args {
char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
char name_l_[PADL_(caddr_t)]; caddr_t name; char name_r_[PADR_(caddr_t)];
#ifndef __rtems__
char namelen_l_[PADL_(int)]; int namelen; char namelen_r_[PADR_(int)];
#else /* __rtems__ */
char namelen_l_[PADL_(__socklen_t)]; __socklen_t namelen; char namelen_r_[PADR_(__socklen_t)];
#endif /* __rtems__ */
};
#ifndef __rtems__
struct getpriority_args {
char which_l_[PADL_(int)]; int which; char which_r_[PADR_(int)];
char who_l_[PADL_(int)]; int who; char who_r_[PADR_(int)];

View File

@ -57,6 +57,8 @@ int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
int bind(int, const struct sockaddr *, socklen_t);
int connect(int, const struct sockaddr *, socklen_t);
int shutdown(int, int);
int socket(int, int, int);

View File

@ -164,86 +164,6 @@ sockargs(mp, buf, buflen, type)
* BSD-style entry points *
*********************************************************************
*/
int
kern_connect(td, fd, sa)
struct thread *td;
int fd;
struct sockaddr *sa;
{
struct socket *so;
int error;
int interrupted = 0;
if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) {
error = EBADF;
return (error);
}
if (so->so_state & SS_ISCONNECTING) {
error = EALREADY;
goto done1;
}
#ifdef KTRACE
if (KTRPOINT(td, KTR_STRUCT))
ktrsockaddr(sa);
#endif
#ifdef MAC
error = mac_socket_check_connect(td->td_ucred, so, sa);
if (error)
goto bad;
#endif
error = soconnect(so, sa, td);
if (error)
goto bad;
if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
error = EINPROGRESS;
goto done1;
}
SOCK_LOCK(so);
while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
error = msleep(&so->so_timeo, SOCK_MTX(so), PSOCK | PCATCH,
"connec", 0);
if (error) {
if (error == EINTR || error == ERESTART)
interrupted = 1;
break;
}
}
if (error == 0) {
error = so->so_error;
so->so_error = 0;
}
SOCK_UNLOCK(so);
bad:
if (!interrupted)
so->so_state &= ~SS_ISCONNECTING;
if (error == ERESTART)
error = EINTR;
done1:
return (error);
}
int
connect (int s, struct sockaddr *name, int namelen)
{
int error;
struct sockaddr *sa;
struct thread *td;
error = getsockaddr(&sa, name, namelen);
if (error == 0)
{
td = curthread;
error = kern_connect(td, s, sa);
free(sa, M_SONAME);
}
if( error == 0 )
{
return error;
}
errno = error;
return -1;
}
int
listen (int s, int backlog)

View File

@ -565,6 +565,63 @@ test_socket_bind(void)
assert(rtems_resource_snapshot_check(&snapshot));
}
static void
no_mem_socket_connect(int fd)
{
struct sockaddr_in addr;
int rv;
errno = 0;
rv = connect(fd, (const struct sockaddr *) &addr, sizeof(addr));
assert(rv == -1);
assert(errno == ENOMEM);
}
static void
test_socket_connect(void)
{
rtems_resource_snapshot snapshot;
struct sockaddr_in addr;
int sd;
int rv;
puts("test socket connect");
rtems_resource_snapshot_take(&snapshot);
init_addr(&addr);
sd = socket(PF_INET, SOCK_DGRAM, 0);
assert(sd >= 0);
do_no_mem_test(no_mem_socket_connect, sd);
errno = 0;
rv = connect(sd, (const struct sockaddr *) &addr, SOCK_MAXADDRLEN + 1);
assert(rv == -1);
assert(errno == ENAMETOOLONG);
errno = 0;
rv = connect(sd, (const struct sockaddr *) &addr, 0);
assert(rv == -1);
assert(errno == EINVAL);
errno = 0;
rv = connect(sd, (const struct sockaddr *) &addr, sizeof(addr));
assert(rv == -1);
assert(errno == ENETUNREACH);
rv = close(sd);
assert(rv == 0);
errno = 0;
rv = connect(sd, (struct sockaddr *) &addr, sizeof(addr));
assert(rv == -1);
assert(errno == EBADF);
assert(rtems_resource_snapshot_check(&snapshot));
}
static void
test_main(void)
{
@ -575,6 +632,7 @@ test_main(void)
test_socket_fstat_and_shutdown();
test_socket_ioctl();
test_socket_bind();
test_socket_connect();
puts("*** END OF " TEST_NAME " TEST ***");
exit(0);